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 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
82 /* this is the down and dirty file with all kinds of
83 kludgy & hacky stuff. This is what it is all about
84 CODE GENERATION for a specific MCU . some of the
85 routines may be reusable, will have to see */
87 static char *zero = "#0x00";
88 static char *one = "#0x01";
89 static char *spname = "sp";
91 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
92 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
93 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
94 static char **fReturn = fReturnpic16;
96 static char *accUse[] = {"a","b"};
98 //static short rbank = -1;
110 /* Resolved ifx structure. This structure stores information
111 about an iCode ifx that makes it easier to generate code.
113 typedef struct resolvedIfx {
114 symbol *lbl; /* pointer to a label */
115 int condition; /* true or false ifx */
116 int generated; /* set true when the code associated with the ifx
120 extern int pic16_ptrRegReq ;
121 extern int pic16_nRegs;
122 extern FILE *codeOutFile;
123 static void saverbank (int, iCode *,bool);
125 static lineNode *lineHead = NULL;
126 static lineNode *lineCurr = NULL;
128 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
129 0xE0, 0xC0, 0x80, 0x00};
130 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
131 0x07, 0x03, 0x01, 0x00};
135 /*-----------------------------------------------------------------*/
136 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
137 /* exponent of 2 is returned, otherwise -1 is */
139 /* note that this is similar to the function `powof2' in SDCCsymt */
143 /*-----------------------------------------------------------------*/
144 static int my_powof2 (unsigned long num)
147 if( (num & (num-1)) == 0) {
160 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
163 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
165 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
166 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
167 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
168 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
169 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
170 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
171 ((result) ? AOP_SIZE(result) : 0));
175 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
178 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
180 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
181 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
182 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
183 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
184 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
185 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
189 void pic16_emitcomment (char *fmt, ...)
192 char lb[INITIAL_INLINEASM];
195 if(!pic16_debug_verbose)
201 vsprintf(lb+1,fmt,ap);
203 while (isspace(*lbp)) lbp++;
206 lineCurr = (lineCurr ?
207 connectLine(lineCurr,newLineNode(lb)) :
208 (lineHead = newLineNode(lb)));
209 lineCurr->isInline = _G.inLine;
210 lineCurr->isDebug = _G.debugLine;
212 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
215 // fprintf(stderr, "%s\n", lb);
218 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
221 char lb[INITIAL_INLINEASM];
224 if(!pic16_debug_verbose)
231 sprintf(lb,"%s\t",inst);
233 sprintf(lb,"%s",inst);
234 vsprintf(lb+(strlen(lb)),fmt,ap);
238 while (isspace(*lbp)) lbp++;
241 lineCurr = (lineCurr ?
242 connectLine(lineCurr,newLineNode(lb)) :
243 (lineHead = newLineNode(lb)));
244 lineCurr->isInline = _G.inLine;
245 lineCurr->isDebug = _G.debugLine;
247 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
250 // fprintf(stderr, "%s\n", lb);
253 void pic16_emitpLabel(int key)
255 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
258 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
262 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
264 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
266 // fprintf(stderr, "%s\n", pcop->name);
269 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
272 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
278 #define pic16_emitcode DEBUGpic16_emitcode
280 /*-----------------------------------------------------------------*/
281 /* pic16_emitcode - writes the code into a file : for now it is simple */
282 /*-----------------------------------------------------------------*/
283 void pic16_emitcode (char *inst,char *fmt, ...)
286 char lb[INITIAL_INLINEASM];
293 sprintf(lb,"%s\t",inst);
295 sprintf(lb,"%s",inst);
296 vsprintf(lb+(strlen(lb)),fmt,ap);
300 while (isspace(*lbp)) lbp++;
303 lineCurr = (lineCurr ?
304 connectLine(lineCurr,newLineNode(lb)) :
305 (lineHead = newLineNode(lb)));
306 lineCurr->isInline = _G.inLine;
307 lineCurr->isDebug = _G.debugLine;
309 // VR fprintf(stderr, "lb = <%s>\n", lbp);
311 // if(pic16_debug_verbose)
312 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
319 /*-----------------------------------------------------------------*/
320 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
321 /*-----------------------------------------------------------------*/
322 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
324 bool r0iu = FALSE , r1iu = FALSE;
325 bool r0ou = FALSE , r1ou = FALSE;
327 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
329 /* the logic: if r0 & r1 used in the instruction
330 then we are in trouble otherwise */
332 /* first check if r0 & r1 are used by this
333 instruction, in which case we are in trouble */
334 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
335 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
340 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
341 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
343 /* if no usage of r0 then return it */
344 if (!r0iu && !r0ou) {
345 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
346 (*aopp)->type = AOP_R0;
348 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
351 /* if no usage of r1 then return it */
352 if (!r1iu && !r1ou) {
353 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
354 (*aopp)->type = AOP_R1;
356 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
359 /* now we know they both have usage */
360 /* if r0 not used in this instruction */
362 /* push it if not already pushed */
364 //pic16_emitcode ("push","%s",
365 // pic16_regWithIdx(R0_IDX)->dname);
369 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
370 (*aopp)->type = AOP_R0;
372 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
375 /* if r1 not used then */
378 /* push it if not already pushed */
380 //pic16_emitcode ("push","%s",
381 // pic16_regWithIdx(R1_IDX)->dname);
385 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
386 (*aopp)->type = AOP_R1;
387 return pic16_regWithIdx(R1_IDX);
391 /* I said end of world but not quite end of world yet */
392 /* if this is a result then we can push it on the stack*/
394 (*aopp)->type = AOP_STK;
398 /* other wise this is true end of the world */
399 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
400 "getFreePtr should never reach here");
404 /*-----------------------------------------------------------------*/
405 /* newAsmop - creates a new asmOp */
406 /*-----------------------------------------------------------------*/
407 static asmop *newAsmop (short type)
411 aop = Safe_calloc(1,sizeof(asmop));
416 static void genSetDPTR(int n)
420 pic16_emitcode(";", "Select standard DPTR");
421 pic16_emitcode("mov", "dps, #0x00");
425 pic16_emitcode(";", "Select alternate DPTR");
426 pic16_emitcode("mov", "dps, #0x01");
430 /*-----------------------------------------------------------------*/
431 /* resolveIfx - converts an iCode ifx into a form more useful for */
432 /* generating code */
433 /*-----------------------------------------------------------------*/
434 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
439 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
441 resIfx->condition = 1; /* assume that the ifx is true */
442 resIfx->generated = 0; /* indicate that the ifx has not been used */
445 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
447 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
448 __FUNCTION__,__LINE__,resIfx->lbl->key);
452 resIfx->lbl = IC_TRUE(ifx);
454 resIfx->lbl = IC_FALSE(ifx);
455 resIfx->condition = 0;
459 DEBUGpic16_emitcode("; ***","ifx true is non-null");
461 DEBUGpic16_emitcode("; ***","ifx false is non-null");
465 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
469 /*-----------------------------------------------------------------*/
470 /* pointerCode - returns the code for a pointer type */
471 /*-----------------------------------------------------------------*/
472 static int pointerCode (sym_link *etype)
475 return PTR_TYPE(SPEC_OCLS(etype));
479 /*-----------------------------------------------------------------*/
480 /* aopForSym - for a true symbol */
481 /*-----------------------------------------------------------------*/
482 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
485 memmap *space= SPEC_OCLS(sym->etype);
487 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
488 /* if already has one */
490 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
494 /* assign depending on the storage class */
495 /* if it is on the stack or indirectly addressable */
496 /* space we need to assign either r0 or r1 to it */
497 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
498 sym->aop = aop = newAsmop(0);
499 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
500 aop->size = getSize(sym->type);
502 /* now assign the address of the variable to
503 the pointer register */
504 if (aop->type != AOP_STK) {
508 pic16_emitcode("push","acc");
510 pic16_emitcode("mov","a,_bp");
511 pic16_emitcode("add","a,#0x%02x",
513 ((char)(sym->stack - _G.nRegsSaved )) :
514 ((char)sym->stack)) & 0xff);
515 pic16_emitcode("mov","%s,a",
516 aop->aopu.aop_ptr->name);
519 pic16_emitcode("pop","acc");
521 pic16_emitcode("mov","%s,#%s",
522 aop->aopu.aop_ptr->name,
524 aop->paged = space->paged;
526 aop->aopu.aop_stk = sym->stack;
530 if (sym->onStack && options.stack10bit)
532 /* It's on the 10 bit stack, which is located in
536 //DEBUGpic16_emitcode(";","%d",__LINE__);
539 pic16_emitcode("push","acc");
541 pic16_emitcode("mov","a,_bp");
542 pic16_emitcode("add","a,#0x%02x",
544 ((char)(sym->stack - _G.nRegsSaved )) :
545 ((char)sym->stack)) & 0xff);
548 pic16_emitcode ("mov","dpx1,#0x40");
549 pic16_emitcode ("mov","dph1,#0x00");
550 pic16_emitcode ("mov","dpl1, a");
554 pic16_emitcode("pop","acc");
556 sym->aop = aop = newAsmop(AOP_DPTR2);
557 aop->size = getSize(sym->type);
561 //DEBUGpic16_emitcode(";","%d",__LINE__);
562 /* if in bit space */
563 if (IN_BITSPACE(space)) {
564 sym->aop = aop = newAsmop (AOP_CRY);
565 aop->aopu.aop_dir = sym->rname ;
566 aop->size = getSize(sym->type);
567 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
570 /* if it is in direct space */
571 if (IN_DIRSPACE(space)) {
572 sym->aop = aop = newAsmop (AOP_DIR);
573 aop->aopu.aop_dir = sym->rname ;
574 aop->size = getSize(sym->type);
575 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
579 /* special case for a function */
580 if (IS_FUNC(sym->type)) {
581 sym->aop = aop = newAsmop(AOP_IMMD);
582 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
583 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
584 strcpy(aop->aopu.aop_immd,sym->rname);
585 aop->size = FPTRSIZE;
586 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
591 /* only remaining is far space */
592 /* in which case DPTR gets the address */
593 sym->aop = aop = newAsmop(AOP_PCODE);
595 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
596 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
597 PCOI(aop->aopu.pcop)->index = 0;
599 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
600 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
602 pic16_allocDirReg (IC_LEFT(ic));
604 aop->size = FPTRSIZE;
606 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
607 sym->aop = aop = newAsmop(AOP_DPTR);
608 pic16_emitcode ("mov","dptr,#%s", sym->rname);
609 aop->size = getSize(sym->type);
611 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
614 /* if it is in code space */
615 if (IN_CODESPACE(space))
621 /*-----------------------------------------------------------------*/
622 /* aopForRemat - rematerialzes an object */
623 /*-----------------------------------------------------------------*/
624 static asmop *aopForRemat (operand *op) // x symbol *sym)
626 symbol *sym = OP_SYMBOL(op);
628 asmop *aop = newAsmop(AOP_PCODE);
632 ic = sym->rematiCode;
634 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
635 if(IS_OP_POINTER(op)) {
636 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
640 val += (int) operandLitValue(IC_RIGHT(ic));
641 } else if (ic->op == '-') {
642 val -= (int) operandLitValue(IC_RIGHT(ic));
646 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
649 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
650 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
652 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
654 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
656 PCOI(aop->aopu.pcop)->index = val;
658 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
659 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
661 val, IS_PTR_CONST(operandType(op)));
663 val, IS_CODEPTR(operandType(op)));
666 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
668 pic16_allocDirReg (IC_LEFT(ic));
673 static int aopIdx (asmop *aop, int offset)
678 if(aop->type != AOP_REG)
681 return aop->aopu.aop_reg[offset]->rIdx;
684 /*-----------------------------------------------------------------*/
685 /* regsInCommon - two operands have some registers in common */
686 /*-----------------------------------------------------------------*/
687 static bool regsInCommon (operand *op1, operand *op2)
692 /* if they have registers in common */
693 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
696 sym1 = OP_SYMBOL(op1);
697 sym2 = OP_SYMBOL(op2);
699 if (sym1->nRegs == 0 || sym2->nRegs == 0)
702 for (i = 0 ; i < sym1->nRegs ; i++) {
707 for (j = 0 ; j < sym2->nRegs ;j++ ) {
711 if (sym2->regs[j] == sym1->regs[i])
719 /*-----------------------------------------------------------------*/
720 /* operandsEqu - equivalent */
721 /*-----------------------------------------------------------------*/
722 static bool operandsEqu ( operand *op1, operand *op2)
726 /* if they not symbols */
727 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
730 sym1 = OP_SYMBOL(op1);
731 sym2 = OP_SYMBOL(op2);
733 /* if both are itemps & one is spilt
734 and the other is not then false */
735 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
736 sym1->isspilt != sym2->isspilt )
739 /* if they are the same */
743 if (strcmp(sym1->rname,sym2->rname) == 0)
747 /* if left is a tmp & right is not */
751 (sym1->usl.spillLoc == sym2))
758 (sym2->usl.spillLoc == sym1))
764 /*-----------------------------------------------------------------*/
765 /* pic16_sameRegs - two asmops have the same registers */
766 /*-----------------------------------------------------------------*/
767 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
774 if (aop1->type != AOP_REG ||
775 aop2->type != AOP_REG )
778 if (aop1->size != aop2->size )
781 for (i = 0 ; i < aop1->size ; i++ )
782 if (aop1->aopu.aop_reg[i] !=
783 aop2->aopu.aop_reg[i] )
789 /*-----------------------------------------------------------------*/
790 /* pic16_aopOp - allocates an asmop for an operand : */
791 /*-----------------------------------------------------------------*/
792 void pic16_aopOp (operand *op, iCode *ic, bool result)
801 // DEBUGpic16_emitcode(";","%d",__LINE__);
803 /* if this a literal */
804 if (IS_OP_LITERAL(op)) {
805 op->aop = aop = newAsmop(AOP_LIT);
806 aop->aopu.aop_lit = op->operand.valOperand;
807 aop->size = getSize(operandType(op));
812 sym_link *type = operandType(op);
814 if(IS_PTR_CONST(type))
818 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
821 /* if already has a asmop then continue */
825 /* if the underlying symbol has a aop */
826 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
827 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
828 op->aop = OP_SYMBOL(op)->aop;
832 /* if this is a true symbol */
833 if (IS_TRUE_SYMOP(op)) {
834 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
835 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
839 /* this is a temporary : this has
845 e) can be a return use only */
849 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
850 /* if the type is a conditional */
851 if (sym->regType == REG_CND) {
852 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
857 /* if it is spilt then two situations
859 b) has a spill location */
860 if (sym->isspilt || sym->nRegs == 0) {
862 DEBUGpic16_emitcode(";","%d",__LINE__);
863 /* rematerialize it NOW */
866 sym->aop = op->aop = aop =
868 aop->size = getSize(sym->type);
869 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
875 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
876 aop->size = getSize(sym->type);
877 for ( i = 0 ; i < 2 ; i++ )
878 aop->aopu.aop_str[i] = accUse[i];
879 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
885 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
886 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
887 //pic16_allocDirReg (IC_LEFT(ic));
888 aop->size = getSize(sym->type);
893 aop = op->aop = sym->aop = newAsmop(AOP_STR);
894 aop->size = getSize(sym->type);
895 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
896 aop->aopu.aop_str[i] = fReturn[i];
898 DEBUGpic16_emitcode(";","%d",__LINE__);
902 /* else spill location */
903 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
904 /* force a new aop if sizes differ */
905 sym->usl.spillLoc->aop = NULL;
907 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
908 __FUNCTION__,__LINE__,
909 sym->usl.spillLoc->rname,
910 sym->rname, sym->usl.spillLoc->offset);
912 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
913 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
914 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
916 sym->usl.spillLoc->offset);
917 aop->size = getSize(sym->type);
923 sym_link *type = operandType(op);
925 if(IS_PTR_CONST(type))
929 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
932 /* must be in a register */
933 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
934 sym->aop = op->aop = aop = newAsmop(AOP_REG);
935 aop->size = sym->nRegs;
936 for ( i = 0 ; i < sym->nRegs ;i++)
937 aop->aopu.aop_reg[i] = sym->regs[i];
940 /*-----------------------------------------------------------------*/
941 /* pic16_freeAsmop - free up the asmop given to an operand */
942 /*----------------------------------------------------------------*/
943 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
960 /* depending on the asmop type only three cases need work AOP_RO
961 , AOP_R1 && AOP_STK */
967 pic16_emitcode ("pop","ar0");
971 bitVectUnSetBit(ic->rUsed,R0_IDX);
977 pic16_emitcode ("pop","ar1");
981 bitVectUnSetBit(ic->rUsed,R1_IDX);
987 int stk = aop->aopu.aop_stk + aop->size;
988 bitVectUnSetBit(ic->rUsed,R0_IDX);
989 bitVectUnSetBit(ic->rUsed,R1_IDX);
991 getFreePtr(ic,&aop,FALSE);
993 if (options.stack10bit)
995 /* I'm not sure what to do here yet... */
998 "*** Warning: probably generating bad code for "
999 "10 bit stack mode.\n");
1003 pic16_emitcode ("mov","a,_bp");
1004 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1005 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1007 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1011 pic16_emitcode("pop","acc");
1012 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1014 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1017 pic16_freeAsmop(op,NULL,ic,TRUE);
1019 pic16_emitcode("pop","ar0");
1024 pic16_emitcode("pop","ar1");
1032 /* all other cases just dealloc */
1036 OP_SYMBOL(op)->aop = NULL;
1037 /* if the symbol has a spill */
1039 SPIL_LOC(op)->aop = NULL;
1044 /*-----------------------------------------------------------------*/
1045 /* pic16_aopGet - for fetching value of the aop */
1046 /*-----------------------------------------------------------------*/
1047 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1052 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1053 /* offset is greater than
1055 if (offset > (aop->size - 1) &&
1056 aop->type != AOP_LIT)
1059 /* depending on type */
1060 switch (aop->type) {
1064 DEBUGpic16_emitcode(";","%d",__LINE__);
1065 /* if we need to increment it */
1066 while (offset > aop->coff) {
1067 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1071 while (offset < aop->coff) {
1072 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1076 aop->coff = offset ;
1078 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1079 return (dname ? "acc" : "a");
1081 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1082 rs = Safe_calloc(1,strlen(s)+1);
1088 DEBUGpic16_emitcode(";","%d",__LINE__);
1089 if (aop->type == AOP_DPTR2)
1094 while (offset > aop->coff) {
1095 pic16_emitcode ("inc","dptr");
1099 while (offset < aop->coff) {
1100 pic16_emitcode("lcall","__decdptr");
1106 pic16_emitcode("clr","a");
1107 pic16_emitcode("movc","a,@a+dptr");
1110 pic16_emitcode("movx","a,@dptr");
1113 if (aop->type == AOP_DPTR2)
1118 return (dname ? "acc" : "a");
1123 sprintf (s,"%s",aop->aopu.aop_immd);
1126 sprintf(s,"(%s >> %d)",
1131 aop->aopu.aop_immd);
1132 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1133 rs = Safe_calloc(1,strlen(s)+1);
1139 sprintf(s,"(%s + %d)",
1142 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1144 sprintf(s,"%s",aop->aopu.aop_dir);
1145 rs = Safe_calloc(1,strlen(s)+1);
1151 // return aop->aopu.aop_reg[offset]->dname;
1153 return aop->aopu.aop_reg[offset]->name;
1156 //pic16_emitcode(";","%d",__LINE__);
1157 return aop->aopu.aop_dir;
1160 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1161 return "AOP_accumulator_bug";
1164 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1165 rs = Safe_calloc(1,strlen(s)+1);
1170 aop->coff = offset ;
1171 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1174 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1176 return aop->aopu.aop_str[offset];
1180 pCodeOp *pcop = aop->aopu.pcop;
1181 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1183 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1184 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1185 sprintf(s,"%s", pcop->name);
1187 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1190 rs = Safe_calloc(1,strlen(s)+1);
1196 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1197 "aopget got unsupported aop->type");
1202 /*-----------------------------------------------------------------*/
1203 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1204 /*-----------------------------------------------------------------*/
1205 pCodeOp *pic16_popGetTempReg(void)
1210 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1211 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1212 PCOR(pcop)->r->wasUsed=1;
1213 PCOR(pcop)->r->isFree=0;
1219 /*-----------------------------------------------------------------*/
1220 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1221 /*-----------------------------------------------------------------*/
1222 void pic16_popReleaseTempReg(pCodeOp *pcop)
1225 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1226 PCOR(pcop)->r->isFree = 1;
1229 /*-----------------------------------------------------------------*/
1230 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1231 /*-----------------------------------------------------------------*/
1232 pCodeOp *pic16_popGetLabel(unsigned int key)
1235 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1240 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1243 /*-----------------------------------------------------------------*/
1244 /* pic16_popCopyReg - copy a pcode operator */
1245 /*-----------------------------------------------------------------*/
1246 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1250 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1251 pcor->pcop.type = pc->pcop.type;
1253 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1254 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1256 pcor->pcop.name = NULL;
1259 pcor->rIdx = pc->rIdx;
1262 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1267 /*-----------------------------------------------------------------*/
1268 /* pic16_popGetLit - asm operator to pcode operator conversion */
1269 /*-----------------------------------------------------------------*/
1270 pCodeOp *pic16_popGetLit(unsigned int lit)
1272 return pic16_newpCodeOpLit(lit);
1275 /*-----------------------------------------------------------------*/
1276 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1277 /*-----------------------------------------------------------------*/
1278 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1280 return pic16_newpCodeOpLit2(lit, arg2);
1284 /*-----------------------------------------------------------------*/
1285 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1286 /*-----------------------------------------------------------------*/
1287 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1290 return pic16_newpCodeOpImmd(name, offset,index, 0);
1294 /*-----------------------------------------------------------------*/
1295 /* pic16_popGet - asm operator to pcode operator conversion */
1296 /*-----------------------------------------------------------------*/
1297 pCodeOp *pic16_popGetWithString(char *str)
1303 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1307 pcop = pic16_newpCodeOp(str,PO_STR);
1312 /*-----------------------------------------------------------------*/
1313 /* pic16_popRegFromString - */
1314 /*-----------------------------------------------------------------*/
1315 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1318 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1319 pcop->type = PO_DIR;
1321 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1322 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1327 pcop->name = Safe_calloc(1,strlen(str)+1);
1328 strcpy(pcop->name,str);
1330 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1332 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1333 if(PCOR(pcop)->r == NULL) {
1334 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1335 // __FUNCTION__, __LINE__, str, size, offset);
1336 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1338 //fprintf(stderr, "allocating new register -> %s\n", str);
1340 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1342 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1344 PCOR(pcop)->instance = offset;
1349 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1353 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1355 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1356 PCOR(pcop)->rIdx = rIdx;
1357 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1358 PCOR(pcop)->r->isFree = 0;
1359 PCOR(pcop)->r->wasUsed = 1;
1361 pcop->type = PCOR(pcop)->r->pc_type;
1366 /*---------------------------------------------------------------------------------*/
1367 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1369 /*---------------------------------------------------------------------------------*/
1370 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1375 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1377 /* comment the following check, so errors to throw up */
1378 // if(!pcop2)return NULL;
1380 temp = pic16_popGet(aop_dst, offset);
1381 pcop2->pcop2 = temp;
1388 /*--------------------------------------------------------------------------------.-*/
1389 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1390 /* VR 030601 , adapted by Hans Dorn */
1391 /*--------------------------------------------------------------------------------.-*/
1392 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1396 pcop2 = (pCodeOpReg2 *) src;
1404 /*---------------------------------------------------------------------------------*/
1405 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1406 /* movff instruction */
1407 /*---------------------------------------------------------------------------------*/
1408 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1413 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1414 pcop2->pcop2 = pic16_popCopyReg(dst);
1416 /* the pCodeOp may be already allocated */
1417 pcop2 = (pCodeOpReg2 *)(src);
1418 pcop2->pcop2 = (pCodeOp *)(dst);
1425 /*-----------------------------------------------------------------*/
1426 /* pic16_popGet - asm operator to pcode operator conversion */
1427 /*-----------------------------------------------------------------*/
1428 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1430 //char *s = buffer ;
1435 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1436 /* offset is greater than
1439 if (offset > (aop->size - 1) &&
1440 aop->type != AOP_LIT)
1441 return NULL; //zero;
1443 /* depending on type */
1444 switch (aop->type) {
1451 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1452 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1456 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1457 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1460 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1461 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1465 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1467 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1468 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1469 PCOR(pcop)->rIdx = rIdx;
1470 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1471 PCOR(pcop)->r->wasUsed=1;
1472 PCOR(pcop)->r->isFree=0;
1474 PCOR(pcop)->instance = offset;
1475 pcop->type = PCOR(pcop)->r->pc_type;
1476 //rs = aop->aopu.aop_reg[offset]->name;
1477 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1482 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1484 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1485 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1486 //if(PCOR(pcop)->r == NULL)
1487 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1491 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1492 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1495 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1496 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1499 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1500 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1501 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1502 pcop->type = PCOR(pcop)->r->pc_type;
1503 pcop->name = PCOR(pcop)->r->name;
1509 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1511 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1512 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1513 PCOI(pcop)->offset = offset;
1517 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1518 "pic16_popGet got unsupported aop->type");
1521 /*-----------------------------------------------------------------*/
1522 /* pic16_aopPut - puts a string for a aop */
1523 /*-----------------------------------------------------------------*/
1524 void pic16_aopPut (asmop *aop, char *s, int offset)
1529 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1531 if (aop->size && offset > ( aop->size - 1)) {
1532 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1533 "pic16_aopPut got offset > aop->size");
1537 /* will assign value to value */
1538 /* depending on where it is ofcourse */
1539 switch (aop->type) {
1542 sprintf(d,"(%s + %d)",
1543 aop->aopu.aop_dir,offset);
1544 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1547 sprintf(d,"%s",aop->aopu.aop_dir);
1550 DEBUGpic16_emitcode(";","%d",__LINE__);
1552 pic16_emitcode("movf","%s,w",s);
1553 pic16_emitcode("movwf","%s",d);
1556 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1557 if(offset >= aop->size) {
1558 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1561 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1564 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1571 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1572 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1575 strcmp(s,"r0") == 0 ||
1576 strcmp(s,"r1") == 0 ||
1577 strcmp(s,"r2") == 0 ||
1578 strcmp(s,"r3") == 0 ||
1579 strcmp(s,"r4") == 0 ||
1580 strcmp(s,"r5") == 0 ||
1581 strcmp(s,"r6") == 0 ||
1582 strcmp(s,"r7") == 0 )
1583 pic16_emitcode("mov","%s,%s ; %d",
1584 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1588 if(strcmp(s,"W")==0 )
1589 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1591 pic16_emitcode("movwf","%s",
1592 aop->aopu.aop_reg[offset]->name);
1594 if(strcmp(s,zero)==0) {
1595 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1597 } else if(strcmp(s,"W")==0) {
1598 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1599 pcop->type = PO_GPR_REGISTER;
1601 PCOR(pcop)->rIdx = -1;
1602 PCOR(pcop)->r = NULL;
1604 DEBUGpic16_emitcode(";","%d",__LINE__);
1605 pcop->name = Safe_strdup(s);
1606 pic16_emitpcode(POC_MOVFW,pcop);
1607 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1608 } else if(strcmp(s,one)==0) {
1609 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1610 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1612 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1620 if (aop->type == AOP_DPTR2)
1626 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1627 "pic16_aopPut writting to code space");
1631 while (offset > aop->coff) {
1633 pic16_emitcode ("inc","dptr");
1636 while (offset < aop->coff) {
1638 pic16_emitcode("lcall","__decdptr");
1643 /* if not in accumulater */
1646 pic16_emitcode ("movx","@dptr,a");
1648 if (aop->type == AOP_DPTR2)
1656 while (offset > aop->coff) {
1658 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1660 while (offset < aop->coff) {
1662 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1668 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1673 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1675 if (strcmp(s,"r0") == 0 ||
1676 strcmp(s,"r1") == 0 ||
1677 strcmp(s,"r2") == 0 ||
1678 strcmp(s,"r3") == 0 ||
1679 strcmp(s,"r4") == 0 ||
1680 strcmp(s,"r5") == 0 ||
1681 strcmp(s,"r6") == 0 ||
1682 strcmp(s,"r7") == 0 ) {
1684 sprintf(buffer,"a%s",s);
1685 pic16_emitcode("mov","@%s,%s",
1686 aop->aopu.aop_ptr->name,buffer);
1688 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1693 if (strcmp(s,"a") == 0)
1694 pic16_emitcode("push","acc");
1696 pic16_emitcode("push","%s",s);
1701 /* if bit variable */
1702 if (!aop->aopu.aop_dir) {
1703 pic16_emitcode("clr","a");
1704 pic16_emitcode("rlc","a");
1707 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1710 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1713 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1715 lbl = newiTempLabel(NULL);
1717 if (strcmp(s,"a")) {
1720 pic16_emitcode("clr","c");
1721 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1722 pic16_emitcode("cpl","c");
1723 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1724 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1731 if (strcmp(aop->aopu.aop_str[offset],s))
1732 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1737 if (!offset && (strcmp(s,"acc") == 0))
1740 if (strcmp(aop->aopu.aop_str[offset],s))
1741 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1745 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1746 "pic16_aopPut got unsupported aop->type");
1752 /*-----------------------------------------------------------------*/
1753 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1754 /*-----------------------------------------------------------------*/
1755 static void mov2w (asmop *aop, int offset)
1761 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1763 if ( aop->type == AOP_PCODE ||
1764 aop->type == AOP_LIT )
1765 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1767 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1772 void pic16_pushpCodeOpReg(pCodeOpReg *pcop)
1774 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pcop, &pic16_pc_postdec1, 0));
1777 void pic16_poppCodeOpReg(pCodeOpReg *pcop)
1779 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, pcop, 0));
1783 /*-----------------------------------------------------------------*/
1784 /* pushw - pushes wreg to stack */
1785 /*-----------------------------------------------------------------*/
1788 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1789 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1793 /*-----------------------------------------------------------------*/
1794 /* pushaop - pushes aop to stack */
1795 /*-----------------------------------------------------------------*/
1796 void pushaop(asmop *aop, int offset)
1798 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1799 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1802 /*-----------------------------------------------------------------*/
1803 /* popaop - pops aop from stack */
1804 /*-----------------------------------------------------------------*/
1805 void popaop(asmop *aop, int offset)
1807 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1808 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1811 void popaopidx(asmop *aop, int offset, int index)
1815 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1817 if(STACK_MODEL_LARGE)ofs++;
1819 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1820 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1823 /*-----------------------------------------------------------------*/
1824 /* reAdjustPreg - points a register back to where it should */
1825 /*-----------------------------------------------------------------*/
1826 static void reAdjustPreg (asmop *aop)
1830 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1832 if ((size = aop->size) <= 1)
1835 switch (aop->type) {
1839 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1843 if (aop->type == AOP_DPTR2)
1849 pic16_emitcode("lcall","__decdptr");
1852 if (aop->type == AOP_DPTR2)
1864 /*-----------------------------------------------------------------*/
1865 /* opIsGptr: returns non-zero if the passed operand is */
1866 /* a generic pointer type. */
1867 /*-----------------------------------------------------------------*/
1868 static int opIsGptr(operand *op)
1870 sym_link *type = operandType(op);
1872 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1873 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1881 /*-----------------------------------------------------------------*/
1882 /* pic16_getDataSize - get the operand data size */
1883 /*-----------------------------------------------------------------*/
1884 int pic16_getDataSize(operand *op)
1886 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1889 return AOP_SIZE(op);
1891 // tsd- in the pic port, the genptr size is 1, so this code here
1892 // fails. ( in the 8051 port, the size was 4).
1895 size = AOP_SIZE(op);
1896 if (size == GPTRSIZE)
1898 sym_link *type = operandType(op);
1899 if (IS_GENPTR(type))
1901 /* generic pointer; arithmetic operations
1902 * should ignore the high byte (pointer type).
1905 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1912 /*-----------------------------------------------------------------*/
1913 /* pic16_outAcc - output Acc */
1914 /*-----------------------------------------------------------------*/
1915 void pic16_outAcc(operand *result)
1918 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1919 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1922 size = pic16_getDataSize(result);
1924 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1927 /* unsigned or positive */
1929 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1934 /*-----------------------------------------------------------------*/
1935 /* pic16_outBitC - output a bit C */
1936 /*-----------------------------------------------------------------*/
1937 void pic16_outBitC(operand *result)
1940 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1941 /* if the result is bit */
1942 if (AOP_TYPE(result) == AOP_CRY)
1943 pic16_aopPut(AOP(result),"c",0);
1945 pic16_emitcode("clr","a ; %d", __LINE__);
1946 pic16_emitcode("rlc","a");
1947 pic16_outAcc(result);
1951 /*-----------------------------------------------------------------*/
1952 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1953 /*-----------------------------------------------------------------*/
1954 void pic16_toBoolean(operand *oper)
1956 int size = AOP_SIZE(oper) - 1;
1959 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1961 if ( AOP_TYPE(oper) != AOP_ACC) {
1962 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1965 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1970 #if !defined(GEN_Not)
1971 /*-----------------------------------------------------------------*/
1972 /* genNot - generate code for ! operation */
1973 /*-----------------------------------------------------------------*/
1974 static void pic16_genNot (iCode *ic)
1979 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1980 /* assign asmOps to operand & result */
1981 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1982 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1984 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1985 /* if in bit space then a special case */
1986 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1987 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1988 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1989 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1991 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1992 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1993 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1998 size = AOP_SIZE(IC_LEFT(ic));
2000 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2001 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2002 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2005 pic16_toBoolean(IC_LEFT(ic));
2007 tlbl = newiTempLabel(NULL);
2008 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2009 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2010 pic16_outBitC(IC_RESULT(ic));
2013 /* release the aops */
2014 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2015 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2020 #if !defined(GEN_Cpl)
2021 /*-----------------------------------------------------------------*/
2022 /* genCpl - generate code for complement */
2023 /*-----------------------------------------------------------------*/
2024 static void pic16_genCpl (iCode *ic)
2030 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2031 /* assign asmOps to operand & result */
2032 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2033 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2035 /* if both are in bit space then
2037 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2038 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2040 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2041 pic16_emitcode("cpl","c");
2042 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2046 size = AOP_SIZE(IC_RESULT(ic));
2049 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2051 pic16_emitcode("cpl","a");
2052 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2054 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2055 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2057 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2058 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2066 /* release the aops */
2067 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2068 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2072 /*-----------------------------------------------------------------*/
2073 /* genUminusFloat - unary minus for floating points */
2074 /*-----------------------------------------------------------------*/
2075 static void genUminusFloat(operand *op,operand *result)
2077 int size ,offset =0 ;
2080 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2081 /* for this we just need to flip the
2082 first it then copy the rest in place */
2083 size = AOP_SIZE(op) - 1;
2084 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2088 pic16_emitcode("cpl","acc.7");
2089 pic16_aopPut(AOP(result),"a",3);
2092 pic16_aopPut(AOP(result),
2093 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2099 /*-----------------------------------------------------------------*/
2100 /* genUminus - unary minus code generation */
2101 /*-----------------------------------------------------------------*/
2102 static void genUminus (iCode *ic)
2105 sym_link *optype, *rtype;
2108 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2110 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2111 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2113 /* if both in bit space then special
2115 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2116 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2118 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2119 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2120 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2125 optype = operandType(IC_LEFT(ic));
2126 rtype = operandType(IC_RESULT(ic));
2128 /* if float then do float stuff */
2129 if (IS_FLOAT(optype)) {
2130 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2134 /* otherwise subtract from zero by taking the 2's complement */
2135 size = AOP_SIZE(IC_LEFT(ic));
2137 for(i=0; i<size; i++) {
2138 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2139 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2141 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2142 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2146 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2147 for(i=1; i<size; i++) {
2149 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2153 /* release the aops */
2154 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2155 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2158 /*-----------------------------------------------------------------*/
2159 /* saveRegisters - will look for a call and save the registers */
2160 /*-----------------------------------------------------------------*/
2161 static void saveRegisters(iCode *lic)
2168 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2170 for (ic = lic ; ic ; ic = ic->next)
2171 if (ic->op == CALL || ic->op == PCALL)
2175 fprintf(stderr,"found parameter push with no function call\n");
2179 /* if the registers have been saved already then
2181 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2184 /* find the registers in use at this time
2185 and push them away to safety */
2186 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2190 if (options.useXstack) {
2191 if (bitVectBitValue(rsave,R0_IDX))
2192 pic16_emitcode("mov","b,r0");
2193 pic16_emitcode("mov","r0,%s",spname);
2194 for (i = 0 ; i < pic16_nRegs ; i++) {
2195 if (bitVectBitValue(rsave,i)) {
2197 pic16_emitcode("mov","a,b");
2199 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2200 pic16_emitcode("movx","@r0,a");
2201 pic16_emitcode("inc","r0");
2204 pic16_emitcode("mov","%s,r0",spname);
2205 if (bitVectBitValue(rsave,R0_IDX))
2206 pic16_emitcode("mov","r0,b");
2208 //for (i = 0 ; i < pic16_nRegs ; i++) {
2209 // if (bitVectBitValue(rsave,i))
2210 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2213 dtype = operandType(IC_LEFT(ic));
2214 if (currFunc && dtype &&
2215 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2216 IFFUNC_ISISR(currFunc->type) &&
2219 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2222 /*-----------------------------------------------------------------*/
2223 /* unsaveRegisters - pop the pushed registers */
2224 /*-----------------------------------------------------------------*/
2225 static void unsaveRegisters (iCode *ic)
2230 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2231 /* find the registers in use at this time
2232 and push them away to safety */
2233 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2236 if (options.useXstack) {
2237 pic16_emitcode("mov","r0,%s",spname);
2238 for (i = pic16_nRegs ; i >= 0 ; i--) {
2239 if (bitVectBitValue(rsave,i)) {
2240 pic16_emitcode("dec","r0");
2241 pic16_emitcode("movx","a,@r0");
2243 pic16_emitcode("mov","b,a");
2245 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2249 pic16_emitcode("mov","%s,r0",spname);
2250 if (bitVectBitValue(rsave,R0_IDX))
2251 pic16_emitcode("mov","r0,b");
2253 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2254 // if (bitVectBitValue(rsave,i))
2255 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2261 /*-----------------------------------------------------------------*/
2263 /*-----------------------------------------------------------------*/
2264 static void pushSide(operand * oper, int size)
2268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2270 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2271 if (AOP_TYPE(oper) != AOP_REG &&
2272 AOP_TYPE(oper) != AOP_DIR &&
2274 pic16_emitcode("mov","a,%s",l);
2275 pic16_emitcode("push","acc");
2277 pic16_emitcode("push","%s",l);
2282 /*-----------------------------------------------------------------*/
2283 /* assignResultValue - */
2284 /*-----------------------------------------------------------------*/
2285 static void assignResultValue(operand * oper)
2287 int size = AOP_SIZE(oper);
2289 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2290 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2292 if(!GpsuedoStkPtr) {
2293 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2294 /* The last byte in the assignment is in W */
2296 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2301 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2302 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2306 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2308 pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2311 pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2312 #endif /* STACK_SUPPORT */
2317 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2319 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2327 /*-----------------------------------------------------------------*/
2328 /* genIpush - genrate code for pushing this gets a little complex */
2329 /*-----------------------------------------------------------------*/
2330 static void genIpush (iCode *ic)
2333 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2335 int size, offset = 0 ;
2339 /* if this is not a parm push : ie. it is spill push
2340 and spill push is always done on the local stack */
2341 if (!ic->parmPush) {
2343 /* and the item is spilt then do nothing */
2344 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2347 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2348 size = AOP_SIZE(IC_LEFT(ic));
2349 /* push it on the stack */
2351 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2356 pic16_emitcode("push","%s",l);
2361 /* this is a paramter push: in this case we call
2362 the routine to find the call and save those
2363 registers that need to be saved */
2366 /* then do the push */
2367 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2370 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2371 size = AOP_SIZE(IC_LEFT(ic));
2374 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2375 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2376 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2378 pic16_emitcode("mov","a,%s",l);
2379 pic16_emitcode("push","acc");
2381 pic16_emitcode("push","%s",l);
2384 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2388 /*-----------------------------------------------------------------*/
2389 /* genIpop - recover the registers: can happen only for spilling */
2390 /*-----------------------------------------------------------------*/
2391 static void genIpop (iCode *ic)
2393 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2398 /* if the temp was not pushed then */
2399 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2402 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2403 size = AOP_SIZE(IC_LEFT(ic));
2406 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2409 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2413 /*-----------------------------------------------------------------*/
2414 /* unsaverbank - restores the resgister bank from stack */
2415 /*-----------------------------------------------------------------*/
2416 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2418 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2424 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2426 if (options.useXstack) {
2428 r = getFreePtr(ic,&aop,FALSE);
2431 pic16_emitcode("mov","%s,_spx",r->name);
2432 pic16_emitcode("movx","a,@%s",r->name);
2433 pic16_emitcode("mov","psw,a");
2434 pic16_emitcode("dec","%s",r->name);
2437 pic16_emitcode ("pop","psw");
2440 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2441 if (options.useXstack) {
2442 pic16_emitcode("movx","a,@%s",r->name);
2443 //pic16_emitcode("mov","(%s+%d),a",
2444 // regspic16[i].base,8*bank+regspic16[i].offset);
2445 pic16_emitcode("dec","%s",r->name);
2448 pic16_emitcode("pop",""); //"(%s+%d)",
2449 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2452 if (options.useXstack) {
2454 pic16_emitcode("mov","_spx,%s",r->name);
2455 pic16_freeAsmop(NULL,aop,ic,TRUE);
2461 /*-----------------------------------------------------------------*/
2462 /* saverbank - saves an entire register bank on the stack */
2463 /*-----------------------------------------------------------------*/
2464 static void saverbank (int bank, iCode *ic, bool pushPsw)
2466 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2472 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2473 if (options.useXstack) {
2476 r = getFreePtr(ic,&aop,FALSE);
2477 pic16_emitcode("mov","%s,_spx",r->name);
2481 for (i = 0 ; i < pic16_nRegs ;i++) {
2482 if (options.useXstack) {
2483 pic16_emitcode("inc","%s",r->name);
2484 //pic16_emitcode("mov","a,(%s+%d)",
2485 // regspic16[i].base,8*bank+regspic16[i].offset);
2486 pic16_emitcode("movx","@%s,a",r->name);
2488 pic16_emitcode("push","");// "(%s+%d)",
2489 //regspic16[i].base,8*bank+regspic16[i].offset);
2493 if (options.useXstack) {
2494 pic16_emitcode("mov","a,psw");
2495 pic16_emitcode("movx","@%s,a",r->name);
2496 pic16_emitcode("inc","%s",r->name);
2497 pic16_emitcode("mov","_spx,%s",r->name);
2498 pic16_freeAsmop (NULL,aop,ic,TRUE);
2501 pic16_emitcode("push","psw");
2503 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2511 /*-----------------------------------------------------------------*/
2512 /* genCall - generates a call statement */
2513 /*-----------------------------------------------------------------*/
2514 static void genCall (iCode *ic)
2519 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2521 /* if caller saves & we have not saved then */
2525 /* if we are calling a function that is not using
2526 * the same register bank then we need to save the
2527 * destination registers on the stack */
2528 dtype = operandType(IC_LEFT(ic));
2529 if (currFunc && dtype &&
2530 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2531 IFFUNC_ISISR(currFunc->type) &&
2534 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2536 /* if send set is not empty the assign */
2540 /* For the Pic port, there is no data stack.
2541 * So parameters passed to functions are stored
2542 * in registers. (The pCode optimizer will get
2543 * rid of most of these :). */
2545 int psuedoStkPtr=-1;
2546 int firstTimeThruLoop = 1;
2548 _G.sendSet = reverseSet(_G.sendSet);
2550 /* First figure how many parameters are getting passed */
2551 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2552 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2553 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2554 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2557 stackParms = psuedoStkPtr;
2559 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2560 int size, offset = 0;
2562 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2563 size = AOP_SIZE(IC_LEFT(sic));
2566 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2567 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2568 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2570 if(!firstTimeThruLoop) {
2571 /* If this is not the first time we've been through the loop
2572 * then we need to save the parameter in a temporary
2573 * register. The last byte of the last parameter is
2579 --psuedoStkPtr; // sanity check
2581 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2584 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2585 #endif /* STACK_SUPPORT */
2588 firstTimeThruLoop=0;
2590 mov2w (AOP(IC_LEFT(sic)), offset);
2593 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2599 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2600 OP_SYMBOL(IC_LEFT(ic))->rname :
2601 OP_SYMBOL(IC_LEFT(ic))->name));
2604 /* if we need assign a result value */
2605 if ((IS_ITEMP(IC_RESULT(ic)) &&
2606 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2607 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2608 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2611 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2614 assignResultValue(IC_RESULT(ic));
2616 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2617 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2619 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2623 if(USE_STACK && stackParms>0) {
2624 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2625 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2626 if(STACK_MODEL_LARGE) {
2628 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2633 /* adjust the stack for parameters if required */
2634 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2636 if (ic->parmBytes) {
2639 if (ic->parmBytes > 3) {
2640 pic16_emitcode("mov","a,%s",spname);
2641 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2642 pic16_emitcode("mov","%s,a",spname);
2644 for ( i = 0 ; i < ic->parmBytes ;i++)
2645 pic16_emitcode("dec","%s",spname);
2648 /* if register bank was saved then pop them */
2650 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2652 /* if we hade saved some registers then unsave them */
2653 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2654 unsaveRegisters (ic);
2657 /*-----------------------------------------------------------------*/
2658 /* genPcall - generates a call by pointer statement */
2659 /*-----------------------------------------------------------------*/
2660 static void genPcall (iCode *ic)
2663 symbol *rlbl = newiTempLabel(NULL);
2666 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2667 /* if caller saves & we have not saved then */
2671 /* if we are calling a function that is not using
2672 the same register bank then we need to save the
2673 destination registers on the stack */
2674 dtype = operandType(IC_LEFT(ic));
2675 if (currFunc && dtype &&
2676 IFFUNC_ISISR(currFunc->type) &&
2677 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2678 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2681 /* push the return address on to the stack */
2682 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2683 pic16_emitcode("push","acc");
2684 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2685 pic16_emitcode("push","acc");
2687 if (options.model == MODEL_FLAT24)
2689 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2690 pic16_emitcode("push","acc");
2693 /* now push the calling address */
2694 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2696 pushSide(IC_LEFT(ic), FPTRSIZE);
2698 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2700 /* if send set is not empty the assign */
2704 for (sic = setFirstItem(_G.sendSet) ; sic ;
2705 sic = setNextItem(_G.sendSet)) {
2706 int size, offset = 0;
2707 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2708 size = AOP_SIZE(IC_LEFT(sic));
2710 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2712 if (strcmp(l,fReturn[offset]))
2713 pic16_emitcode("mov","%s,%s",
2718 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2723 pic16_emitcode("ret","");
2724 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2727 /* if we need assign a result value */
2728 if ((IS_ITEMP(IC_RESULT(ic)) &&
2729 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2730 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2731 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2734 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2737 assignResultValue(IC_RESULT(ic));
2739 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2742 /* adjust the stack for parameters if
2744 if (ic->parmBytes) {
2746 if (ic->parmBytes > 3) {
2747 pic16_emitcode("mov","a,%s",spname);
2748 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2749 pic16_emitcode("mov","%s,a",spname);
2751 for ( i = 0 ; i < ic->parmBytes ;i++)
2752 pic16_emitcode("dec","%s",spname);
2756 /* if register bank was saved then unsave them */
2757 if (currFunc && dtype &&
2758 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2759 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2761 /* if we hade saved some registers then
2764 unsaveRegisters (ic);
2768 /*-----------------------------------------------------------------*/
2769 /* resultRemat - result is rematerializable */
2770 /*-----------------------------------------------------------------*/
2771 static int resultRemat (iCode *ic)
2773 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2774 if (SKIP_IC(ic) || ic->op == IFX)
2777 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2778 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2779 if (sym->remat && !POINTER_SET(ic))
2786 #if defined(__BORLANDC__) || defined(_MSC_VER)
2787 #define STRCASECMP stricmp
2789 #define STRCASECMP strcasecmp
2793 /*-----------------------------------------------------------------*/
2794 /* inExcludeList - return 1 if the string is in exclude Reg list */
2795 /*-----------------------------------------------------------------*/
2796 static bool inExcludeList(char *s)
2798 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2801 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2802 if (options.excludeRegs[i] &&
2803 STRCASECMP(options.excludeRegs[i],"none") == 0)
2806 for ( i = 0 ; options.excludeRegs[i]; i++) {
2807 if (options.excludeRegs[i] &&
2808 STRCASECMP(s,options.excludeRegs[i]) == 0)
2815 /*-----------------------------------------------------------------*/
2816 /* genFunction - generated code for function entry */
2817 /*-----------------------------------------------------------------*/
2818 static void genFunction (iCode *ic)
2823 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2825 labelOffset += (max_key+4);
2829 /* create the function header */
2830 pic16_emitcode(";","-----------------------------------------");
2831 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2832 pic16_emitcode(";","-----------------------------------------");
2834 pic16_emitcode("","%s:",sym->rname);
2835 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
2840 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
2841 if(strcmp(ab->name, sym->name)) {
2842 pic16_pBlockConvert2Absolute(pb);
2848 ftype = operandType(IC_LEFT(ic));
2850 if(IFFUNC_ISNAKED(ftype)) {
2851 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
2856 /* if critical function then turn interrupts off */
2857 if (IFFUNC_ISCRITICAL(ftype))
2858 pic16_emitcode("clr","ea");
2860 /* here we need to generate the equates for the
2861 * register bank if required */
2863 if (FUNC_REGBANK(ftype) != rbank) {
2866 rbank = FUNC_REGBANK(ftype);
2867 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2868 if (strcmp(regspic16[i].base,"0") == 0)
2869 pic16_emitcode("","%s = 0x%02x",
2871 8*rbank+regspic16[i].offset);
2873 pic16_emitcode ("","%s = %s + 0x%02x",
2876 *rbank+regspic16[i].offset);
2881 /* if this is an interrupt service routine then
2882 * save acc, b, dpl, dph */
2883 if (IFFUNC_ISISR(sym->type)) {
2884 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2885 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2886 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2887 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2889 pic16_pBlockConvert2ISR(pb);
2891 if (!inExcludeList("acc"))
2892 pic16_emitcode ("push","acc");
2893 if (!inExcludeList("b"))
2894 pic16_emitcode ("push","b");
2895 if (!inExcludeList("dpl"))
2896 pic16_emitcode ("push","dpl");
2897 if (!inExcludeList("dph"))
2898 pic16_emitcode ("push","dph");
2900 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) {
2901 pic16_emitcode ("push", "dpx");
2903 /* Make sure we're using standard DPTR */
2904 pic16_emitcode ("push", "dps");
2905 pic16_emitcode ("mov", "dps, #0x00");
2906 if (options.stack10bit) {
2907 /* This ISR could conceivably use DPTR2. Better save it. */
2908 pic16_emitcode ("push", "dpl1");
2909 pic16_emitcode ("push", "dph1");
2910 pic16_emitcode ("push", "dpx1");
2914 /* if this isr has no bank i.e. is going to
2915 * run with bank 0 , then we need to save more
2917 if (!FUNC_REGBANK(sym->type)) {
2919 /* if this function does not call any other
2920 * function then we can be economical and
2921 * save only those registers that are used */
2922 if (! IFFUNC_HASFCALL(sym->type)) {
2925 /* if any registers used */
2926 if (sym->regsUsed) {
2927 /* save the registers used */
2928 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2929 if (bitVectBitValue(sym->regsUsed,i) ||
2930 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2931 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2936 /* this function has a function call cannot
2937 * determines register usage so we will have the
2939 saverbank(0,ic,FALSE);
2945 /* emit code to setup stack frame if user enabled,
2946 * and function is not main() */
2948 // fprintf(stderr, "function name: %s\n", sym->name);
2949 if(USE_STACK && strcmp(sym->name, "main")) {
2950 if(!options.ommitFramePtr || sym->regsUsed) {
2951 /* setup the stack frame */
2952 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
2953 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
2954 if(STACK_MODEL_LARGE)
2955 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
2960 /* if callee-save to be used for this function
2961 * then save the registers being used in this function */
2962 if (IFFUNC_CALLEESAVES(sym->type)) {
2965 // fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
2967 /* if any registers used */
2973 /* save the registers used */
2974 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
2975 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2976 if (bitVectBitValue(sym->regsUsed,i)) {
2977 // fprintf(stderr, "%s:%d function %s uses register %s\n",
2978 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
2979 // pic16_regWithIdx(i)->name);
2981 pic16_pushpCodeOpReg( PCOR(pic16_popRegFromIdx(i) ));
2982 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
2983 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
2984 // &pic16_pc_postdec1, 0));
2995 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2997 if (options.useXstack) {
2998 pic16_emitcode("mov","r0,%s",spname);
2999 pic16_emitcode("mov","a,_bp");
3000 pic16_emitcode("movx","@r0,a");
3001 pic16_emitcode("inc","%s",spname);
3003 /* set up the stack */
3004 pic16_emitcode ("push","_bp"); /* save the callers stack */
3006 pic16_emitcode ("mov","_bp,%s",spname);
3009 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3011 /* adjust the stack for the function */
3016 werror(W_STACK_OVERFLOW,sym->name);
3018 if (i > 3 && sym->recvSize < 4) {
3019 pic16_emitcode ("mov","a,sp");
3020 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3021 pic16_emitcode ("mov","sp,a");
3024 pic16_emitcode("inc","sp");
3028 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3030 pic16_emitcode ("mov","a,_spx");
3031 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3032 pic16_emitcode ("mov","_spx,a");
3037 /*-----------------------------------------------------------------*/
3038 /* genEndFunction - generates epilogue for functions */
3039 /*-----------------------------------------------------------------*/
3040 static void genEndFunction (iCode *ic)
3042 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3044 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3046 if(IFFUNC_ISNAKED(sym->type)) {
3047 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3052 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3054 pic16_emitcode ("mov","%s,_bp",spname);
3058 /* if use external stack but some variables were
3059 added to the local stack then decrement the
3061 if (options.useXstack && sym->stack) {
3062 pic16_emitcode("mov","a,sp");
3063 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3064 pic16_emitcode("mov","sp,a");
3069 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3070 if (options.useXstack) {
3071 pic16_emitcode("mov","r0,%s",spname);
3072 pic16_emitcode("movx","a,@r0");
3073 pic16_emitcode("mov","_bp,a");
3074 pic16_emitcode("dec","%s",spname);
3078 pic16_emitcode ("pop","_bp");
3083 /* restore the register bank */
3084 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
3085 pic16_emitcode ("pop","psw");
3087 if (IFFUNC_ISISR(sym->type)) {
3089 /* now we need to restore the registers */
3090 /* if this isr has no bank i.e. is going to
3091 run with bank 0 , then we need to save more
3093 if (!FUNC_REGBANK(sym->type)) {
3095 /* if this function does not call any other
3096 function then we can be economical and
3097 save only those registers that are used */
3098 if (! IFFUNC_HASFCALL(sym->type)) {
3101 /* if any registers used */
3102 if (sym->regsUsed) {
3103 /* save the registers used */
3104 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3105 if (bitVectBitValue(sym->regsUsed,i) ||
3106 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3107 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
3112 /* this function has a function call cannot
3113 determines register usage so we will have the
3115 unsaverbank(0,ic,FALSE);
3119 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
3121 if (options.stack10bit)
3123 pic16_emitcode ("pop", "dpx1");
3124 pic16_emitcode ("pop", "dph1");
3125 pic16_emitcode ("pop", "dpl1");
3127 pic16_emitcode ("pop", "dps");
3128 pic16_emitcode ("pop", "dpx");
3130 if (!inExcludeList("dph"))
3131 pic16_emitcode ("pop","dph");
3132 if (!inExcludeList("dpl"))
3133 pic16_emitcode ("pop","dpl");
3134 if (!inExcludeList("b"))
3135 pic16_emitcode ("pop","b");
3136 if (!inExcludeList("acc"))
3137 pic16_emitcode ("pop","acc");
3139 if (IFFUNC_ISCRITICAL(sym->type))
3140 pic16_emitcode("setb","ea");
3143 /* if debug then send end of function */
3144 /* if (options.debug && currFunc) { */
3147 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3148 FileBaseName(ic->filename),currFunc->lastLine,
3149 ic->level,ic->block);
3150 if (IS_STATIC(currFunc->etype))
3151 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3153 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3157 // pic16_emitcode ("reti","");
3159 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
3160 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
3161 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
3162 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
3163 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
3166 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
3169 pic16_emitpcodeNULLop(POC_RETFIE);
3173 if (IFFUNC_ISCRITICAL(sym->type))
3174 pic16_emitcode("setb","ea");
3176 /* if any registers used */
3183 /* save the registers used */
3184 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3185 for ( i = sym->regsUsed->size; i >= 0; i--) {
3186 if (bitVectBitValue(sym->regsUsed,i)) {
3187 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3188 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3189 // pic16_regWithIdx(i)->name);
3191 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3193 PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3199 /* if debug then send end of function */
3202 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3203 FileBaseName(ic->filename),currFunc->lastLine,
3204 ic->level,ic->block);
3205 if (IS_STATIC(currFunc->etype))
3206 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3208 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3213 /* insert code to restore stack frame, if user enabled it
3214 * and function is not main() */
3216 if(USE_STACK && strcmp(sym->name, "main")) {
3217 if(!options.ommitFramePtr || sym->regsUsed) {
3218 /* restore stack frame */
3219 if(STACK_MODEL_LARGE)
3220 pic16_emitpcode(POC_MOVFF,
3221 pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h, 0));
3222 pic16_emitpcode(POC_MOVFF,
3223 pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l, 0));
3228 pic16_emitcode ("return","");
3229 pic16_emitpcodeNULLop(POC_RETURN);
3231 /* Mark the end of a function */
3232 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3237 /*-----------------------------------------------------------------*/
3238 /* genRet - generate code for return statement */
3239 /*-----------------------------------------------------------------*/
3240 static void genRet (iCode *ic)
3242 int size,offset = 0 , pushed = 0;
3244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3245 /* if we have no return value then
3246 just generate the "ret" */
3250 /* we have something to return then
3251 move the return value into place */
3252 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3253 size = AOP_SIZE(IC_LEFT(ic));
3257 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3259 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3261 pic16_emitcode("push","%s",l);
3264 DEBUGpic16_emitcode(";", "%d", __LINE__);
3265 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3267 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3268 if (strcmp(fReturn[offset],l)) {
3269 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3270 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3271 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3273 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3276 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3286 if (strcmp(fReturn[pushed],"a"))
3287 pic16_emitcode("pop",fReturn[pushed]);
3289 pic16_emitcode("pop","acc");
3292 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3295 /* generate a jump to the return label
3296 if the next is not the return statement */
3297 if (!(ic->next && ic->next->op == LABEL &&
3298 IC_LABEL(ic->next) == returnLabel)) {
3300 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3301 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3306 /*-----------------------------------------------------------------*/
3307 /* genLabel - generates a label */
3308 /*-----------------------------------------------------------------*/
3309 static void genLabel (iCode *ic)
3311 /* special case never generate */
3312 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3313 if (IC_LABEL(ic) == entryLabel)
3316 pic16_emitpLabel(IC_LABEL(ic)->key);
3317 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3320 /*-----------------------------------------------------------------*/
3321 /* genGoto - generates a goto */
3322 /*-----------------------------------------------------------------*/
3324 static void genGoto (iCode *ic)
3326 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3327 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3331 /*-----------------------------------------------------------------*/
3332 /* genMultbits :- multiplication of bits */
3333 /*-----------------------------------------------------------------*/
3334 static void genMultbits (operand *left,
3338 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3340 if(!pic16_sameRegs(AOP(result),AOP(right)))
3341 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3343 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3344 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3345 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3350 /*-----------------------------------------------------------------*/
3351 /* genMultOneByte : 8 bit multiplication & division */
3352 /*-----------------------------------------------------------------*/
3353 static void genMultOneByte (operand *left,
3357 sym_link *opetype = operandType(result);
3362 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3363 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3364 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3366 /* (if two literals, the value is computed before) */
3367 /* if one literal, literal on the right */
3368 if (AOP_TYPE(left) == AOP_LIT){
3374 size = AOP_SIZE(result);
3377 if (AOP_TYPE(right) == AOP_LIT){
3378 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3379 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3380 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3381 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3382 pic16_emitcode("call","genMultLit");
3384 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3385 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3386 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3387 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3388 pic16_emitcode("call","pic16_genMult8X8_8");
3391 pic16_genMult8X8_8 (left, right,result);
3394 /* signed or unsigned */
3395 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3396 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3398 //pic16_emitcode("mul","ab");
3399 /* if result size = 1, mul signed = mul unsigned */
3400 //pic16_aopPut(AOP(result),"a",0);
3402 } else { // (size > 1)
3404 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3405 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3406 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3407 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3409 if (SPEC_USIGN(opetype)){
3410 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3411 pic16_genUMult8X8_16 (left, right, result, NULL);
3414 /* for filling the MSBs */
3415 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3416 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3420 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3422 pic16_emitcode("mov","a,b");
3424 /* adjust the MSB if left or right neg */
3426 /* if one literal */
3427 if (AOP_TYPE(right) == AOP_LIT){
3428 pic16_emitcode("multiply ","right is a lit");
3429 /* AND literal negative */
3430 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3431 /* adjust MSB (c==0 after mul) */
3432 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3436 pic16_genSMult8X8_16 (left, right, result, NULL);
3440 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3442 pic16_emitcode("rlc","a");
3443 pic16_emitcode("subb","a,acc");
3451 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3452 //pic16_aopPut(AOP(result),"a",offset++);
3456 /*-----------------------------------------------------------------*/
3457 /* genMult - generates code for multiplication */
3458 /*-----------------------------------------------------------------*/
3459 static void genMult (iCode *ic)
3461 operand *left = IC_LEFT(ic);
3462 operand *right = IC_RIGHT(ic);
3463 operand *result= IC_RESULT(ic);
3465 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3466 /* assign the amsops */
3467 pic16_aopOp (left,ic,FALSE);
3468 pic16_aopOp (right,ic,FALSE);
3469 pic16_aopOp (result,ic,TRUE);
3471 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3473 /* special cases first */
3475 if (AOP_TYPE(left) == AOP_CRY &&
3476 AOP_TYPE(right)== AOP_CRY) {
3477 genMultbits(left,right,result);
3481 /* if both are of size == 1 */
3482 if (AOP_SIZE(left) == 1 &&
3483 AOP_SIZE(right) == 1 ) {
3484 genMultOneByte(left,right,result);
3488 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3490 /* should have been converted to function call */
3494 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3495 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3496 pic16_freeAsmop(result,NULL,ic,TRUE);
3499 /*-----------------------------------------------------------------*/
3500 /* genDivbits :- division of bits */
3501 /*-----------------------------------------------------------------*/
3502 static void genDivbits (operand *left,
3509 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3510 /* the result must be bit */
3511 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3512 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3516 pic16_emitcode("div","ab");
3517 pic16_emitcode("rrc","a");
3518 pic16_aopPut(AOP(result),"c",0);
3521 /*-----------------------------------------------------------------*/
3522 /* genDivOneByte : 8 bit division */
3523 /*-----------------------------------------------------------------*/
3524 static void genDivOneByte (operand *left,
3528 sym_link *opetype = operandType(result);
3533 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3534 size = AOP_SIZE(result) - 1;
3536 /* signed or unsigned */
3537 if (SPEC_USIGN(opetype)) {
3538 /* unsigned is easy */
3539 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3540 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3542 pic16_emitcode("div","ab");
3543 pic16_aopPut(AOP(result),"a",0);
3545 pic16_aopPut(AOP(result),zero,offset++);
3549 /* signed is a little bit more difficult */
3551 /* save the signs of the operands */
3552 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3554 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3555 pic16_emitcode("push","acc"); /* save it on the stack */
3557 /* now sign adjust for both left & right */
3558 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3560 lbl = newiTempLabel(NULL);
3561 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3562 pic16_emitcode("cpl","a");
3563 pic16_emitcode("inc","a");
3564 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3565 pic16_emitcode("mov","b,a");
3567 /* sign adjust left side */
3568 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3571 lbl = newiTempLabel(NULL);
3572 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3573 pic16_emitcode("cpl","a");
3574 pic16_emitcode("inc","a");
3575 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3577 /* now the division */
3578 pic16_emitcode("div","ab");
3579 /* we are interested in the lower order
3581 pic16_emitcode("mov","b,a");
3582 lbl = newiTempLabel(NULL);
3583 pic16_emitcode("pop","acc");
3584 /* if there was an over flow we don't
3585 adjust the sign of the result */
3586 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3587 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3589 pic16_emitcode("clr","a");
3590 pic16_emitcode("subb","a,b");
3591 pic16_emitcode("mov","b,a");
3592 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3594 /* now we are done */
3595 pic16_aopPut(AOP(result),"b",0);
3597 pic16_emitcode("mov","c,b.7");
3598 pic16_emitcode("subb","a,acc");
3601 pic16_aopPut(AOP(result),"a",offset++);
3605 /*-----------------------------------------------------------------*/
3606 /* genDiv - generates code for division */
3607 /*-----------------------------------------------------------------*/
3608 static void genDiv (iCode *ic)
3610 operand *left = IC_LEFT(ic);
3611 operand *right = IC_RIGHT(ic);
3612 operand *result= IC_RESULT(ic);
3614 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3615 /* assign the amsops */
3616 pic16_aopOp (left,ic,FALSE);
3617 pic16_aopOp (right,ic,FALSE);
3618 pic16_aopOp (result,ic,TRUE);
3620 /* special cases first */
3622 if (AOP_TYPE(left) == AOP_CRY &&
3623 AOP_TYPE(right)== AOP_CRY) {
3624 genDivbits(left,right,result);
3628 /* if both are of size == 1 */
3629 if (AOP_SIZE(left) == 1 &&
3630 AOP_SIZE(right) == 1 ) {
3631 genDivOneByte(left,right,result);
3635 /* should have been converted to function call */
3638 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3639 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3640 pic16_freeAsmop(result,NULL,ic,TRUE);
3643 /*-----------------------------------------------------------------*/
3644 /* genModbits :- modulus of bits */
3645 /*-----------------------------------------------------------------*/
3646 static void genModbits (operand *left,
3653 /* the result must be bit */
3654 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3655 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3659 pic16_emitcode("div","ab");
3660 pic16_emitcode("mov","a,b");
3661 pic16_emitcode("rrc","a");
3662 pic16_aopPut(AOP(result),"c",0);
3665 /*-----------------------------------------------------------------*/
3666 /* genModOneByte : 8 bit modulus */
3667 /*-----------------------------------------------------------------*/
3668 static void genModOneByte (operand *left,
3672 sym_link *opetype = operandType(result);
3676 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3677 /* signed or unsigned */
3678 if (SPEC_USIGN(opetype)) {
3679 /* unsigned is easy */
3680 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3681 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3683 pic16_emitcode("div","ab");
3684 pic16_aopPut(AOP(result),"b",0);
3688 /* signed is a little bit more difficult */
3690 /* save the signs of the operands */
3691 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3694 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3695 pic16_emitcode("push","acc"); /* save it on the stack */
3697 /* now sign adjust for both left & right */
3698 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3701 lbl = newiTempLabel(NULL);
3702 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3703 pic16_emitcode("cpl","a");
3704 pic16_emitcode("inc","a");
3705 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3706 pic16_emitcode("mov","b,a");
3708 /* sign adjust left side */
3709 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3712 lbl = newiTempLabel(NULL);
3713 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3714 pic16_emitcode("cpl","a");
3715 pic16_emitcode("inc","a");
3716 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3718 /* now the multiplication */
3719 pic16_emitcode("div","ab");
3720 /* we are interested in the lower order
3722 lbl = newiTempLabel(NULL);
3723 pic16_emitcode("pop","acc");
3724 /* if there was an over flow we don't
3725 adjust the sign of the result */
3726 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3727 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3729 pic16_emitcode("clr","a");
3730 pic16_emitcode("subb","a,b");
3731 pic16_emitcode("mov","b,a");
3732 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3734 /* now we are done */
3735 pic16_aopPut(AOP(result),"b",0);
3739 /*-----------------------------------------------------------------*/
3740 /* genMod - generates code for division */
3741 /*-----------------------------------------------------------------*/
3742 static void genMod (iCode *ic)
3744 operand *left = IC_LEFT(ic);
3745 operand *right = IC_RIGHT(ic);
3746 operand *result= IC_RESULT(ic);
3748 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3749 /* assign the amsops */
3750 pic16_aopOp (left,ic,FALSE);
3751 pic16_aopOp (right,ic,FALSE);
3752 pic16_aopOp (result,ic,TRUE);
3754 /* special cases first */
3756 if (AOP_TYPE(left) == AOP_CRY &&
3757 AOP_TYPE(right)== AOP_CRY) {
3758 genModbits(left,right,result);
3762 /* if both are of size == 1 */
3763 if (AOP_SIZE(left) == 1 &&
3764 AOP_SIZE(right) == 1 ) {
3765 genModOneByte(left,right,result);
3769 /* should have been converted to function call */
3773 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3774 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3775 pic16_freeAsmop(result,NULL,ic,TRUE);
3778 /*-----------------------------------------------------------------*/
3779 /* genIfxJump :- will create a jump depending on the ifx */
3780 /*-----------------------------------------------------------------*/
3782 note: May need to add parameter to indicate when a variable is in bit space.
3784 static void genIfxJump (iCode *ic, char *jval)
3787 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3788 /* if true label then we jump if condition
3790 if ( IC_TRUE(ic) ) {
3792 if(strcmp(jval,"a") == 0)
3794 else if (strcmp(jval,"c") == 0)
3797 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3798 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3801 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3802 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3806 /* false label is present */
3807 if(strcmp(jval,"a") == 0)
3809 else if (strcmp(jval,"c") == 0)
3812 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3813 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3816 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3817 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3822 /* mark the icode as generated */
3826 /*-----------------------------------------------------------------*/
3828 /*-----------------------------------------------------------------*/
3829 static void genSkip(iCode *ifx,int status_bit)
3831 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3835 if ( IC_TRUE(ifx) ) {
3836 switch(status_bit) {
3851 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3852 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3856 switch(status_bit) {
3870 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3871 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3877 /*-----------------------------------------------------------------*/
3879 /*-----------------------------------------------------------------*/
3880 static void genSkipc(resolvedIfx *rifx)
3890 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3891 rifx->generated = 1;
3894 /*-----------------------------------------------------------------*/
3896 /*-----------------------------------------------------------------*/
3897 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3902 if( (rifx->condition ^ invert_condition) & 1)
3907 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3908 rifx->generated = 1;
3912 /*-----------------------------------------------------------------*/
3914 /*-----------------------------------------------------------------*/
3915 static void genSkipz(iCode *ifx, int condition)
3926 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3928 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3931 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3933 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3938 /*-----------------------------------------------------------------*/
3940 /*-----------------------------------------------------------------*/
3941 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3947 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3949 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3952 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3953 rifx->generated = 1;
3957 /*-----------------------------------------------------------------*/
3958 /* genChkZeroes :- greater or less than comparison */
3959 /* For each byte in a literal that is zero, inclusive or the */
3960 /* the corresponding byte in the operand with W */
3961 /* returns true if any of the bytes are zero */
3962 /*-----------------------------------------------------------------*/
3963 static int genChkZeroes(operand *op, int lit, int size)
3970 i = (lit >> (size*8)) & 0xff;
3974 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3976 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3985 /*-----------------------------------------------------------------*/
3986 /* genCmp :- greater or less than comparison */
3987 /*-----------------------------------------------------------------*/
3988 static void genCmp (operand *left,operand *right,
3989 operand *result, iCode *ifx, int sign)
3991 int size; //, offset = 0 ;
3992 unsigned long lit = 0L,i = 0;
3993 resolvedIfx rFalseIfx;
3994 // resolvedIfx rTrueIfx;
3996 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3999 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4000 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4004 resolveIfx(&rFalseIfx,ifx);
4005 truelbl = newiTempLabel(NULL);
4006 size = max(AOP_SIZE(left),AOP_SIZE(right));
4008 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4012 /* if literal is on the right then swap with left */
4013 if ((AOP_TYPE(right) == AOP_LIT)) {
4014 operand *tmp = right ;
4015 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4016 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4019 lit = (lit - 1) & mask;
4022 rFalseIfx.condition ^= 1;
4025 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4026 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4030 //if(IC_TRUE(ifx) == NULL)
4031 /* if left & right are bit variables */
4032 if (AOP_TYPE(left) == AOP_CRY &&
4033 AOP_TYPE(right) == AOP_CRY ) {
4034 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4035 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4037 /* subtract right from left if at the
4038 end the carry flag is set then we know that
4039 left is greater than right */
4043 symbol *lbl = newiTempLabel(NULL);
4046 if(AOP_TYPE(right) == AOP_LIT) {
4048 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4050 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4057 genSkipCond(&rFalseIfx,left,size-1,7);
4059 /* no need to compare to 0...*/
4060 /* NOTE: this is a de-generate compare that most certainly
4061 * creates some dead code. */
4062 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4064 if(ifx) ifx->generated = 1;
4071 //i = (lit >> (size*8)) & 0xff;
4072 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4074 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4076 i = ((0-lit) & 0xff);
4079 /* lit is 0x7f, all signed chars are less than
4080 * this except for 0x7f itself */
4081 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4082 genSkipz2(&rFalseIfx,0);
4084 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4085 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4086 genSkipc(&rFalseIfx);
4091 genSkipz2(&rFalseIfx,1);
4093 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4094 genSkipc(&rFalseIfx);
4098 if(ifx) ifx->generated = 1;
4102 /* chars are out of the way. now do ints and longs */
4105 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4112 genSkipCond(&rFalseIfx,left,size,7);
4113 if(ifx) ifx->generated = 1;
4118 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4120 //rFalseIfx.condition ^= 1;
4121 //genSkipCond(&rFalseIfx,left,size,7);
4122 //rFalseIfx.condition ^= 1;
4124 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4125 if(rFalseIfx.condition)
4126 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4128 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4130 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4131 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4132 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4135 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4137 if(rFalseIfx.condition) {
4139 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4145 genSkipc(&rFalseIfx);
4146 pic16_emitpLabel(truelbl->key);
4147 if(ifx) ifx->generated = 1;
4154 if( (lit & 0xff) == 0) {
4155 /* lower byte is zero */
4156 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4157 i = ((lit >> 8) & 0xff) ^0x80;
4158 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4159 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4160 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4161 genSkipc(&rFalseIfx);
4164 if(ifx) ifx->generated = 1;
4169 /* Special cases for signed longs */
4170 if( (lit & 0xffffff) == 0) {
4171 /* lower byte is zero */
4172 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4173 i = ((lit >> 8*3) & 0xff) ^0x80;
4174 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4175 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4176 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4177 genSkipc(&rFalseIfx);
4180 if(ifx) ifx->generated = 1;
4188 if(lit & (0x80 << (size*8))) {
4189 /* lit is negative */
4190 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4192 //genSkipCond(&rFalseIfx,left,size,7);
4194 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4196 if(rFalseIfx.condition)
4197 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4199 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4203 /* lit is positive */
4204 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4205 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4206 if(rFalseIfx.condition)
4207 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4209 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4214 This works, but is only good for ints.
4215 It also requires a "known zero" register.
4216 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4217 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4218 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4219 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4220 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4221 genSkipc(&rFalseIfx);
4223 pic16_emitpLabel(truelbl->key);
4224 if(ifx) ifx->generated = 1;
4228 /* There are no more special cases, so perform a general compare */
4230 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4231 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4235 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4237 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4239 //rFalseIfx.condition ^= 1;
4240 genSkipc(&rFalseIfx);
4242 pic16_emitpLabel(truelbl->key);
4244 if(ifx) ifx->generated = 1;
4251 /* sign is out of the way. So now do an unsigned compare */
4252 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4255 /* General case - compare to an unsigned literal on the right.*/
4257 i = (lit >> (size*8)) & 0xff;
4258 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4259 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4261 i = (lit >> (size*8)) & 0xff;
4264 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4266 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4268 /* this byte of the lit is zero,
4269 *if it's not the last then OR in the variable */
4271 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4276 pic16_emitpLabel(lbl->key);
4277 //if(emitFinalCheck)
4278 genSkipc(&rFalseIfx);
4280 pic16_emitpLabel(truelbl->key);
4282 if(ifx) ifx->generated = 1;
4289 if(AOP_TYPE(left) == AOP_LIT) {
4290 //symbol *lbl = newiTempLabel(NULL);
4292 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4295 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4298 if((lit == 0) && (sign == 0)){
4301 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4303 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4305 genSkipz2(&rFalseIfx,0);
4306 if(ifx) ifx->generated = 1;
4313 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4314 /* degenerate compare can never be true */
4315 if(rFalseIfx.condition == 0)
4316 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4318 if(ifx) ifx->generated = 1;
4323 /* signed comparisons to a literal byte */
4325 int lp1 = (lit+1) & 0xff;
4327 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4330 rFalseIfx.condition ^= 1;
4331 genSkipCond(&rFalseIfx,right,0,7);
4334 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4335 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4336 genSkipz2(&rFalseIfx,1);
4339 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4340 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4341 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4342 rFalseIfx.condition ^= 1;
4343 genSkipc(&rFalseIfx);
4347 /* unsigned comparisons to a literal byte */
4349 switch(lit & 0xff ) {
4351 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4352 genSkipz2(&rFalseIfx,0);
4355 rFalseIfx.condition ^= 1;
4356 genSkipCond(&rFalseIfx,right,0,7);
4360 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4361 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4362 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4363 rFalseIfx.condition ^= 1;
4364 if (AOP_TYPE(result) == AOP_CRY)
4365 genSkipc(&rFalseIfx);
4367 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4368 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4374 if(ifx) ifx->generated = 1;
4380 /* Size is greater than 1 */
4388 /* this means lit = 0xffffffff, or -1 */
4391 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4392 rFalseIfx.condition ^= 1;
4393 genSkipCond(&rFalseIfx,right,size,7);
4394 if(ifx) ifx->generated = 1;
4401 if(rFalseIfx.condition) {
4402 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4403 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4406 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4408 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4412 if(rFalseIfx.condition) {
4413 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4414 pic16_emitpLabel(truelbl->key);
4416 rFalseIfx.condition ^= 1;
4417 genSkipCond(&rFalseIfx,right,s,7);
4420 if(ifx) ifx->generated = 1;
4424 if((size == 1) && (0 == (lp1&0xff))) {
4425 /* lower byte of signed word is zero */
4426 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4427 i = ((lp1 >> 8) & 0xff) ^0x80;
4428 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4429 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4430 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4431 rFalseIfx.condition ^= 1;
4432 genSkipc(&rFalseIfx);
4435 if(ifx) ifx->generated = 1;
4439 if(lit & (0x80 << (size*8))) {
4440 /* Lit is less than zero */
4441 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4442 //rFalseIfx.condition ^= 1;
4443 //genSkipCond(&rFalseIfx,left,size,7);
4444 //rFalseIfx.condition ^= 1;
4445 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4446 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4448 if(rFalseIfx.condition)
4449 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4451 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4455 /* Lit is greater than or equal to zero */
4456 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4457 //rFalseIfx.condition ^= 1;
4458 //genSkipCond(&rFalseIfx,right,size,7);
4459 //rFalseIfx.condition ^= 1;
4461 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4462 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4464 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4465 if(rFalseIfx.condition)
4466 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4468 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4473 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4474 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4478 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4480 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4482 rFalseIfx.condition ^= 1;
4483 //rFalseIfx.condition = 1;
4484 genSkipc(&rFalseIfx);
4486 pic16_emitpLabel(truelbl->key);
4488 if(ifx) ifx->generated = 1;
4493 /* compare word or long to an unsigned literal on the right.*/
4498 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4501 break; /* handled above */
4504 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4506 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4507 genSkipz2(&rFalseIfx,0);
4511 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4513 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4516 if(rFalseIfx.condition)
4517 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4519 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4522 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4523 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4525 rFalseIfx.condition ^= 1;
4526 genSkipc(&rFalseIfx);
4529 pic16_emitpLabel(truelbl->key);
4531 if(ifx) ifx->generated = 1;
4537 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4538 i = (lit >> (size*8)) & 0xff;
4540 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4541 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4544 i = (lit >> (size*8)) & 0xff;
4547 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4549 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4551 /* this byte of the lit is zero,
4552 *if it's not the last then OR in the variable */
4554 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4559 pic16_emitpLabel(lbl->key);
4561 rFalseIfx.condition ^= 1;
4562 genSkipc(&rFalseIfx);
4566 pic16_emitpLabel(truelbl->key);
4567 if(ifx) ifx->generated = 1;
4571 /* Compare two variables */
4573 DEBUGpic16_emitcode(";sign","%d",sign);
4577 /* Sigh. thus sucks... */
4579 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4580 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4581 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4582 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4583 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4584 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4586 /* Signed char comparison */
4587 /* Special thanks to Nikolai Golovchenko for this snippet */
4588 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4589 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4590 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4591 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4592 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4593 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4595 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4596 genSkipc(&rFalseIfx);
4598 if(ifx) ifx->generated = 1;
4604 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4605 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4609 /* The rest of the bytes of a multi-byte compare */
4613 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4616 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4617 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4622 pic16_emitpLabel(lbl->key);
4624 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4625 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4626 (AOP_TYPE(result) == AOP_REG)) {
4627 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4628 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4630 genSkipc(&rFalseIfx);
4632 //genSkipc(&rFalseIfx);
4633 if(ifx) ifx->generated = 1;
4640 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4641 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4642 pic16_outBitC(result);
4644 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4645 /* if the result is used in the next
4646 ifx conditional branch then generate
4647 code a little differently */
4649 genIfxJump (ifx,"c");
4651 pic16_outBitC(result);
4652 /* leave the result in acc */
4657 /*-----------------------------------------------------------------*/
4658 /* genCmpGt :- greater than comparison */
4659 /*-----------------------------------------------------------------*/
4660 static void genCmpGt (iCode *ic, iCode *ifx)
4662 operand *left, *right, *result;
4663 sym_link *letype , *retype;
4666 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4668 right= IC_RIGHT(ic);
4669 result = IC_RESULT(ic);
4671 letype = getSpec(operandType(left));
4672 retype =getSpec(operandType(right));
4673 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4674 /* assign the amsops */
4675 pic16_aopOp (left,ic,FALSE);
4676 pic16_aopOp (right,ic,FALSE);
4677 pic16_aopOp (result,ic,TRUE);
4679 genCmp(right, left, result, ifx, sign);
4681 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4682 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4683 pic16_freeAsmop(result,NULL,ic,TRUE);
4686 /*-----------------------------------------------------------------*/
4687 /* genCmpLt - less than comparisons */
4688 /*-----------------------------------------------------------------*/
4689 static void genCmpLt (iCode *ic, iCode *ifx)
4691 operand *left, *right, *result;
4692 sym_link *letype , *retype;
4695 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4697 right= IC_RIGHT(ic);
4698 result = IC_RESULT(ic);
4700 letype = getSpec(operandType(left));
4701 retype =getSpec(operandType(right));
4702 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4704 /* assign the amsops */
4705 pic16_aopOp (left,ic,FALSE);
4706 pic16_aopOp (right,ic,FALSE);
4707 pic16_aopOp (result,ic,TRUE);
4709 genCmp(left, right, result, ifx, sign);
4711 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4712 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4713 pic16_freeAsmop(result,NULL,ic,TRUE);
4716 /*-----------------------------------------------------------------*/
4717 /* genc16bit2lit - compare a 16 bit value to a literal */
4718 /*-----------------------------------------------------------------*/
4719 static void genc16bit2lit(operand *op, int lit, int offset)
4723 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4724 if( (lit&0xff) == 0)
4729 switch( BYTEofLONG(lit,i)) {
4731 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4734 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4737 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4740 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4741 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4746 switch( BYTEofLONG(lit,i)) {
4748 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4752 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4756 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4759 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4761 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4767 /*-----------------------------------------------------------------*/
4768 /* gencjneshort - compare and jump if not equal */
4769 /*-----------------------------------------------------------------*/
4770 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4772 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4774 int res_offset = 0; /* the result may be a different size then left or right */
4775 int res_size = AOP_SIZE(result);
4779 unsigned long lit = 0L;
4780 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4781 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4783 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4784 resolveIfx(&rIfx,ifx);
4785 lbl = newiTempLabel(NULL);
4788 /* if the left side is a literal or
4789 if the right is in a pointer register and left
4791 if ((AOP_TYPE(left) == AOP_LIT) ||
4792 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4797 if(AOP_TYPE(right) == AOP_LIT)
4798 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4800 /* if the right side is a literal then anything goes */
4801 if (AOP_TYPE(right) == AOP_LIT &&
4802 AOP_TYPE(left) != AOP_DIR ) {
4805 genc16bit2lit(left, lit, 0);
4807 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4812 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4813 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4815 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4819 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4821 if(res_offset < res_size-1)
4829 /* if the right side is in a register or in direct space or
4830 if the left is a pointer register & right is not */
4831 else if (AOP_TYPE(right) == AOP_REG ||
4832 AOP_TYPE(right) == AOP_DIR ||
4833 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4834 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4835 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4836 int lbl_key = lbl->key;
4839 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4840 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4842 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4843 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4844 __FUNCTION__,__LINE__);
4848 /* switch(size) { */
4850 /* genc16bit2lit(left, lit, 0); */
4852 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4857 if((AOP_TYPE(left) == AOP_DIR) &&
4858 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4860 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4861 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4863 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4865 switch (lit & 0xff) {
4867 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4870 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4871 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4872 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4876 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4877 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4878 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4879 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4883 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4884 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4889 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4892 if(AOP_TYPE(result) == AOP_CRY) {
4893 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4898 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4900 /* fix me. probably need to check result size too */
4901 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4906 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4907 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4914 if(res_offset < res_size-1)
4919 } else if(AOP_TYPE(right) == AOP_REG &&
4920 AOP_TYPE(left) != AOP_DIR){
4923 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4924 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4925 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4930 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4932 if(res_offset < res_size-1)
4937 /* right is a pointer reg need both a & b */
4939 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4941 pic16_emitcode("mov","b,%s",l);
4942 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4943 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4948 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4950 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4952 pic16_emitpLabel(lbl->key);
4954 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4961 /*-----------------------------------------------------------------*/
4962 /* gencjne - compare and jump if not equal */
4963 /*-----------------------------------------------------------------*/
4964 static void gencjne(operand *left, operand *right, iCode *ifx)
4966 symbol *tlbl = newiTempLabel(NULL);
4968 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4969 gencjneshort(left, right, lbl);
4971 pic16_emitcode("mov","a,%s",one);
4972 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4973 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4974 pic16_emitcode("clr","a");
4975 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4977 pic16_emitpLabel(lbl->key);
4978 pic16_emitpLabel(tlbl->key);
4983 /*-----------------------------------------------------------------*/
4984 /* genCmpEq - generates code for equal to */
4985 /*-----------------------------------------------------------------*/
4986 static void genCmpEq (iCode *ic, iCode *ifx)
4988 operand *left, *right, *result;
4989 unsigned long lit = 0L;
4991 symbol *falselbl = newiTempLabel(NULL);
4994 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4997 DEBUGpic16_emitcode ("; ifx is non-null","");
4999 DEBUGpic16_emitcode ("; ifx is null","");
5001 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5002 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5003 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5005 size = max(AOP_SIZE(left),AOP_SIZE(right));
5007 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5009 /* if literal, literal on the right or
5010 if the right is in a pointer register and left
5012 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5013 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5014 operand *tmp = right ;
5020 if(ifx && !AOP_SIZE(result)){
5022 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5023 /* if they are both bit variables */
5024 if (AOP_TYPE(left) == AOP_CRY &&
5025 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5026 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5027 if(AOP_TYPE(right) == AOP_LIT){
5028 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5030 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5031 pic16_emitcode("cpl","c");
5032 } else if(lit == 1L) {
5033 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5035 pic16_emitcode("clr","c");
5037 /* AOP_TYPE(right) == AOP_CRY */
5039 symbol *lbl = newiTempLabel(NULL);
5040 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5041 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5042 pic16_emitcode("cpl","c");
5043 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5045 /* if true label then we jump if condition
5047 tlbl = newiTempLabel(NULL);
5048 if ( IC_TRUE(ifx) ) {
5049 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5050 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5052 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5053 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5055 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5058 /* left and right are both bit variables, result is carry */
5061 resolveIfx(&rIfx,ifx);
5063 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5064 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5065 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5066 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5071 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5073 /* They're not both bit variables. Is the right a literal? */
5074 if(AOP_TYPE(right) == AOP_LIT) {
5075 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5080 switch(lit & 0xff) {
5082 if ( IC_TRUE(ifx) ) {
5083 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5085 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5087 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5088 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5092 if ( IC_TRUE(ifx) ) {
5093 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5095 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5097 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5098 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5102 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5104 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5109 /* end of size == 1 */
5113 genc16bit2lit(left,lit,offset);
5116 /* end of size == 2 */
5121 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5122 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5123 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5124 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5127 /* search for patterns that can be optimized */
5129 genc16bit2lit(left,lit,0);
5133 emitSKPZ; // if hi word unequal
5135 emitSKPNZ; // if hi word equal
5137 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5138 genc16bit2lit(left,lit,2);
5141 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5142 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5146 pic16_emitpLabel(falselbl->key);
5155 } else if(AOP_TYPE(right) == AOP_CRY ) {
5156 /* we know the left is not a bit, but that the right is */
5157 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5158 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5159 pic16_popGet(AOP(right),offset));
5160 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5162 /* if the two are equal, then W will be 0 and the Z bit is set
5163 * we could test Z now, or go ahead and check the high order bytes if
5164 * the variable we're comparing is larger than a byte. */
5167 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5169 if ( IC_TRUE(ifx) ) {
5171 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5172 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5175 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5176 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5180 /* They're both variables that are larger than bits */
5183 tlbl = newiTempLabel(NULL);
5186 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5187 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5189 if ( IC_TRUE(ifx) ) {
5193 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5195 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5196 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5200 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5203 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5204 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5209 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5211 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5212 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5216 if(s>1 && IC_TRUE(ifx)) {
5217 pic16_emitpLabel(tlbl->key);
5218 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5222 /* mark the icode as generated */
5227 /* if they are both bit variables */
5228 if (AOP_TYPE(left) == AOP_CRY &&
5229 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5230 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5231 if(AOP_TYPE(right) == AOP_LIT){
5232 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5234 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5235 pic16_emitcode("cpl","c");
5236 } else if(lit == 1L) {
5237 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5239 pic16_emitcode("clr","c");
5241 /* AOP_TYPE(right) == AOP_CRY */
5243 symbol *lbl = newiTempLabel(NULL);
5244 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5245 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5246 pic16_emitcode("cpl","c");
5247 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5250 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5251 pic16_outBitC(result);
5255 genIfxJump (ifx,"c");
5258 /* if the result is used in an arithmetic operation
5259 then put the result in place */
5260 pic16_outBitC(result);
5263 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5264 gencjne(left,right,result,ifx);
5267 gencjne(left,right,newiTempLabel(NULL));
5269 if(IC_TRUE(ifx)->key)
5270 gencjne(left,right,IC_TRUE(ifx)->key);
5272 gencjne(left,right,IC_FALSE(ifx)->key);
5276 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5277 pic16_aopPut(AOP(result),"a",0);
5282 genIfxJump (ifx,"a");
5286 /* if the result is used in an arithmetic operation
5287 then put the result in place */
5289 if (AOP_TYPE(result) != AOP_CRY)
5290 pic16_outAcc(result);
5292 /* leave the result in acc */
5296 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5297 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5298 pic16_freeAsmop(result,NULL,ic,TRUE);
5301 /*-----------------------------------------------------------------*/
5302 /* ifxForOp - returns the icode containing the ifx for operand */
5303 /*-----------------------------------------------------------------*/
5304 static iCode *ifxForOp ( operand *op, iCode *ic )
5306 /* if true symbol then needs to be assigned */
5307 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5308 if (IS_TRUE_SYMOP(op))
5311 /* if this has register type condition and
5312 the next instruction is ifx with the same operand
5313 and live to of the operand is upto the ifx only then */
5315 ic->next->op == IFX &&
5316 IC_COND(ic->next)->key == op->key &&
5317 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5321 ic->next->op == IFX &&
5322 IC_COND(ic->next)->key == op->key) {
5323 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5327 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5329 ic->next->op == IFX)
5330 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5333 ic->next->op == IFX &&
5334 IC_COND(ic->next)->key == op->key) {
5335 DEBUGpic16_emitcode ("; "," key is okay");
5336 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5337 OP_SYMBOL(op)->liveTo,
5344 /*-----------------------------------------------------------------*/
5345 /* genAndOp - for && operation */
5346 /*-----------------------------------------------------------------*/
5347 static void genAndOp (iCode *ic)
5349 operand *left,*right, *result;
5352 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5353 /* note here that && operations that are in an
5354 if statement are taken away by backPatchLabels
5355 only those used in arthmetic operations remain */
5356 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5357 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5358 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5360 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5362 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5363 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5364 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5366 /* if both are bit variables */
5367 /* if (AOP_TYPE(left) == AOP_CRY && */
5368 /* AOP_TYPE(right) == AOP_CRY ) { */
5369 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5370 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5371 /* pic16_outBitC(result); */
5373 /* tlbl = newiTempLabel(NULL); */
5374 /* pic16_toBoolean(left); */
5375 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5376 /* pic16_toBoolean(right); */
5377 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5378 /* pic16_outBitAcc(result); */
5381 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5382 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5383 pic16_freeAsmop(result,NULL,ic,TRUE);
5387 /*-----------------------------------------------------------------*/
5388 /* genOrOp - for || operation */
5389 /*-----------------------------------------------------------------*/
5392 modified this code, but it doesn't appear to ever get called
5395 static void genOrOp (iCode *ic)
5397 operand *left,*right, *result;
5400 /* note here that || operations that are in an
5401 if statement are taken away by backPatchLabels
5402 only those used in arthmetic operations remain */
5403 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5404 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5405 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5406 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5408 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5410 /* if both are bit variables */
5411 if (AOP_TYPE(left) == AOP_CRY &&
5412 AOP_TYPE(right) == AOP_CRY ) {
5413 pic16_emitcode("clrc","");
5414 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5415 AOP(left)->aopu.aop_dir,
5416 AOP(left)->aopu.aop_dir);
5417 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5418 AOP(right)->aopu.aop_dir,
5419 AOP(right)->aopu.aop_dir);
5420 pic16_emitcode("setc","");
5423 tlbl = newiTempLabel(NULL);
5424 pic16_toBoolean(left);
5426 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5427 pic16_toBoolean(right);
5428 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5430 pic16_outBitAcc(result);
5433 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5434 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5435 pic16_freeAsmop(result,NULL,ic,TRUE);
5438 /*-----------------------------------------------------------------*/
5439 /* isLiteralBit - test if lit == 2^n */
5440 /*-----------------------------------------------------------------*/
5441 static int isLiteralBit(unsigned long lit)
5443 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5444 0x100L,0x200L,0x400L,0x800L,
5445 0x1000L,0x2000L,0x4000L,0x8000L,
5446 0x10000L,0x20000L,0x40000L,0x80000L,
5447 0x100000L,0x200000L,0x400000L,0x800000L,
5448 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5449 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5452 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5453 for(idx = 0; idx < 32; idx++)
5459 /*-----------------------------------------------------------------*/
5460 /* continueIfTrue - */
5461 /*-----------------------------------------------------------------*/
5462 static void continueIfTrue (iCode *ic)
5464 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5466 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5470 /*-----------------------------------------------------------------*/
5472 /*-----------------------------------------------------------------*/
5473 static void jumpIfTrue (iCode *ic)
5475 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5477 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5481 /*-----------------------------------------------------------------*/
5482 /* jmpTrueOrFalse - */
5483 /*-----------------------------------------------------------------*/
5484 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5486 // ugly but optimized by peephole
5487 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5489 symbol *nlbl = newiTempLabel(NULL);
5490 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5491 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5492 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5493 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5496 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5497 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5502 /*-----------------------------------------------------------------*/
5503 /* genAnd - code for and */
5504 /*-----------------------------------------------------------------*/
5505 static void genAnd (iCode *ic, iCode *ifx)
5507 operand *left, *right, *result;
5509 unsigned long lit = 0L;
5514 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5515 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5516 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5517 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5519 resolveIfx(&rIfx,ifx);
5521 /* if left is a literal & right is not then exchange them */
5522 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5523 AOP_NEEDSACC(left)) {
5524 operand *tmp = right ;
5529 /* if result = right then exchange them */
5530 if(pic16_sameRegs(AOP(result),AOP(right))){
5531 operand *tmp = right ;
5536 /* if right is bit then exchange them */
5537 if (AOP_TYPE(right) == AOP_CRY &&
5538 AOP_TYPE(left) != AOP_CRY){
5539 operand *tmp = right ;
5543 if(AOP_TYPE(right) == AOP_LIT)
5544 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5546 size = AOP_SIZE(result);
5548 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5551 // result = bit & yy;
5552 if (AOP_TYPE(left) == AOP_CRY){
5553 // c = bit & literal;
5554 if(AOP_TYPE(right) == AOP_LIT){
5556 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5559 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5562 if(size && (AOP_TYPE(result) == AOP_CRY)){
5563 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5566 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5570 pic16_emitcode("clr","c");
5573 if (AOP_TYPE(right) == AOP_CRY){
5575 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5576 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5579 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5581 pic16_emitcode("rrc","a");
5582 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5588 pic16_outBitC(result);
5590 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5591 genIfxJump(ifx, "c");
5595 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5596 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5597 if((AOP_TYPE(right) == AOP_LIT) &&
5598 (AOP_TYPE(result) == AOP_CRY) &&
5599 (AOP_TYPE(left) != AOP_CRY)){
5600 int posbit = isLiteralBit(lit);
5604 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5607 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5613 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5614 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5616 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5617 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5620 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5621 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5622 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5629 symbol *tlbl = newiTempLabel(NULL);
5630 int sizel = AOP_SIZE(left);
5632 pic16_emitcode("setb","c");
5634 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5635 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5637 if((posbit = isLiteralBit(bytelit)) != 0)
5638 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5640 if(bytelit != 0x0FFL)
5641 pic16_emitcode("anl","a,%s",
5642 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5643 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5648 // bit = left & literal
5650 pic16_emitcode("clr","c");
5651 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5653 // if(left & literal)
5656 jmpTrueOrFalse(ifx, tlbl);
5660 pic16_outBitC(result);
5664 /* if left is same as result */
5665 if(pic16_sameRegs(AOP(result),AOP(left))){
5667 for(;size--; offset++,lit>>=8) {
5668 if(AOP_TYPE(right) == AOP_LIT){
5669 switch(lit & 0xff) {
5671 /* and'ing with 0 has clears the result */
5672 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5673 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5676 /* and'ing with 0xff is a nop when the result and left are the same */
5681 int p = my_powof2( (~lit) & 0xff );
5683 /* only one bit is set in the literal, so use a bcf instruction */
5684 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5685 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5688 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5689 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5690 if(know_W != (lit&0xff))
5691 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5693 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5698 if (AOP_TYPE(left) == AOP_ACC) {
5699 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5701 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5702 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5709 // left & result in different registers
5710 if(AOP_TYPE(result) == AOP_CRY){
5712 // if(size), result in bit
5713 // if(!size && ifx), conditional oper: if(left & right)
5714 symbol *tlbl = newiTempLabel(NULL);
5715 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5717 pic16_emitcode("setb","c");
5719 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5720 pic16_emitcode("anl","a,%s",
5721 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5722 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5727 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5728 pic16_outBitC(result);
5730 jmpTrueOrFalse(ifx, tlbl);
5732 for(;(size--);offset++) {
5734 // result = left & right
5735 if(AOP_TYPE(right) == AOP_LIT){
5736 int t = (lit >> (offset*8)) & 0x0FFL;
5739 pic16_emitcode("clrf","%s",
5740 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5741 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5744 pic16_emitcode("movf","%s,w",
5745 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5746 pic16_emitcode("movwf","%s",
5747 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5748 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5749 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5752 pic16_emitcode("movlw","0x%x",t);
5753 pic16_emitcode("andwf","%s,w",
5754 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5755 pic16_emitcode("movwf","%s",
5756 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5758 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5759 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5760 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5765 if (AOP_TYPE(left) == AOP_ACC) {
5766 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5767 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5769 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5770 pic16_emitcode("andwf","%s,w",
5771 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5772 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5773 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5775 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5776 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5782 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5783 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5784 pic16_freeAsmop(result,NULL,ic,TRUE);
5787 /*-----------------------------------------------------------------*/
5788 /* genOr - code for or */
5789 /*-----------------------------------------------------------------*/
5790 static void genOr (iCode *ic, iCode *ifx)
5792 operand *left, *right, *result;
5794 unsigned long lit = 0L;
5796 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5798 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5799 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5800 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5802 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5804 /* if left is a literal & right is not then exchange them */
5805 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5806 AOP_NEEDSACC(left)) {
5807 operand *tmp = right ;
5812 /* if result = right then exchange them */
5813 if(pic16_sameRegs(AOP(result),AOP(right))){
5814 operand *tmp = right ;
5819 /* if right is bit then exchange them */
5820 if (AOP_TYPE(right) == AOP_CRY &&
5821 AOP_TYPE(left) != AOP_CRY){
5822 operand *tmp = right ;
5827 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5829 if(AOP_TYPE(right) == AOP_LIT)
5830 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5832 size = AOP_SIZE(result);
5836 if (AOP_TYPE(left) == AOP_CRY){
5837 if(AOP_TYPE(right) == AOP_LIT){
5838 // c = bit & literal;
5840 // lit != 0 => result = 1
5841 if(AOP_TYPE(result) == AOP_CRY){
5843 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5844 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5845 // AOP(result)->aopu.aop_dir,
5846 // AOP(result)->aopu.aop_dir);
5848 continueIfTrue(ifx);
5852 // lit == 0 => result = left
5853 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5855 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5858 if (AOP_TYPE(right) == AOP_CRY){
5859 if(pic16_sameRegs(AOP(result),AOP(left))){
5861 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5862 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5863 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5865 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5866 AOP(result)->aopu.aop_dir,
5867 AOP(result)->aopu.aop_dir);
5868 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5869 AOP(right)->aopu.aop_dir,
5870 AOP(right)->aopu.aop_dir);
5871 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5872 AOP(result)->aopu.aop_dir,
5873 AOP(result)->aopu.aop_dir);
5875 if( AOP_TYPE(result) == AOP_ACC) {
5876 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5877 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5878 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5879 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5883 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5884 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5885 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5886 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5888 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5889 AOP(result)->aopu.aop_dir,
5890 AOP(result)->aopu.aop_dir);
5891 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5892 AOP(right)->aopu.aop_dir,
5893 AOP(right)->aopu.aop_dir);
5894 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5895 AOP(left)->aopu.aop_dir,
5896 AOP(left)->aopu.aop_dir);
5897 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5898 AOP(result)->aopu.aop_dir,
5899 AOP(result)->aopu.aop_dir);
5904 symbol *tlbl = newiTempLabel(NULL);
5905 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5908 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5909 if( AOP_TYPE(right) == AOP_ACC) {
5910 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5912 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5913 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5918 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5919 pic16_emitcode(";XXX setb","c");
5920 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5921 AOP(left)->aopu.aop_dir,tlbl->key+100);
5922 pic16_toBoolean(right);
5923 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5924 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5925 jmpTrueOrFalse(ifx, tlbl);
5929 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5936 pic16_outBitC(result);
5938 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5939 genIfxJump(ifx, "c");
5943 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5944 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5945 if((AOP_TYPE(right) == AOP_LIT) &&
5946 (AOP_TYPE(result) == AOP_CRY) &&
5947 (AOP_TYPE(left) != AOP_CRY)){
5949 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5952 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5954 continueIfTrue(ifx);
5957 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5958 // lit = 0, result = boolean(left)
5960 pic16_emitcode(";XXX setb","c");
5961 pic16_toBoolean(right);
5963 symbol *tlbl = newiTempLabel(NULL);
5964 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5966 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5968 genIfxJump (ifx,"a");
5972 pic16_outBitC(result);
5976 /* if left is same as result */
5977 if(pic16_sameRegs(AOP(result),AOP(left))){
5979 for(;size--; offset++,lit>>=8) {
5980 if(AOP_TYPE(right) == AOP_LIT){
5981 if((lit & 0xff) == 0)
5982 /* or'ing with 0 has no effect */
5985 int p = my_powof2(lit & 0xff);
5987 /* only one bit is set in the literal, so use a bsf instruction */
5988 pic16_emitpcode(POC_BSF,
5989 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5991 if(know_W != (lit & 0xff))
5992 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5993 know_W = lit & 0xff;
5994 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5999 if (AOP_TYPE(left) == AOP_ACC) {
6000 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
6001 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6003 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6004 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6006 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6007 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6013 // left & result in different registers
6014 if(AOP_TYPE(result) == AOP_CRY){
6016 // if(size), result in bit
6017 // if(!size && ifx), conditional oper: if(left | right)
6018 symbol *tlbl = newiTempLabel(NULL);
6019 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6020 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6024 pic16_emitcode(";XXX setb","c");
6026 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6027 pic16_emitcode(";XXX orl","a,%s",
6028 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6029 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6034 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6035 pic16_outBitC(result);
6037 jmpTrueOrFalse(ifx, tlbl);
6038 } else for(;(size--);offset++){
6040 // result = left & right
6041 if(AOP_TYPE(right) == AOP_LIT){
6042 int t = (lit >> (offset*8)) & 0x0FFL;
6045 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6046 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6048 pic16_emitcode("movf","%s,w",
6049 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6050 pic16_emitcode("movwf","%s",
6051 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6054 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6055 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6056 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6058 pic16_emitcode("movlw","0x%x",t);
6059 pic16_emitcode("iorwf","%s,w",
6060 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6061 pic16_emitcode("movwf","%s",
6062 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6068 // faster than result <- left, anl result,right
6069 // and better if result is SFR
6070 if (AOP_TYPE(left) == AOP_ACC) {
6071 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6072 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6074 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6075 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6077 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6078 pic16_emitcode("iorwf","%s,w",
6079 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6081 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6082 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6087 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6088 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6089 pic16_freeAsmop(result,NULL,ic,TRUE);
6092 /*-----------------------------------------------------------------*/
6093 /* genXor - code for xclusive or */
6094 /*-----------------------------------------------------------------*/
6095 static void genXor (iCode *ic, iCode *ifx)
6097 operand *left, *right, *result;
6099 unsigned long lit = 0L;
6101 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6103 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6104 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6105 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6107 /* if left is a literal & right is not ||
6108 if left needs acc & right does not */
6109 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6110 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6111 operand *tmp = right ;
6116 /* if result = right then exchange them */
6117 if(pic16_sameRegs(AOP(result),AOP(right))){
6118 operand *tmp = right ;
6123 /* if right is bit then exchange them */
6124 if (AOP_TYPE(right) == AOP_CRY &&
6125 AOP_TYPE(left) != AOP_CRY){
6126 operand *tmp = right ;
6130 if(AOP_TYPE(right) == AOP_LIT)
6131 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6133 size = AOP_SIZE(result);
6137 if (AOP_TYPE(left) == AOP_CRY){
6138 if(AOP_TYPE(right) == AOP_LIT){
6139 // c = bit & literal;
6141 // lit>>1 != 0 => result = 1
6142 if(AOP_TYPE(result) == AOP_CRY){
6144 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6145 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6147 continueIfTrue(ifx);
6150 pic16_emitcode("setb","c");
6154 // lit == 0, result = left
6155 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6157 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6159 // lit == 1, result = not(left)
6160 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6161 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6162 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6163 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6166 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6167 pic16_emitcode("cpl","c");
6174 symbol *tlbl = newiTempLabel(NULL);
6175 if (AOP_TYPE(right) == AOP_CRY){
6177 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6180 int sizer = AOP_SIZE(right);
6182 // if val>>1 != 0, result = 1
6183 pic16_emitcode("setb","c");
6185 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6187 // test the msb of the lsb
6188 pic16_emitcode("anl","a,#0xfe");
6189 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6193 pic16_emitcode("rrc","a");
6195 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6196 pic16_emitcode("cpl","c");
6197 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6202 pic16_outBitC(result);
6204 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6205 genIfxJump(ifx, "c");
6209 if(pic16_sameRegs(AOP(result),AOP(left))){
6210 /* if left is same as result */
6211 for(;size--; offset++) {
6212 if(AOP_TYPE(right) == AOP_LIT){
6213 int t = (lit >> (offset*8)) & 0x0FFL;
6217 if (IS_AOP_PREG(left)) {
6218 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6219 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6220 pic16_aopPut(AOP(result),"a",offset);
6222 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6223 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6224 pic16_emitcode("xrl","%s,%s",
6225 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6226 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6229 if (AOP_TYPE(left) == AOP_ACC)
6230 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6232 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6233 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6235 if (IS_AOP_PREG(left)) {
6236 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6237 pic16_aopPut(AOP(result),"a",offset);
6239 pic16_emitcode("xrl","%s,a",
6240 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6246 // left & result in different registers
6247 if(AOP_TYPE(result) == AOP_CRY){
6249 // if(size), result in bit
6250 // if(!size && ifx), conditional oper: if(left ^ right)
6251 symbol *tlbl = newiTempLabel(NULL);
6252 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6254 pic16_emitcode("setb","c");
6256 if((AOP_TYPE(right) == AOP_LIT) &&
6257 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6258 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6260 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6261 pic16_emitcode("xrl","a,%s",
6262 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6264 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6269 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6270 pic16_outBitC(result);
6272 jmpTrueOrFalse(ifx, tlbl);
6273 } else for(;(size--);offset++){
6275 // result = left & right
6276 if(AOP_TYPE(right) == AOP_LIT){
6277 int t = (lit >> (offset*8)) & 0x0FFL;
6280 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6281 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6282 pic16_emitcode("movf","%s,w",
6283 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6284 pic16_emitcode("movwf","%s",
6285 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6288 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6289 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6290 pic16_emitcode("comf","%s,w",
6291 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6292 pic16_emitcode("movwf","%s",
6293 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6296 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6297 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6298 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6299 pic16_emitcode("movlw","0x%x",t);
6300 pic16_emitcode("xorwf","%s,w",
6301 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6302 pic16_emitcode("movwf","%s",
6303 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6309 // faster than result <- left, anl result,right
6310 // and better if result is SFR
6311 if (AOP_TYPE(left) == AOP_ACC) {
6312 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6313 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6315 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6316 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6317 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6318 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6320 if ( AOP_TYPE(result) != AOP_ACC){
6321 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6322 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6328 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6329 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6330 pic16_freeAsmop(result,NULL,ic,TRUE);
6333 /*-----------------------------------------------------------------*/
6334 /* genInline - write the inline code out */
6335 /*-----------------------------------------------------------------*/
6336 static void genInline (iCode *ic)
6338 char *buffer, *bp, *bp1;
6340 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6342 _G.inLine += (!options.asmpeep);
6344 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6345 strcpy(buffer,IC_INLINE(ic));
6347 /* emit each line as a code */
6353 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6354 // inline directly, no process
6361 pic16_emitcode(bp1,"");
6367 if ((bp1 != bp) && *bp1)
6368 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6372 _G.inLine -= (!options.asmpeep);
6375 /*-----------------------------------------------------------------*/
6376 /* genRRC - rotate right with carry */
6377 /*-----------------------------------------------------------------*/
6378 static void genRRC (iCode *ic)
6380 operand *left , *result ;
6381 int size, offset = 0, same;
6383 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6385 /* rotate right with carry */
6387 result=IC_RESULT(ic);
6388 pic16_aopOp (left,ic,FALSE);
6389 pic16_aopOp (result,ic,FALSE);
6391 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6393 same = pic16_sameRegs(AOP(result),AOP(left));
6395 size = AOP_SIZE(result);
6397 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6399 /* get the lsb and put it into the carry */
6400 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6407 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6409 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6410 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6416 pic16_freeAsmop(left,NULL,ic,TRUE);
6417 pic16_freeAsmop(result,NULL,ic,TRUE);
6420 /*-----------------------------------------------------------------*/
6421 /* genRLC - generate code for rotate left with carry */
6422 /*-----------------------------------------------------------------*/
6423 static void genRLC (iCode *ic)
6425 operand *left , *result ;
6426 int size, offset = 0;
6429 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6430 /* rotate right with carry */
6432 result=IC_RESULT(ic);
6433 pic16_aopOp (left,ic,FALSE);
6434 pic16_aopOp (result,ic,FALSE);
6436 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6438 same = pic16_sameRegs(AOP(result),AOP(left));
6440 /* move it to the result */
6441 size = AOP_SIZE(result);
6443 /* get the msb and put it into the carry */
6444 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6451 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6453 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6454 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6461 pic16_freeAsmop(left,NULL,ic,TRUE);
6462 pic16_freeAsmop(result,NULL,ic,TRUE);
6465 /*-----------------------------------------------------------------*/
6466 /* genGetHbit - generates code get highest order bit */
6467 /*-----------------------------------------------------------------*/
6468 static void genGetHbit (iCode *ic)
6470 operand *left, *result;
6472 result=IC_RESULT(ic);
6473 pic16_aopOp (left,ic,FALSE);
6474 pic16_aopOp (result,ic,FALSE);
6476 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6477 /* get the highest order byte into a */
6478 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6479 if(AOP_TYPE(result) == AOP_CRY){
6480 pic16_emitcode("rlc","a");
6481 pic16_outBitC(result);
6484 pic16_emitcode("rl","a");
6485 pic16_emitcode("anl","a,#0x01");
6486 pic16_outAcc(result);
6490 pic16_freeAsmop(left,NULL,ic,TRUE);
6491 pic16_freeAsmop(result,NULL,ic,TRUE);
6495 /*-----------------------------------------------------------------*/
6496 /* AccRol - rotate left accumulator by known count */
6497 /*-----------------------------------------------------------------*/
6498 static void AccRol (int shCount)
6500 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6501 shCount &= 0x0007; // shCount : 0..7
6506 pic16_emitcode("rl","a");
6509 pic16_emitcode("rl","a");
6510 pic16_emitcode("rl","a");
6513 pic16_emitcode("swap","a");
6514 pic16_emitcode("rr","a");
6517 pic16_emitcode("swap","a");
6520 pic16_emitcode("swap","a");
6521 pic16_emitcode("rl","a");
6524 pic16_emitcode("rr","a");
6525 pic16_emitcode("rr","a");
6528 pic16_emitcode("rr","a");
6534 /*-----------------------------------------------------------------*/
6535 /* AccLsh - left shift accumulator by known count */
6536 /*-----------------------------------------------------------------*/
6537 static void AccLsh (int shCount)
6539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6545 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6548 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6549 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6552 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6553 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6556 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6559 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6560 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6563 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6564 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6567 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6570 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
6574 /*-----------------------------------------------------------------*/
6575 /* AccRsh - right shift accumulator by known count */
6576 /*-----------------------------------------------------------------*/
6577 static void AccRsh (int shCount)
6579 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6585 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6588 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6589 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6592 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6593 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6596 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6599 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6600 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6603 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6604 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6607 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6610 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
6614 /*-----------------------------------------------------------------*/
6615 /* AccSRsh - signed right shift accumulator by known count */
6616 /*-----------------------------------------------------------------*/
6617 static void AccSRsh (int shCount)
6620 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6623 pic16_emitcode("mov","c,acc.7");
6624 pic16_emitcode("rrc","a");
6625 } else if(shCount == 2){
6626 pic16_emitcode("mov","c,acc.7");
6627 pic16_emitcode("rrc","a");
6628 pic16_emitcode("mov","c,acc.7");
6629 pic16_emitcode("rrc","a");
6631 tlbl = newiTempLabel(NULL);
6632 /* rotate right accumulator */
6633 AccRol(8 - shCount);
6634 /* and kill the higher order bits */
6635 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6636 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6637 pic16_emitcode("orl","a,#0x%02x",
6638 (unsigned char)~SRMask[shCount]);
6639 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6644 /*-----------------------------------------------------------------*/
6645 /* shiftR1Left2Result - shift right one byte from left to result */
6646 /*-----------------------------------------------------------------*/
6647 static void shiftR1Left2ResultSigned (operand *left, int offl,
6648 operand *result, int offr,
6653 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6655 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6659 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6661 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6663 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6664 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6670 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6672 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6674 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6675 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6677 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6678 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6684 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6686 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6687 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6690 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6691 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6692 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6694 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6695 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6697 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6701 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6702 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6703 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6704 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6705 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6709 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6711 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6712 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6714 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6715 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6716 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6717 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6718 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6723 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6724 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6725 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6726 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6727 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6728 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6730 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6731 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6732 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6733 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6734 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6740 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6741 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6742 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6743 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6745 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6746 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6747 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6755 /*-----------------------------------------------------------------*/
6756 /* shiftR1Left2Result - shift right one byte from left to result */
6757 /*-----------------------------------------------------------------*/
6758 static void shiftR1Left2Result (operand *left, int offl,
6759 operand *result, int offr,
6760 int shCount, int sign)
6764 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6766 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6768 /* Copy the msb into the carry if signed. */
6770 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6780 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6782 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6783 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6789 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6791 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6792 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6795 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6800 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6802 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6803 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6806 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6807 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6808 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6809 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6813 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6814 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6815 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6819 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6820 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6821 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6823 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6828 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6829 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6830 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6831 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6832 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6837 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6838 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6839 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6848 /*-----------------------------------------------------------------*/
6849 /* shiftL1Left2Result - shift left one byte from left to result */
6850 /*-----------------------------------------------------------------*/
6851 static void shiftL1Left2Result (operand *left, int offl,
6852 operand *result, int offr, int shCount)
6857 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6859 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6860 DEBUGpic16_emitcode ("; ***","same = %d",same);
6861 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6863 /* shift left accumulator */
6864 //AccLsh(shCount); // don't comment out just yet...
6865 // pic16_aopPut(AOP(result),"a",offr);
6869 /* Shift left 1 bit position */
6870 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6872 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6874 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6875 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6879 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6880 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6881 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6882 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6885 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6886 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6887 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6888 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6889 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6892 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6893 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6894 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6897 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6898 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6899 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6900 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6903 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6904 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6905 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6906 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6907 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6910 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6911 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6912 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6916 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6921 /*-----------------------------------------------------------------*/
6922 /* movLeft2Result - move byte from left to result */
6923 /*-----------------------------------------------------------------*/
6924 static void movLeft2Result (operand *left, int offl,
6925 operand *result, int offr)
6928 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6929 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6930 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6932 if (*l == '@' && (IS_AOP_PREG(result))) {
6933 pic16_emitcode("mov","a,%s",l);
6934 pic16_aopPut(AOP(result),"a",offr);
6936 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6937 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6942 /*-----------------------------------------------------------------*/
6943 /* shiftL2Left2Result - shift left two bytes from left to result */
6944 /*-----------------------------------------------------------------*/
6945 static void shiftL2Left2Result (operand *left, int offl,
6946 operand *result, int offr, int shCount)
6948 int same = pic16_sameRegs(AOP(result), AOP(left));
6951 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
6953 if (same && (offl != offr)) { // shift bytes
6956 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
6957 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
6959 } else { // just treat as different later on
6972 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6973 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6974 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6978 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6979 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6985 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6986 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6987 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6988 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6989 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6990 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6991 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6993 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6994 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6998 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6999 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7000 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7001 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7002 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7003 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7004 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7005 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7006 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7007 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7010 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7011 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7012 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7013 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7014 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7024 /* note, use a mov/add for the shift since the mov has a
7025 chance of getting optimized out */
7026 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7027 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7028 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7029 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7030 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7034 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7035 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7041 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7042 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7043 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7044 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7045 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7046 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7047 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7048 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7052 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7053 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7057 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7058 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7059 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7060 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7062 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7063 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7064 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7065 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7066 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7067 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7068 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7069 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7072 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7073 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7074 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7075 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7076 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7081 /*-----------------------------------------------------------------*/
7082 /* shiftR2Left2Result - shift right two bytes from left to result */
7083 /*-----------------------------------------------------------------*/
7084 static void shiftR2Left2Result (operand *left, int offl,
7085 operand *result, int offr,
7086 int shCount, int sign)
7088 int same = pic16_sameRegs(AOP(result), AOP(left));
7090 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7092 if (same && (offl != offr)) { // shift right bytes
7095 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7096 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7098 } else { // just treat as different later on
7110 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7115 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7116 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7118 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7119 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7120 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7121 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7126 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7129 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7130 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7137 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7138 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7139 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7141 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7142 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7143 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7144 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7146 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7147 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7148 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7150 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7151 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7152 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7153 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7154 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7158 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7159 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7163 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7164 pic16_emitpcode(POC_BTFSC,
7165 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7166 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7174 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7175 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7177 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7178 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7179 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7180 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7182 pic16_emitpcode(POC_BTFSC,
7183 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7184 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7186 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7187 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7188 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7189 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7191 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7192 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7193 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7194 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7195 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7196 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7197 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7198 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7200 pic16_emitpcode(POC_BTFSC,
7201 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7202 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7204 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7205 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7212 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7213 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7214 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7215 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7218 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7220 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7225 /*-----------------------------------------------------------------*/
7226 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7227 /*-----------------------------------------------------------------*/
7228 static void shiftLLeftOrResult (operand *left, int offl,
7229 operand *result, int offr, int shCount)
7231 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7233 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7234 /* shift left accumulator */
7236 /* or with result */
7237 /* back to result */
7238 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7241 /*-----------------------------------------------------------------*/
7242 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7243 /*-----------------------------------------------------------------*/
7244 static void shiftRLeftOrResult (operand *left, int offl,
7245 operand *result, int offr, int shCount)
7247 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7249 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7250 /* shift right accumulator */
7252 /* or with result */
7253 /* back to result */
7254 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7257 /*-----------------------------------------------------------------*/
7258 /* genlshOne - left shift a one byte quantity by known count */
7259 /*-----------------------------------------------------------------*/
7260 static void genlshOne (operand *result, operand *left, int shCount)
7262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7263 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7266 /*-----------------------------------------------------------------*/
7267 /* genlshTwo - left shift two bytes by known amount != 0 */
7268 /*-----------------------------------------------------------------*/
7269 static void genlshTwo (operand *result,operand *left, int shCount)
7273 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7274 size = pic16_getDataSize(result);
7276 /* if shCount >= 8 */
7282 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7284 movLeft2Result(left, LSB, result, MSB16);
7286 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7289 /* 1 <= shCount <= 7 */
7292 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7294 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7298 /*-----------------------------------------------------------------*/
7299 /* shiftLLong - shift left one long from left to result */
7300 /* offr = LSB or MSB16 */
7301 /*-----------------------------------------------------------------*/
7302 static void shiftLLong (operand *left, operand *result, int offr )
7304 int size = AOP_SIZE(result);
7305 int same = pic16_sameRegs(AOP(left),AOP(result));
7308 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7310 if (same && (offr == MSB16)) { //shift one byte
7311 for(i=size-1;i>=MSB16;i--) {
7312 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7313 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7316 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7319 if (size >= LSB+offr ){
7321 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7323 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7324 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7328 if(size >= MSB16+offr){
7330 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7332 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7333 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7337 if(size >= MSB24+offr){
7339 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7341 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7342 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7346 if(size > MSB32+offr){
7348 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7350 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7351 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7355 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7359 /*-----------------------------------------------------------------*/
7360 /* genlshFour - shift four byte by a known amount != 0 */
7361 /*-----------------------------------------------------------------*/
7362 static void genlshFour (operand *result, operand *left, int shCount)
7366 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7367 size = AOP_SIZE(result);
7369 /* if shifting more that 3 bytes */
7370 if (shCount >= 24 ) {
7373 /* lowest order of left goes to the highest
7374 order of the destination */
7375 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7377 movLeft2Result(left, LSB, result, MSB32);
7379 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7380 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7381 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7386 /* more than two bytes */
7387 else if ( shCount >= 16 ) {
7388 /* lower order two bytes goes to higher order two bytes */
7390 /* if some more remaining */
7392 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7394 movLeft2Result(left, MSB16, result, MSB32);
7395 movLeft2Result(left, LSB, result, MSB24);
7397 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7398 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7402 /* if more than 1 byte */
7403 else if ( shCount >= 8 ) {
7404 /* lower order three bytes goes to higher order three bytes */
7408 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7410 movLeft2Result(left, LSB, result, MSB16);
7412 else{ /* size = 4 */
7414 movLeft2Result(left, MSB24, result, MSB32);
7415 movLeft2Result(left, MSB16, result, MSB24);
7416 movLeft2Result(left, LSB, result, MSB16);
7417 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7419 else if(shCount == 1)
7420 shiftLLong(left, result, MSB16);
7422 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7423 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7424 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7425 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7430 /* 1 <= shCount <= 7 */
7431 else if(shCount <= 3)
7433 shiftLLong(left, result, LSB);
7434 while(--shCount >= 1)
7435 shiftLLong(result, result, LSB);
7437 /* 3 <= shCount <= 7, optimize */
7439 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7440 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7441 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7445 /*-----------------------------------------------------------------*/
7446 /* genLeftShiftLiteral - left shifting by known count */
7447 /*-----------------------------------------------------------------*/
7448 static void genLeftShiftLiteral (operand *left,
7453 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7456 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7457 pic16_freeAsmop(right,NULL,ic,TRUE);
7459 pic16_aopOp(left,ic,FALSE);
7460 pic16_aopOp(result,ic,FALSE);
7462 size = getSize(operandType(result));
7465 pic16_emitcode("; shift left ","result %d, left %d",size,
7469 /* I suppose that the left size >= result size */
7472 movLeft2Result(left, size, result, size);
7476 else if(shCount >= (size * 8))
7478 pic16_aopPut(AOP(result),zero,size);
7482 genlshOne (result,left,shCount);
7487 genlshTwo (result,left,shCount);
7491 genlshFour (result,left,shCount);
7495 pic16_freeAsmop(left,NULL,ic,TRUE);
7496 pic16_freeAsmop(result,NULL,ic,TRUE);
7499 /*-----------------------------------------------------------------*
7500 * genMultiAsm - repeat assembly instruction for size of register.
7501 * if endian == 1, then the high byte (i.e base address + size of
7502 * register) is used first else the low byte is used first;
7503 *-----------------------------------------------------------------*/
7504 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7509 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7522 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7527 /*-----------------------------------------------------------------*/
7528 /* genLeftShift - generates code for left shifting */
7529 /*-----------------------------------------------------------------*/
7530 static void genLeftShift (iCode *ic)
7532 operand *left,*right, *result;
7535 symbol *tlbl , *tlbl1;
7538 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7540 right = IC_RIGHT(ic);
7542 result = IC_RESULT(ic);
7544 pic16_aopOp(right,ic,FALSE);
7546 /* if the shift count is known then do it
7547 as efficiently as possible */
7548 if (AOP_TYPE(right) == AOP_LIT) {
7549 genLeftShiftLiteral (left,right,result,ic);
7553 /* shift count is unknown then we have to form
7554 a loop get the loop count in B : Note: we take
7555 only the lower order byte since shifting
7556 more that 32 bits make no sense anyway, ( the
7557 largest size of an object can be only 32 bits ) */
7560 pic16_aopOp(left,ic,FALSE);
7561 pic16_aopOp(result,ic,FALSE);
7563 /* now move the left to the result if they are not the
7565 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7566 AOP_SIZE(result) > 1) {
7568 size = AOP_SIZE(result);
7571 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7572 if (*l == '@' && (IS_AOP_PREG(result))) {
7574 pic16_emitcode("mov","a,%s",l);
7575 pic16_aopPut(AOP(result),"a",offset);
7577 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7578 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7579 //pic16_aopPut(AOP(result),l,offset);
7585 size = AOP_SIZE(result);
7587 /* if it is only one byte then */
7589 if(optimized_for_speed) {
7590 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7591 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7592 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7593 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7594 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7595 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7596 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7597 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7598 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7599 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7600 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7601 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7604 tlbl = newiTempLabel(NULL);
7605 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7606 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7607 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7610 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7611 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7612 pic16_emitpLabel(tlbl->key);
7613 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7614 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7616 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7621 if (pic16_sameRegs(AOP(left),AOP(result))) {
7623 tlbl = newiTempLabel(NULL);
7624 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7625 genMultiAsm(POC_RRCF, result, size,1);
7626 pic16_emitpLabel(tlbl->key);
7627 genMultiAsm(POC_RLCF, result, size,0);
7628 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7630 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7634 //tlbl = newiTempLabel(NULL);
7636 //tlbl1 = newiTempLabel(NULL);
7638 //reAdjustPreg(AOP(result));
7640 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7641 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7642 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7644 //pic16_emitcode("add","a,acc");
7645 //pic16_aopPut(AOP(result),"a",offset++);
7647 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7649 // pic16_emitcode("rlc","a");
7650 // pic16_aopPut(AOP(result),"a",offset++);
7652 //reAdjustPreg(AOP(result));
7654 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7655 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7658 tlbl = newiTempLabel(NULL);
7659 tlbl1= newiTempLabel(NULL);
7661 size = AOP_SIZE(result);
7664 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7666 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7668 /* offset should be 0, 1 or 3 */
7670 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
7672 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7674 pic16_emitpcode(POC_MOVWF, pctemp);
7677 pic16_emitpLabel(tlbl->key);
7680 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7682 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7684 pic16_emitpcode(POC_DECFSZ, pctemp);
7685 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7686 pic16_emitpLabel(tlbl1->key);
7688 pic16_popReleaseTempReg(pctemp);
7692 pic16_freeAsmop (right,NULL,ic,TRUE);
7693 pic16_freeAsmop(left,NULL,ic,TRUE);
7694 pic16_freeAsmop(result,NULL,ic,TRUE);
7697 /*-----------------------------------------------------------------*/
7698 /* genrshOne - right shift a one byte quantity by known count */
7699 /*-----------------------------------------------------------------*/
7700 static void genrshOne (operand *result, operand *left,
7701 int shCount, int sign)
7703 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7704 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7707 /*-----------------------------------------------------------------*/
7708 /* genrshTwo - right shift two bytes by known amount != 0 */
7709 /*-----------------------------------------------------------------*/
7710 static void genrshTwo (operand *result,operand *left,
7711 int shCount, int sign)
7713 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7714 /* if shCount >= 8 */
7718 shiftR1Left2Result(left, MSB16, result, LSB,
7721 movLeft2Result(left, MSB16, result, LSB);
7723 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7726 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7727 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7731 /* 1 <= shCount <= 7 */
7733 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7736 /*-----------------------------------------------------------------*/
7737 /* shiftRLong - shift right one long from left to result */
7738 /* offl = LSB or MSB16 */
7739 /*-----------------------------------------------------------------*/
7740 static void shiftRLong (operand *left, int offl,
7741 operand *result, int sign)
7743 int size = AOP_SIZE(result);
7744 int same = pic16_sameRegs(AOP(left),AOP(result));
7746 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
7748 if (same && (offl == MSB16)) { //shift one byte right
7749 for(i=MSB16;i<size;i++) {
7750 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
7751 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
7756 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
7762 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
7764 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
7765 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
7769 /* add sign of "a" */
7770 pic16_addSign(result, MSB32, sign);
7774 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
7776 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
7777 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
7781 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
7783 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
7784 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
7788 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
7791 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
7792 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
7797 /*-----------------------------------------------------------------*/
7798 /* genrshFour - shift four byte by a known amount != 0 */
7799 /*-----------------------------------------------------------------*/
7800 static void genrshFour (operand *result, operand *left,
7801 int shCount, int sign)
7803 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7804 /* if shifting more that 3 bytes */
7805 if(shCount >= 24 ) {
7808 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7810 movLeft2Result(left, MSB32, result, LSB);
7812 pic16_addSign(result, MSB16, sign);
7814 else if(shCount >= 16){
7817 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7819 movLeft2Result(left, MSB24, result, LSB);
7820 movLeft2Result(left, MSB32, result, MSB16);
7822 pic16_addSign(result, MSB24, sign);
7824 else if(shCount >= 8){
7827 shiftRLong(left, MSB16, result, sign);
7828 else if(shCount == 0){
7829 movLeft2Result(left, MSB16, result, LSB);
7830 movLeft2Result(left, MSB24, result, MSB16);
7831 movLeft2Result(left, MSB32, result, MSB24);
7832 pic16_addSign(result, MSB32, sign);
7834 else{ //shcount >= 2
7835 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7836 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7837 /* the last shift is signed */
7838 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7839 pic16_addSign(result, MSB32, sign);
7842 else{ /* 1 <= shCount <= 7 */
7844 shiftRLong(left, LSB, result, sign);
7846 shiftRLong(result, LSB, result, sign);
7849 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7850 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7851 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7856 /*-----------------------------------------------------------------*/
7857 /* genRightShiftLiteral - right shifting by known count */
7858 /*-----------------------------------------------------------------*/
7859 static void genRightShiftLiteral (operand *left,
7865 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7868 pic16_freeAsmop(right,NULL,ic,TRUE);
7870 pic16_aopOp(left,ic,FALSE);
7871 pic16_aopOp(result,ic,FALSE);
7873 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
7876 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7880 lsize = pic16_getDataSize(left);
7881 res_size = pic16_getDataSize(result);
7882 /* test the LEFT size !!! */
7884 /* I suppose that the left size >= result size */
7887 movLeft2Result(left, lsize, result, res_size);
7890 else if(shCount >= (lsize * 8)){
7893 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7895 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7896 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7901 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7902 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7903 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7905 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7910 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7917 genrshOne (result,left,shCount,sign);
7921 genrshTwo (result,left,shCount,sign);
7925 genrshFour (result,left,shCount,sign);
7933 pic16_freeAsmop(left,NULL,ic,TRUE);
7934 pic16_freeAsmop(result,NULL,ic,TRUE);
7937 /*-----------------------------------------------------------------*/
7938 /* genSignedRightShift - right shift of signed number */
7939 /*-----------------------------------------------------------------*/
7940 static void genSignedRightShift (iCode *ic)
7942 operand *right, *left, *result;
7945 symbol *tlbl, *tlbl1 ;
7948 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7950 /* we do it the hard way put the shift count in b
7951 and loop thru preserving the sign */
7952 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7954 right = IC_RIGHT(ic);
7956 result = IC_RESULT(ic);
7958 pic16_aopOp(right,ic,FALSE);
7959 pic16_aopOp(left,ic,FALSE);
7960 pic16_aopOp(result,ic,FALSE);
7963 if ( AOP_TYPE(right) == AOP_LIT) {
7964 genRightShiftLiteral (left,right,result,ic,1);
7967 /* shift count is unknown then we have to form
7968 a loop get the loop count in B : Note: we take
7969 only the lower order byte since shifting
7970 more that 32 bits make no sense anyway, ( the
7971 largest size of an object can be only 32 bits ) */
7973 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7974 //pic16_emitcode("inc","b");
7975 //pic16_freeAsmop (right,NULL,ic,TRUE);
7976 //pic16_aopOp(left,ic,FALSE);
7977 //pic16_aopOp(result,ic,FALSE);
7979 /* now move the left to the result if they are not the
7981 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7982 AOP_SIZE(result) > 1) {
7984 size = AOP_SIZE(result);
7988 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7989 if (*l == '@' && IS_AOP_PREG(result)) {
7991 pic16_emitcode("mov","a,%s",l);
7992 pic16_aopPut(AOP(result),"a",offset);
7994 pic16_aopPut(AOP(result),l,offset);
7996 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7997 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8003 /* mov the highest order bit to OVR */
8004 tlbl = newiTempLabel(NULL);
8005 tlbl1= newiTempLabel(NULL);
8007 size = AOP_SIZE(result);
8010 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8012 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8014 /* offset should be 0, 1 or 3 */
8015 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8017 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8019 pic16_emitpcode(POC_MOVWF, pctemp);
8022 pic16_emitpLabel(tlbl->key);
8024 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8025 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8028 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8031 pic16_emitpcode(POC_DECFSZ, pctemp);
8032 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8033 pic16_emitpLabel(tlbl1->key);
8035 pic16_popReleaseTempReg(pctemp);
8037 size = AOP_SIZE(result);
8039 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8040 pic16_emitcode("rlc","a");
8041 pic16_emitcode("mov","ov,c");
8042 /* if it is only one byte then */
8044 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8046 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8047 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8048 pic16_emitcode("mov","c,ov");
8049 pic16_emitcode("rrc","a");
8050 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8051 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8052 pic16_aopPut(AOP(result),"a",0);
8056 reAdjustPreg(AOP(result));
8057 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8058 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8059 pic16_emitcode("mov","c,ov");
8061 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8063 pic16_emitcode("rrc","a");
8064 pic16_aopPut(AOP(result),"a",offset--);
8066 reAdjustPreg(AOP(result));
8067 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8068 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8073 pic16_freeAsmop(left,NULL,ic,TRUE);
8074 pic16_freeAsmop(result,NULL,ic,TRUE);
8075 pic16_freeAsmop(right,NULL,ic,TRUE);
8078 /*-----------------------------------------------------------------*/
8079 /* genRightShift - generate code for right shifting */
8080 /*-----------------------------------------------------------------*/
8081 static void genRightShift (iCode *ic)
8083 operand *right, *left, *result;
8087 symbol *tlbl, *tlbl1 ;
8089 /* if signed then we do it the hard way preserve the
8090 sign bit moving it inwards */
8091 letype = getSpec(operandType(IC_LEFT(ic)));
8092 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8094 if (!SPEC_USIGN(letype)) {
8095 genSignedRightShift (ic);
8099 /* signed & unsigned types are treated the same : i.e. the
8100 signed is NOT propagated inwards : quoting from the
8101 ANSI - standard : "for E1 >> E2, is equivalent to division
8102 by 2**E2 if unsigned or if it has a non-negative value,
8103 otherwise the result is implementation defined ", MY definition
8104 is that the sign does not get propagated */
8106 right = IC_RIGHT(ic);
8108 result = IC_RESULT(ic);
8110 pic16_aopOp(right,ic,FALSE);
8112 /* if the shift count is known then do it
8113 as efficiently as possible */
8114 if (AOP_TYPE(right) == AOP_LIT) {
8115 genRightShiftLiteral (left,right,result,ic, 0);
8119 /* shift count is unknown then we have to form
8120 a loop get the loop count in B : Note: we take
8121 only the lower order byte since shifting
8122 more that 32 bits make no sense anyway, ( the
8123 largest size of an object can be only 32 bits ) */
8125 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8126 pic16_emitcode("inc","b");
8127 pic16_aopOp(left,ic,FALSE);
8128 pic16_aopOp(result,ic,FALSE);
8130 /* now move the left to the result if they are not the
8132 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8133 AOP_SIZE(result) > 1) {
8135 size = AOP_SIZE(result);
8138 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8139 if (*l == '@' && IS_AOP_PREG(result)) {
8141 pic16_emitcode("mov","a,%s",l);
8142 pic16_aopPut(AOP(result),"a",offset);
8144 pic16_aopPut(AOP(result),l,offset);
8149 tlbl = newiTempLabel(NULL);
8150 tlbl1= newiTempLabel(NULL);
8151 size = AOP_SIZE(result);
8154 /* if it is only one byte then */
8157 tlbl = newiTempLabel(NULL);
8158 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8159 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8160 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8163 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8164 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8165 pic16_emitpLabel(tlbl->key);
8166 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8167 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8169 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8174 reAdjustPreg(AOP(result));
8175 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8176 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8179 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8181 pic16_emitcode("rrc","a");
8182 pic16_aopPut(AOP(result),"a",offset--);
8184 reAdjustPreg(AOP(result));
8186 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8187 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8190 pic16_freeAsmop(left,NULL,ic,TRUE);
8191 pic16_freeAsmop (right,NULL,ic,TRUE);
8192 pic16_freeAsmop(result,NULL,ic,TRUE);
8195 /*-----------------------------------------------------------------*/
8196 /* genUnpackBits - generates code for unpacking bits */
8197 /*-----------------------------------------------------------------*/
8198 static void genUnpackBits (operand *result, char *rname, int ptype)
8205 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8206 etype = getSpec(operandType(result));
8208 /* read the first byte */
8213 pic16_emitcode("mov","a,@%s",rname);
8217 pic16_emitcode("movx","a,@%s",rname);
8221 pic16_emitcode("movx","a,@dptr");
8225 pic16_emitcode("clr","a");
8226 pic16_emitcode("movc","a","@a+dptr");
8230 pic16_emitcode("lcall","__gptrget");
8234 /* if we have bitdisplacement then it fits */
8235 /* into this byte completely or if length is */
8236 /* less than a byte */
8237 if ((shCnt = SPEC_BSTR(etype)) ||
8238 (SPEC_BLEN(etype) <= 8)) {
8240 /* shift right acc */
8243 pic16_emitcode("anl","a,#0x%02x",
8244 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8245 pic16_aopPut(AOP(result),"a",offset);
8249 /* bit field did not fit in a byte */
8250 rlen = SPEC_BLEN(etype) - 8;
8251 pic16_aopPut(AOP(result),"a",offset++);
8258 pic16_emitcode("inc","%s",rname);
8259 pic16_emitcode("mov","a,@%s",rname);
8263 pic16_emitcode("inc","%s",rname);
8264 pic16_emitcode("movx","a,@%s",rname);
8268 pic16_emitcode("inc","dptr");
8269 pic16_emitcode("movx","a,@dptr");
8273 pic16_emitcode("clr","a");
8274 pic16_emitcode("inc","dptr");
8275 pic16_emitcode("movc","a","@a+dptr");
8279 pic16_emitcode("inc","dptr");
8280 pic16_emitcode("lcall","__gptrget");
8285 /* if we are done */
8289 pic16_aopPut(AOP(result),"a",offset++);
8294 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8295 pic16_aopPut(AOP(result),"a",offset);
8302 /*-----------------------------------------------------------------*/
8303 /* genDataPointerGet - generates code when ptr offset is known */
8304 /*-----------------------------------------------------------------*/
8305 static void genDataPointerGet (operand *left,
8309 int size , offset = 0;
8312 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8315 /* optimization - most of the time, left and result are the same
8316 * address, but different types. for the pic code, we could omit
8320 pic16_aopOp(result,ic,TRUE);
8322 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8324 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8326 size = AOP_SIZE(result);
8329 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8333 pic16_freeAsmop(left,NULL,ic,TRUE);
8334 pic16_freeAsmop(result,NULL,ic,TRUE);
8337 /*-----------------------------------------------------------------*/
8338 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8339 /*-----------------------------------------------------------------*/
8340 static void genNearPointerGet (operand *left,
8345 //regs *preg = NULL ;
8347 sym_link *rtype, *retype;
8348 sym_link *ltype = operandType(left);
8351 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8353 rtype = operandType(result);
8354 retype= getSpec(rtype);
8356 pic16_aopOp(left,ic,FALSE);
8358 /* if left is rematerialisable and
8359 result is not bit variable type and
8360 the left is pointer to data space i.e
8361 lower 128 bytes of space */
8362 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8363 !IS_BITVAR(retype) &&
8364 DCL_TYPE(ltype) == POINTER) {
8365 //genDataPointerGet (left,result,ic);
8369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8371 /* if the value is already in a pointer register
8372 then don't need anything more */
8373 if (!AOP_INPREG(AOP(left))) {
8374 /* otherwise get a free pointer register */
8375 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8378 preg = getFreePtr(ic,&aop,FALSE);
8379 pic16_emitcode("mov","%s,%s",
8381 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8382 rname = preg->name ;
8386 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8388 pic16_aopOp (result,ic,FALSE);
8390 /* if bitfield then unpack the bits */
8391 if (IS_BITFIELD(retype))
8392 genUnpackBits (result,rname,POINTER);
8394 /* we have can just get the values */
8395 int size = AOP_SIZE(result);
8398 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8400 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8401 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8403 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8404 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8406 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8410 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8412 pic16_emitcode("mov","a,@%s",rname);
8413 pic16_aopPut(AOP(result),"a",offset);
8415 sprintf(buffer,"@%s",rname);
8416 pic16_aopPut(AOP(result),buffer,offset);
8420 pic16_emitcode("inc","%s",rname);
8425 /* now some housekeeping stuff */
8427 /* we had to allocate for this iCode */
8428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8429 pic16_freeAsmop(NULL,aop,ic,TRUE);
8431 /* we did not allocate which means left
8432 already in a pointer register, then
8433 if size > 0 && this could be used again
8434 we have to point it back to where it
8436 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8437 if (AOP_SIZE(result) > 1 &&
8438 !OP_SYMBOL(left)->remat &&
8439 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8441 int size = AOP_SIZE(result) - 1;
8443 pic16_emitcode("dec","%s",rname);
8448 pic16_freeAsmop(left,NULL,ic,TRUE);
8449 pic16_freeAsmop(result,NULL,ic,TRUE);
8453 /*-----------------------------------------------------------------*/
8454 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8455 /*-----------------------------------------------------------------*/
8456 static void genPagedPointerGet (operand *left,
8463 sym_link *rtype, *retype;
8465 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8467 rtype = operandType(result);
8468 retype= getSpec(rtype);
8470 pic16_aopOp(left,ic,FALSE);
8472 /* if the value is already in a pointer register
8473 then don't need anything more */
8474 if (!AOP_INPREG(AOP(left))) {
8475 /* otherwise get a free pointer register */
8477 preg = getFreePtr(ic,&aop,FALSE);
8478 pic16_emitcode("mov","%s,%s",
8480 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8481 rname = preg->name ;
8483 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8485 pic16_freeAsmop(left,NULL,ic,TRUE);
8486 pic16_aopOp (result,ic,FALSE);
8488 /* if bitfield then unpack the bits */
8489 if (IS_BITFIELD(retype))
8490 genUnpackBits (result,rname,PPOINTER);
8492 /* we have can just get the values */
8493 int size = AOP_SIZE(result);
8498 pic16_emitcode("movx","a,@%s",rname);
8499 pic16_aopPut(AOP(result),"a",offset);
8504 pic16_emitcode("inc","%s",rname);
8508 /* now some housekeeping stuff */
8510 /* we had to allocate for this iCode */
8511 pic16_freeAsmop(NULL,aop,ic,TRUE);
8513 /* we did not allocate which means left
8514 already in a pointer register, then
8515 if size > 0 && this could be used again
8516 we have to point it back to where it
8518 if (AOP_SIZE(result) > 1 &&
8519 !OP_SYMBOL(left)->remat &&
8520 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8522 int size = AOP_SIZE(result) - 1;
8524 pic16_emitcode("dec","%s",rname);
8529 pic16_freeAsmop(result,NULL,ic,TRUE);
8534 /*-----------------------------------------------------------------*/
8535 /* genFarPointerGet - gget value from far space */
8536 /*-----------------------------------------------------------------*/
8537 static void genFarPointerGet (operand *left,
8538 operand *result, iCode *ic)
8541 sym_link *retype = getSpec(operandType(result));
8543 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8545 pic16_aopOp(left,ic,FALSE);
8547 /* if the operand is already in dptr
8548 then we do nothing else we move the value to dptr */
8549 if (AOP_TYPE(left) != AOP_STR) {
8550 /* if this is remateriazable */
8551 if (AOP_TYPE(left) == AOP_IMMD)
8552 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8553 else { /* we need to get it byte by byte */
8554 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8555 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8556 if (options.model == MODEL_FLAT24)
8558 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8562 /* so dptr know contains the address */
8563 pic16_freeAsmop(left,NULL,ic,TRUE);
8564 pic16_aopOp(result,ic,FALSE);
8566 /* if bit then unpack */
8567 if (IS_BITFIELD(retype))
8568 genUnpackBits(result,"dptr",FPOINTER);
8570 size = AOP_SIZE(result);
8574 pic16_emitcode("movx","a,@dptr");
8575 pic16_aopPut(AOP(result),"a",offset++);
8577 pic16_emitcode("inc","dptr");
8581 pic16_freeAsmop(result,NULL,ic,TRUE);
8584 /*-----------------------------------------------------------------*/
8585 /* genCodePointerGet - get value from code space */
8586 /*-----------------------------------------------------------------*/
8587 static void genCodePointerGet (operand *left,
8588 operand *result, iCode *ic)
8591 sym_link *retype = getSpec(operandType(result));
8593 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8595 pic16_aopOp(left,ic,FALSE);
8597 /* if the operand is already in dptr
8598 then we do nothing else we move the value to dptr */
8599 if (AOP_TYPE(left) != AOP_STR) {
8600 /* if this is remateriazable */
8601 if (AOP_TYPE(left) == AOP_IMMD)
8602 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8603 else { /* we need to get it byte by byte */
8604 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8605 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8606 if (options.model == MODEL_FLAT24)
8608 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8612 /* so dptr know contains the address */
8613 pic16_freeAsmop(left,NULL,ic,TRUE);
8614 pic16_aopOp(result,ic,FALSE);
8616 /* if bit then unpack */
8617 if (IS_BITFIELD(retype))
8618 genUnpackBits(result,"dptr",CPOINTER);
8620 size = AOP_SIZE(result);
8624 pic16_emitcode("clr","a");
8625 pic16_emitcode("movc","a,@a+dptr");
8626 pic16_aopPut(AOP(result),"a",offset++);
8628 pic16_emitcode("inc","dptr");
8632 pic16_freeAsmop(result,NULL,ic,TRUE);
8635 /*-----------------------------------------------------------------*/
8636 /* genGenPointerGet - gget value from generic pointer space */
8637 /*-----------------------------------------------------------------*/
8638 static void genGenPointerGet (operand *left,
8639 operand *result, iCode *ic)
8641 int size, offset, lit;
8642 sym_link *retype = getSpec(operandType(result));
8644 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8645 pic16_aopOp(left,ic,FALSE);
8646 pic16_aopOp(result,ic,FALSE);
8647 size = AOP_SIZE(result);
8649 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8651 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
8653 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
8654 // load FSR0 from immediate
8655 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
8659 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8661 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8668 else { /* we need to get it byte by byte */
8669 // set up FSR0 with address from left
8670 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
8671 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
8677 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8679 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8686 /* if bit then unpack */
8687 if (IS_BITFIELD(retype))
8688 genUnpackBits(result,"BAD",GPOINTER);
8691 pic16_freeAsmop(left,NULL,ic,TRUE);
8692 pic16_freeAsmop(result,NULL,ic,TRUE);
8696 /*-----------------------------------------------------------------*/
8697 /* genConstPointerGet - get value from const generic pointer space */
8698 /*-----------------------------------------------------------------*/
8699 static void genConstPointerGet (operand *left,
8700 operand *result, iCode *ic)
8702 //sym_link *retype = getSpec(operandType(result));
8703 symbol *albl = newiTempLabel(NULL);
8704 symbol *blbl = newiTempLabel(NULL);
8707 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8708 pic16_aopOp(left,ic,FALSE);
8709 pic16_aopOp(result,ic,FALSE);
8712 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8714 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8716 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8717 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8718 pic16_emitpLabel(albl->key);
8720 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8722 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8723 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8724 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8725 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8726 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8728 pic16_emitpLabel(blbl->key);
8730 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8733 pic16_freeAsmop(left,NULL,ic,TRUE);
8734 pic16_freeAsmop(result,NULL,ic,TRUE);
8737 /*-----------------------------------------------------------------*/
8738 /* genPointerGet - generate code for pointer get */
8739 /*-----------------------------------------------------------------*/
8740 static void genPointerGet (iCode *ic)
8742 operand *left, *result ;
8743 sym_link *type, *etype;
8746 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8749 result = IC_RESULT(ic) ;
8751 /* depending on the type of pointer we need to
8752 move it to the correct pointer register */
8753 type = operandType(left);
8754 etype = getSpec(type);
8757 if (IS_PTR_CONST(type))
8759 if (IS_CODEPTR(type))
8761 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8763 /* if left is of type of pointer then it is simple */
8764 if (IS_PTR(type) && !IS_FUNC(type->next))
8765 p_type = DCL_TYPE(type);
8767 /* we have to go by the storage class */
8768 p_type = PTR_TYPE(SPEC_OCLS(etype));
8770 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8772 if (SPEC_OCLS(etype)->codesp ) {
8773 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8774 //p_type = CPOINTER ;
8777 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8778 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8779 /*p_type = FPOINTER ;*/
8781 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8782 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8783 /* p_type = PPOINTER; */
8785 if (SPEC_OCLS(etype) == idata )
8786 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8787 /* p_type = IPOINTER; */
8789 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8790 /* p_type = POINTER ; */
8793 /* now that we have the pointer type we assign
8794 the pointer values */
8799 genNearPointerGet (left,result,ic);
8803 genPagedPointerGet(left,result,ic);
8807 genFarPointerGet (left,result,ic);
8811 genConstPointerGet (left,result,ic);
8812 //pic16_emitcodePointerGet (left,result,ic);
8817 if (IS_PTR_CONST(type))
8818 genConstPointerGet (left,result,ic);
8821 genGenPointerGet (left,result,ic);
8827 /*-----------------------------------------------------------------*/
8828 /* genPackBits - generates code for packed bit storage */
8829 /*-----------------------------------------------------------------*/
8830 static void genPackBits (sym_link *etype ,
8832 char *rname, int p_type)
8840 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8841 blen = SPEC_BLEN(etype);
8842 bstr = SPEC_BSTR(etype);
8844 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8847 /* if the bit lenth is less than or */
8848 /* it exactly fits a byte then */
8849 if (SPEC_BLEN(etype) <= 8 ) {
8850 shCount = SPEC_BSTR(etype) ;
8852 /* shift left acc */
8855 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8860 pic16_emitcode ("mov","b,a");
8861 pic16_emitcode("mov","a,@%s",rname);
8865 pic16_emitcode ("mov","b,a");
8866 pic16_emitcode("movx","a,@dptr");
8870 pic16_emitcode ("push","b");
8871 pic16_emitcode ("push","acc");
8872 pic16_emitcode ("lcall","__gptrget");
8873 pic16_emitcode ("pop","b");
8877 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8878 ((unsigned char)(0xFF << (blen+bstr)) |
8879 (unsigned char)(0xFF >> (8-bstr)) ) );
8880 pic16_emitcode ("orl","a,b");
8881 if (p_type == GPOINTER)
8882 pic16_emitcode("pop","b");
8888 pic16_emitcode("mov","@%s,a",rname);
8892 pic16_emitcode("movx","@dptr,a");
8896 DEBUGpic16_emitcode(";lcall","__gptrput");
8901 if ( SPEC_BLEN(etype) <= 8 )
8904 pic16_emitcode("inc","%s",rname);
8905 rLen = SPEC_BLEN(etype) ;
8907 /* now generate for lengths greater than one byte */
8910 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8920 pic16_emitcode("mov","@%s,a",rname);
8922 pic16_emitcode("mov","@%s,%s",rname,l);
8927 pic16_emitcode("movx","@dptr,a");
8932 DEBUGpic16_emitcode(";lcall","__gptrput");
8935 pic16_emitcode ("inc","%s",rname);
8940 /* last last was not complete */
8942 /* save the byte & read byte */
8945 pic16_emitcode ("mov","b,a");
8946 pic16_emitcode("mov","a,@%s",rname);
8950 pic16_emitcode ("mov","b,a");
8951 pic16_emitcode("movx","a,@dptr");
8955 pic16_emitcode ("push","b");
8956 pic16_emitcode ("push","acc");
8957 pic16_emitcode ("lcall","__gptrget");
8958 pic16_emitcode ("pop","b");
8962 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8963 pic16_emitcode ("orl","a,b");
8966 if (p_type == GPOINTER)
8967 pic16_emitcode("pop","b");
8972 pic16_emitcode("mov","@%s,a",rname);
8976 pic16_emitcode("movx","@dptr,a");
8980 DEBUGpic16_emitcode(";lcall","__gptrput");
8984 /*-----------------------------------------------------------------*/
8985 /* genDataPointerSet - remat pointer to data space */
8986 /*-----------------------------------------------------------------*/
8987 static void genDataPointerSet(operand *right,
8991 int size, offset = 0 ;
8992 char *l, buffer[256];
8994 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8995 pic16_aopOp(right,ic,FALSE);
8997 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8998 size = AOP_SIZE(right);
9000 if ( AOP_TYPE(result) == AOP_PCODE) {
9001 fprintf(stderr,"genDataPointerSet %s, %d\n",
9002 AOP(result)->aopu.pcop->name,
9003 PCOI(AOP(result)->aopu.pcop)->offset);
9007 // tsd, was l+1 - the underline `_' prefix was being stripped
9010 sprintf(buffer,"(%s + %d)",l,offset);
9011 fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer);
9013 sprintf(buffer,"%s",l);
9015 if (AOP_TYPE(right) == AOP_LIT) {
9016 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9017 lit = lit >> (8*offset);
9019 pic16_emitcode("movlw","%d",lit);
9020 pic16_emitcode("movwf","%s",buffer);
9022 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9023 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
9024 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9027 pic16_emitcode("clrf","%s",buffer);
9028 //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer));
9029 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9032 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
9033 pic16_emitcode("movwf","%s",buffer);
9035 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9036 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
9037 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9044 pic16_freeAsmop(right,NULL,ic,TRUE);
9045 pic16_freeAsmop(result,NULL,ic,TRUE);
9048 /*-----------------------------------------------------------------*/
9049 /* genNearPointerSet - pic16_emitcode for near pointer put */
9050 /*-----------------------------------------------------------------*/
9051 static void genNearPointerSet (operand *right,
9058 sym_link *ptype = operandType(result);
9061 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9062 retype= getSpec(operandType(right));
9064 pic16_aopOp(result,ic,FALSE);
9067 /* if the result is rematerializable &
9068 in data space & not a bit variable */
9069 //if (AOP_TYPE(result) == AOP_IMMD &&
9070 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
9071 DCL_TYPE(ptype) == POINTER &&
9072 !IS_BITVAR(retype)) {
9073 genDataPointerSet (right,result,ic);
9074 pic16_freeAsmop(result,NULL,ic,TRUE);
9078 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9079 pic16_aopOp(right,ic,FALSE);
9080 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9082 /* if the value is already in a pointer register
9083 then don't need anything more */
9084 if (!AOP_INPREG(AOP(result))) {
9085 /* otherwise get a free pointer register */
9086 //aop = newAsmop(0);
9087 //preg = getFreePtr(ic,&aop,FALSE);
9088 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9089 //pic16_emitcode("mov","%s,%s",
9091 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
9092 //rname = preg->name ;
9093 //pic16_emitcode("movwf","fsr0");
9094 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
9095 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
9096 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9097 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9101 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9103 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9105 /* if bitfield then unpack the bits */
9106 if (IS_BITFIELD(retype)) {
9107 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9108 "The programmer is obviously confused");
9109 // genPackBits (retype,right,"BAD",POINTER);
9113 /* we have can just get the values */
9114 int size = AOP_SIZE(right);
9117 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9119 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9122 //pic16_emitcode("mov","@%s,a",rname);
9123 pic16_emitcode("movf","indf0,w ;1");
9126 if (AOP_TYPE(right) == AOP_LIT) {
9127 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9129 pic16_emitcode("movlw","%s",l);
9130 pic16_emitcode("movwf","indf0 ;2");
9132 pic16_emitcode("clrf","indf0");
9134 pic16_emitcode("movf","%s,w",l);
9135 pic16_emitcode("movwf","indf0 ;2");
9137 //pic16_emitcode("mov","@%s,%s",rname,l);
9140 pic16_emitcode("incf","fsr0,f ;3");
9141 //pic16_emitcode("inc","%s",rname);
9146 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9147 /* now some housekeeping stuff */
9149 /* we had to allocate for this iCode */
9150 pic16_freeAsmop(NULL,aop,ic,TRUE);
9152 /* we did not allocate which means left
9153 already in a pointer register, then
9154 if size > 0 && this could be used again
9155 we have to point it back to where it
9157 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9158 if (AOP_SIZE(right) > 1 &&
9159 !OP_SYMBOL(result)->remat &&
9160 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9162 int size = AOP_SIZE(right) - 1;
9164 pic16_emitcode("decf","fsr0,f");
9165 //pic16_emitcode("dec","%s",rname);
9169 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9172 pic16_freeAsmop(right,NULL,ic,TRUE);
9173 pic16_freeAsmop(result,NULL,ic,TRUE);
9176 /*-----------------------------------------------------------------*/
9177 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9178 /*-----------------------------------------------------------------*/
9179 static void genPagedPointerSet (operand *right,
9188 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9190 retype= getSpec(operandType(right));
9192 pic16_aopOp(result,ic,FALSE);
9194 /* if the value is already in a pointer register
9195 then don't need anything more */
9196 if (!AOP_INPREG(AOP(result))) {
9197 /* otherwise get a free pointer register */
9199 preg = getFreePtr(ic,&aop,FALSE);
9200 pic16_emitcode("mov","%s,%s",
9202 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9203 rname = preg->name ;
9205 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9207 pic16_freeAsmop(result,NULL,ic,TRUE);
9208 pic16_aopOp (right,ic,FALSE);
9210 /* if bitfield then unpack the bits */
9211 if (IS_BITFIELD(retype))
9212 genPackBits (retype,right,rname,PPOINTER);
9214 /* we have can just get the values */
9215 int size = AOP_SIZE(right);
9219 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9222 pic16_emitcode("movx","@%s,a",rname);
9225 pic16_emitcode("inc","%s",rname);
9231 /* now some housekeeping stuff */
9233 /* we had to allocate for this iCode */
9234 pic16_freeAsmop(NULL,aop,ic,TRUE);
9236 /* we did not allocate which means left
9237 already in a pointer register, then
9238 if size > 0 && this could be used again
9239 we have to point it back to where it
9241 if (AOP_SIZE(right) > 1 &&
9242 !OP_SYMBOL(result)->remat &&
9243 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9245 int size = AOP_SIZE(right) - 1;
9247 pic16_emitcode("dec","%s",rname);
9252 pic16_freeAsmop(right,NULL,ic,TRUE);
9257 /*-----------------------------------------------------------------*/
9258 /* genFarPointerSet - set value from far space */
9259 /*-----------------------------------------------------------------*/
9260 static void genFarPointerSet (operand *right,
9261 operand *result, iCode *ic)
9264 sym_link *retype = getSpec(operandType(right));
9266 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9267 pic16_aopOp(result,ic,FALSE);
9269 /* if the operand is already in dptr
9270 then we do nothing else we move the value to dptr */
9271 if (AOP_TYPE(result) != AOP_STR) {
9272 /* if this is remateriazable */
9273 if (AOP_TYPE(result) == AOP_IMMD)
9274 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9275 else { /* we need to get it byte by byte */
9276 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9277 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9278 if (options.model == MODEL_FLAT24)
9280 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9284 /* so dptr know contains the address */
9285 pic16_freeAsmop(result,NULL,ic,TRUE);
9286 pic16_aopOp(right,ic,FALSE);
9288 /* if bit then unpack */
9289 if (IS_BITFIELD(retype))
9290 genPackBits(retype,right,"dptr",FPOINTER);
9292 size = AOP_SIZE(right);
9296 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9298 pic16_emitcode("movx","@dptr,a");
9300 pic16_emitcode("inc","dptr");
9304 pic16_freeAsmop(right,NULL,ic,TRUE);
9307 /*-----------------------------------------------------------------*/
9308 /* genGenPointerSet - set value from generic pointer space */
9309 /*-----------------------------------------------------------------*/
9310 static void genGenPointerSet (operand *right,
9311 operand *result, iCode *ic)
9313 int size, offset, lit;
9314 sym_link *retype = getSpec(operandType(right));
9316 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9318 pic16_aopOp(result,ic,FALSE);
9319 pic16_aopOp(right,ic,FALSE);
9320 size = AOP_SIZE(right);
9323 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9326 /* if the operand is already in dptr
9327 then we do nothing else we move the value to dptr */
9328 if (AOP_TYPE(result) != AOP_STR) {
9329 /* if this is remateriazable */
9330 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9331 // WARNING: anythig until "else" is untested!
9332 if (AOP_TYPE(result) == AOP_IMMD) {
9333 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9334 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
9335 // load FSR0 from immediate
9336 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9340 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9342 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9348 else { /* we need to get it byte by byte */
9349 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9350 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9352 // set up FSR0 with address of result
9353 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9354 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9356 /* hack hack! see if this the FSR. If so don't load W */
9357 if(AOP_TYPE(right) != AOP_ACC) {
9359 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9363 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9365 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9372 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9374 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9376 } // if (AOP_TYPE(result) != AOP_IMMD)
9378 } // if (AOP_TYPE(result) != AOP_STR)
9379 /* so dptr know contains the address */
9382 /* if bit then unpack */
9383 if (IS_BITFIELD(retype))
9384 genPackBits(retype,right,"dptr",GPOINTER);
9386 size = AOP_SIZE(right);
9389 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9391 // set up FSR0 with address of result
9392 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9393 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9396 if (AOP_TYPE(right) == AOP_LIT) {
9397 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9399 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
9401 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9403 } else { // no literal
9405 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9407 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9415 pic16_freeAsmop(right,NULL,ic,TRUE);
9416 pic16_freeAsmop(result,NULL,ic,TRUE);
9419 /*-----------------------------------------------------------------*/
9420 /* genPointerSet - stores the value into a pointer location */
9421 /*-----------------------------------------------------------------*/
9422 static void genPointerSet (iCode *ic)
9424 operand *right, *result ;
9425 sym_link *type, *etype;
9428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9430 right = IC_RIGHT(ic);
9431 result = IC_RESULT(ic) ;
9433 /* depending on the type of pointer we need to
9434 move it to the correct pointer register */
9435 type = operandType(result);
9436 etype = getSpec(type);
9437 /* if left is of type of pointer then it is simple */
9438 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9439 p_type = DCL_TYPE(type);
9442 /* we have to go by the storage class */
9443 p_type = PTR_TYPE(SPEC_OCLS(etype));
9445 /* if (SPEC_OCLS(etype)->codesp ) { */
9446 /* p_type = CPOINTER ; */
9449 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9450 /* p_type = FPOINTER ; */
9452 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9453 /* p_type = PPOINTER ; */
9455 /* if (SPEC_OCLS(etype) == idata ) */
9456 /* p_type = IPOINTER ; */
9458 /* p_type = POINTER ; */
9461 /* now that we have the pointer type we assign
9462 the pointer values */
9467 genNearPointerSet (right,result,ic);
9471 genPagedPointerSet (right,result,ic);
9475 genFarPointerSet (right,result,ic);
9479 genGenPointerSet (right,result,ic);
9483 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9484 "genPointerSet: illegal pointer type");
9488 /*-----------------------------------------------------------------*/
9489 /* genIfx - generate code for Ifx statement */
9490 /*-----------------------------------------------------------------*/
9491 static void genIfx (iCode *ic, iCode *popIc)
9493 operand *cond = IC_COND(ic);
9496 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9498 pic16_aopOp(cond,ic,FALSE);
9500 /* get the value into acc */
9501 if (AOP_TYPE(cond) != AOP_CRY)
9502 pic16_toBoolean(cond);
9505 /* the result is now in the accumulator */
9506 pic16_freeAsmop(cond,NULL,ic,TRUE);
9508 /* if there was something to be popped then do it */
9512 /* if the condition is a bit variable */
9513 if (isbit && IS_ITEMP(cond) &&
9515 genIfxJump(ic,SPIL_LOC(cond)->rname);
9516 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9519 if (isbit && !IS_ITEMP(cond))
9520 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9528 /*-----------------------------------------------------------------*/
9529 /* genAddrOf - generates code for address of */
9530 /*-----------------------------------------------------------------*/
9532 static void genAddrOf (iCode *ic)
9534 operand *right, *result, *left;
9537 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9540 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9542 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9543 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9544 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9546 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9548 size = AOP_SIZE(IC_RESULT(ic));
9553 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9554 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9559 pic16_freeAsmop(left,NULL,ic,FALSE);
9560 pic16_freeAsmop(result,NULL,ic,TRUE);
9564 #else /* new genAddrOf */
9566 static void genAddrOf (iCode *ic)
9568 operand *result, *left;
9570 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9571 pCodeOp *pcop0, *pcop1, *pcop2;
9573 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9575 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9576 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9578 sym = OP_SYMBOL( left );
9580 size = AOP_SIZE(IC_RESULT(ic));
9582 if(pic16_debug_verbose) {
9583 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9584 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9587 /* Assume that what we want the address of is in data space
9588 * since there is no stack on the PIC, yet! -- VR */
9590 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9593 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9596 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9600 pic16_emitpcode(POC_MOVLW, pcop0);
9601 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9602 pic16_emitpcode(POC_MOVLW, pcop1);
9603 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9604 pic16_emitpcode(POC_MOVLW, pcop2);
9605 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9608 pic16_emitpcode(POC_MOVLW, pcop0);
9609 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9610 pic16_emitpcode(POC_MOVLW, pcop1);
9611 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9613 pic16_emitpcode(POC_MOVLW, pcop0);
9614 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9617 pic16_freeAsmop(result,NULL,ic,TRUE);
9618 pic16_freeAsmop(left, NULL, ic, FALSE);
9621 #endif /* new genAddrOf */
9624 /*-----------------------------------------------------------------*/
9625 /* genFarFarAssign - assignment when both are in far space */
9626 /*-----------------------------------------------------------------*/
9627 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9629 int size = AOP_SIZE(right);
9632 /* first push the right side on to the stack */
9634 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9636 pic16_emitcode ("push","acc");
9639 pic16_freeAsmop(right,NULL,ic,FALSE);
9640 /* now assign DPTR to result */
9641 pic16_aopOp(result,ic,FALSE);
9642 size = AOP_SIZE(result);
9644 pic16_emitcode ("pop","acc");
9645 pic16_aopPut(AOP(result),"a",--offset);
9647 pic16_freeAsmop(result,NULL,ic,FALSE);
9652 /*-----------------------------------------------------------------*/
9653 /* genAssign - generate code for assignment */
9654 /*-----------------------------------------------------------------*/
9655 static void genAssign (iCode *ic)
9657 operand *result, *right;
9658 int size, offset,know_W;
9659 unsigned long lit = 0L;
9661 result = IC_RESULT(ic);
9662 right = IC_RIGHT(ic) ;
9664 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9666 /* if they are the same */
9667 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9670 pic16_aopOp(right,ic,FALSE);
9671 pic16_aopOp(result,ic,TRUE);
9673 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9675 /* if they are the same registers */
9676 if (pic16_sameRegs(AOP(right),AOP(result)))
9679 /* if the result is a bit */
9680 if (AOP_TYPE(result) == AOP_CRY) {
9681 /* if the right size is a literal then
9682 we know what the value is */
9683 if (AOP_TYPE(right) == AOP_LIT) {
9685 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9686 pic16_popGet(AOP(result),0));
9688 if (((int) operandLitValue(right)))
9689 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9690 AOP(result)->aopu.aop_dir,
9691 AOP(result)->aopu.aop_dir);
9693 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9694 AOP(result)->aopu.aop_dir,
9695 AOP(result)->aopu.aop_dir);
9699 /* the right is also a bit variable */
9700 if (AOP_TYPE(right) == AOP_CRY) {
9701 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9702 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9703 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9705 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9706 AOP(result)->aopu.aop_dir,
9707 AOP(result)->aopu.aop_dir);
9708 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9709 AOP(right)->aopu.aop_dir,
9710 AOP(right)->aopu.aop_dir);
9711 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9712 AOP(result)->aopu.aop_dir,
9713 AOP(result)->aopu.aop_dir);
9718 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9719 pic16_toBoolean(right);
9721 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9722 //pic16_aopPut(AOP(result),"a",0);
9726 /* bit variables done */
9728 size = AOP_SIZE(result);
9730 if(AOP_TYPE(right) == AOP_LIT)
9731 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9733 /* VR - What is this?! */
9734 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9735 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9736 if(aopIdx(AOP(result),0) == 4) {
9737 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9738 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9739 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9742 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9747 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9748 if(AOP_TYPE(right) == AOP_LIT) {
9750 if(know_W != (lit&0xff))
9751 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9753 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9755 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9759 } else if (AOP_TYPE(right) == AOP_CRY) {
9760 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9762 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9763 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9766 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9769 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9770 normally should work, but mind that the W register live range
9771 is not checked, so if the code generator assumes that the W
9772 is already loaded after such a pair, wrong code will be generated.
9774 Checking the live range is the next step.
9775 This is experimental code yet and has not been fully tested yet.
9776 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9777 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9779 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9781 /* This is the old code, which is assumed(?!) that works fine(!?) */
9783 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9784 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9793 pic16_freeAsmop (right,NULL,ic,FALSE);
9794 pic16_freeAsmop (result,NULL,ic,TRUE);
9797 /*-----------------------------------------------------------------*/
9798 /* genJumpTab - generates code for jump table */
9799 /*-----------------------------------------------------------------*/
9800 static void genJumpTab (iCode *ic)
9805 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9807 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9808 /* get the condition into accumulator */
9809 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9811 /* multiply by three */
9812 pic16_emitcode("add","a,acc");
9813 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9815 jtab = newiTempLabel(NULL);
9816 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9817 pic16_emitcode("jmp","@a+dptr");
9818 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9820 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9821 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9823 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9824 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9825 pic16_emitpLabel(jtab->key);
9827 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9829 /* now generate the jump labels */
9830 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9831 jtab = setNextItem(IC_JTLABELS(ic))) {
9832 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9833 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9839 /*-----------------------------------------------------------------*/
9840 /* genMixedOperation - gen code for operators between mixed types */
9841 /*-----------------------------------------------------------------*/
9843 TSD - Written for the PIC port - but this unfortunately is buggy.
9844 This routine is good in that it is able to efficiently promote
9845 types to different (larger) sizes. Unfortunately, the temporary
9846 variables that are optimized out by this routine are sometimes
9847 used in other places. So until I know how to really parse the
9848 iCode tree, I'm going to not be using this routine :(.
9850 static int genMixedOperation (iCode *ic)
9853 operand *result = IC_RESULT(ic);
9854 sym_link *ctype = operandType(IC_LEFT(ic));
9855 operand *right = IC_RIGHT(ic);
9861 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9863 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9869 nextright = IC_RIGHT(nextic);
9870 nextleft = IC_LEFT(nextic);
9871 nextresult = IC_RESULT(nextic);
9873 pic16_aopOp(right,ic,FALSE);
9874 pic16_aopOp(result,ic,FALSE);
9875 pic16_aopOp(nextright, nextic, FALSE);
9876 pic16_aopOp(nextleft, nextic, FALSE);
9877 pic16_aopOp(nextresult, nextic, FALSE);
9879 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9885 pic16_emitcode(";remove right +","");
9887 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9893 pic16_emitcode(";remove left +","");
9897 big = AOP_SIZE(nextleft);
9898 small = AOP_SIZE(nextright);
9900 switch(nextic->op) {
9903 pic16_emitcode(";optimize a +","");
9904 /* if unsigned or not an integral type */
9905 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9906 pic16_emitcode(";add a bit to something","");
9909 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9911 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9912 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9913 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9915 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9923 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9924 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9925 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9928 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9930 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9931 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9932 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9933 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9934 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9937 pic16_emitcode("rlf","known_zero,w");
9944 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9945 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9946 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9948 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9958 pic16_freeAsmop(right,NULL,ic,TRUE);
9959 pic16_freeAsmop(result,NULL,ic,TRUE);
9960 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9961 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9963 nextic->generated = 1;
9970 /*-----------------------------------------------------------------*/
9971 /* genCast - gen code for casting */
9972 /*-----------------------------------------------------------------*/
9973 static void genCast (iCode *ic)
9975 operand *result = IC_RESULT(ic);
9976 sym_link *ctype = operandType(IC_LEFT(ic));
9977 sym_link *rtype = operandType(IC_RIGHT(ic));
9978 operand *right = IC_RIGHT(ic);
9981 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9982 /* if they are equivalent then do nothing */
9983 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9986 pic16_aopOp(right,ic,FALSE) ;
9987 pic16_aopOp(result,ic,FALSE);
9989 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9991 /* if the result is a bit */
9992 if (AOP_TYPE(result) == AOP_CRY) {
9994 /* if the right size is a literal then
9995 * we know what the value is */
9996 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9998 if (AOP_TYPE(right) == AOP_LIT) {
9999 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10000 pic16_popGet(AOP(result),0));
10002 if (((int) operandLitValue(right)))
10003 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10004 AOP(result)->aopu.aop_dir,
10005 AOP(result)->aopu.aop_dir);
10007 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10008 AOP(result)->aopu.aop_dir,
10009 AOP(result)->aopu.aop_dir);
10013 /* the right is also a bit variable */
10014 if (AOP_TYPE(right) == AOP_CRY) {
10016 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10018 pic16_emitcode("clrc","");
10019 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10020 AOP(right)->aopu.aop_dir,
10021 AOP(right)->aopu.aop_dir);
10022 pic16_aopPut(AOP(result),"c",0);
10026 /* we need to or */
10027 if (AOP_TYPE(right) == AOP_REG) {
10028 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10029 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10030 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10032 pic16_toBoolean(right);
10033 pic16_aopPut(AOP(result),"a",0);
10037 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10040 size = AOP_SIZE(result);
10042 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10044 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10045 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10046 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10049 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10054 /* if they are the same size : or less */
10055 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10057 /* if they are in the same place */
10058 if (pic16_sameRegs(AOP(right),AOP(result)))
10061 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10063 if (IS_PTR_CONST(rtype))
10065 if (IS_CODEPTR(rtype))
10067 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10070 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10072 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10074 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10077 if(AOP_TYPE(right) == AOP_IMMD) {
10078 pCodeOp *pcop0, *pcop1, *pcop2;
10079 symbol *sym = OP_SYMBOL( right );
10081 size = AOP_SIZE(result);
10083 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10085 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10087 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10090 pic16_emitpcode(POC_MOVLW, pcop0);
10091 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10092 pic16_emitpcode(POC_MOVLW, pcop1);
10093 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10094 pic16_emitpcode(POC_MOVLW, pcop2);
10095 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10098 pic16_emitpcode(POC_MOVLW, pcop0);
10099 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10100 pic16_emitpcode(POC_MOVLW, pcop1);
10101 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10103 pic16_emitpcode(POC_MOVLW, pcop0);
10104 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10108 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10109 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10110 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10111 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10112 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10113 if(AOP_SIZE(result) <2)
10114 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10116 /* if they in different places then copy */
10117 size = AOP_SIZE(result);
10120 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10121 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10128 /* if the result is of type pointer */
10129 if (IS_PTR(ctype)) {
10131 sym_link *type = operandType(right);
10132 sym_link *etype = getSpec(type);
10134 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10136 /* pointer to generic pointer */
10137 if (IS_GENPTR(ctype)) {
10141 p_type = DCL_TYPE(type);
10143 /* we have to go by the storage class */
10144 p_type = PTR_TYPE(SPEC_OCLS(etype));
10146 /* if (SPEC_OCLS(etype)->codesp ) */
10147 /* p_type = CPOINTER ; */
10149 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10150 /* p_type = FPOINTER ; */
10152 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10153 /* p_type = PPOINTER; */
10155 /* if (SPEC_OCLS(etype) == idata ) */
10156 /* p_type = IPOINTER ; */
10158 /* p_type = POINTER ; */
10161 /* the first two bytes are known */
10162 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10163 size = GPTRSIZE - 1;
10166 if(offset < AOP_SIZE(right)) {
10167 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10168 if ((AOP_TYPE(right) == AOP_PCODE) &&
10169 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10170 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10171 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10173 pic16_aopPut(AOP(result),
10174 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10178 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10181 /* the last byte depending on type */
10185 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10188 pic16_emitcode(";BUG!? ","%d",__LINE__);
10192 pic16_emitcode(";BUG!? ","%d",__LINE__);
10196 pic16_emitcode(";BUG!? ","%d",__LINE__);
10201 /* this should never happen */
10202 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10203 "got unknown pointer type");
10206 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10210 /* just copy the pointers */
10211 size = AOP_SIZE(result);
10214 pic16_aopPut(AOP(result),
10215 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10224 /* so we now know that the size of destination is greater
10225 than the size of the source.
10226 Now, if the next iCode is an operator then we might be
10227 able to optimize the operation without performing a cast.
10229 if(genMixedOperation(ic))
10232 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10234 /* we move to result for the size of source */
10235 size = AOP_SIZE(right);
10238 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10239 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10243 /* now depending on the sign of the destination */
10244 size = AOP_SIZE(result) - AOP_SIZE(right);
10245 /* if unsigned or not an integral type */
10246 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10248 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10250 /* we need to extend the sign :( */
10253 /* Save one instruction of casting char to int */
10254 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10255 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10256 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10258 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10261 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10263 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10265 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10268 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10273 pic16_freeAsmop(right,NULL,ic,TRUE);
10274 pic16_freeAsmop(result,NULL,ic,TRUE);
10278 /*-----------------------------------------------------------------*/
10279 /* genDjnz - generate decrement & jump if not zero instrucion */
10280 /*-----------------------------------------------------------------*/
10281 static int genDjnz (iCode *ic, iCode *ifx)
10283 symbol *lbl, *lbl1;
10284 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10289 /* if the if condition has a false label
10290 then we cannot save */
10294 /* if the minus is not of the form
10296 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10297 !IS_OP_LITERAL(IC_RIGHT(ic)))
10300 if (operandLitValue(IC_RIGHT(ic)) != 1)
10303 /* if the size of this greater than one then no
10305 if (getSize(operandType(IC_RESULT(ic))) > 1)
10308 /* otherwise we can save BIG */
10309 lbl = newiTempLabel(NULL);
10310 lbl1= newiTempLabel(NULL);
10312 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10314 if (IS_AOP_PREG(IC_RESULT(ic))) {
10315 pic16_emitcode("dec","%s",
10316 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10317 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10318 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10322 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10323 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10325 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10326 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10329 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10330 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10331 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10332 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10335 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10336 ifx->generated = 1;
10340 /*-----------------------------------------------------------------*/
10341 /* genReceive - generate code for a receive iCode */
10342 /*-----------------------------------------------------------------*/
10343 static void genReceive (iCode *ic)
10345 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10347 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10348 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10349 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10351 int size = getSize(operandType(IC_RESULT(ic)));
10352 int offset = pic16_fReturnSizePic - size;
10355 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10356 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10360 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10362 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10363 size = AOP_SIZE(IC_RESULT(ic));
10366 pic16_emitcode ("pop","acc");
10367 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10370 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10373 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10375 assignResultValue(IC_RESULT(ic));
10378 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10381 /*-----------------------------------------------------------------*/
10382 /* genDummyRead - generate code for dummy read of volatiles */
10383 /*-----------------------------------------------------------------*/
10385 genDummyRead (iCode * ic)
10387 pic16_emitcode ("; genDummyRead","");
10388 pic16_emitcode ("; not implemented","");
10393 /*-----------------------------------------------------------------*/
10394 /* genpic16Code - generate code for pic16 based controllers */
10395 /*-----------------------------------------------------------------*/
10397 * At this point, ralloc.c has gone through the iCode and attempted
10398 * to optimize in a way suitable for a PIC. Now we've got to generate
10399 * PIC instructions that correspond to the iCode.
10401 * Once the instructions are generated, we'll pass through both the
10402 * peep hole optimizer and the pCode optimizer.
10403 *-----------------------------------------------------------------*/
10405 void genpic16Code (iCode *lic)
10410 lineHead = lineCurr = NULL;
10412 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10413 pic16_addpBlock(pb);
10416 /* if debug information required */
10417 if (options.debug && currFunc) {
10419 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10421 if (IS_STATIC(currFunc->etype)) {
10422 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10423 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10425 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10426 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10435 for (ic = lic ; ic ; ic = ic->next ) {
10437 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10438 // DEBUGpic16_emitcode("; VR", "");
10439 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10440 if ( cln != ic->lineno ) {
10441 if ( options.debug ) {
10443 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10444 FileBaseName(ic->filename),ic->lineno,
10445 ic->level,ic->block);
10449 if(!options.noCcodeInAsm) {
10450 pic16_addpCode2pBlock(pb,
10451 pic16_newpCodeCSource(ic->lineno, ic->filename,
10452 printCLine(ic->filename, ic->lineno)));
10458 if(options.iCodeInAsm) {
10459 /* insert here code to print iCode as comment */
10460 pic16_emitcomment("; ic:%d: %s", ic->seq, printILine(ic));
10463 /* if the result is marked as
10464 spilt and rematerializable or code for
10465 this has already been generated then
10467 if (resultRemat(ic) || ic->generated )
10470 /* depending on the operation */
10489 /* IPOP happens only when trying to restore a
10490 spilt live range, if there is an ifx statement
10491 following this pop then the if statement might
10492 be using some of the registers being popped which
10493 would destroy the contents of the register so
10494 we need to check for this condition and handle it */
10496 ic->next->op == IFX &&
10497 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10498 genIfx (ic->next,ic);
10516 genEndFunction (ic);
10532 pic16_genPlus (ic) ;
10536 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10537 pic16_genMinus (ic);
10553 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10557 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10564 /* note these two are xlated by algebraic equivalence
10565 during parsing SDCC.y */
10566 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10567 "got '>=' or '<=' shouldn't have come here");
10571 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10583 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10587 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10591 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10615 genRightShift (ic);
10618 case GET_VALUE_AT_ADDRESS:
10623 if (POINTER_SET(ic))
10650 addSet(&_G.sendSet,ic);
10653 case DUMMY_READ_VOLATILE:
10663 /* now we are ready to call the
10664 peep hole optimizer */
10665 if (!options.nopeep) {
10666 peepHole (&lineHead);
10668 /* now do the actual printing */
10669 printLine (lineHead,codeOutFile);
10672 DFPRINTF((stderr,"printing pBlock\n\n"));
10673 pic16_printpBlock(stdout,pb);