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 */
6354 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL));
6356 pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 0));
6358 // inline directly, no process
6365 pic16_emitcode(bp1,"");
6371 if ((bp1 != bp) && *bp1)
6372 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6376 _G.inLine -= (!options.asmpeep);
6379 /*-----------------------------------------------------------------*/
6380 /* genRRC - rotate right with carry */
6381 /*-----------------------------------------------------------------*/
6382 static void genRRC (iCode *ic)
6384 operand *left , *result ;
6385 int size, offset = 0, same;
6387 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6389 /* rotate right with carry */
6391 result=IC_RESULT(ic);
6392 pic16_aopOp (left,ic,FALSE);
6393 pic16_aopOp (result,ic,FALSE);
6395 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6397 same = pic16_sameRegs(AOP(result),AOP(left));
6399 size = AOP_SIZE(result);
6401 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6403 /* get the lsb and put it into the carry */
6404 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6411 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6413 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6414 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6420 pic16_freeAsmop(left,NULL,ic,TRUE);
6421 pic16_freeAsmop(result,NULL,ic,TRUE);
6424 /*-----------------------------------------------------------------*/
6425 /* genRLC - generate code for rotate left with carry */
6426 /*-----------------------------------------------------------------*/
6427 static void genRLC (iCode *ic)
6429 operand *left , *result ;
6430 int size, offset = 0;
6433 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6434 /* rotate right with carry */
6436 result=IC_RESULT(ic);
6437 pic16_aopOp (left,ic,FALSE);
6438 pic16_aopOp (result,ic,FALSE);
6440 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6442 same = pic16_sameRegs(AOP(result),AOP(left));
6444 /* move it to the result */
6445 size = AOP_SIZE(result);
6447 /* get the msb and put it into the carry */
6448 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6455 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6457 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6458 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6465 pic16_freeAsmop(left,NULL,ic,TRUE);
6466 pic16_freeAsmop(result,NULL,ic,TRUE);
6469 /*-----------------------------------------------------------------*/
6470 /* genGetHbit - generates code get highest order bit */
6471 /*-----------------------------------------------------------------*/
6472 static void genGetHbit (iCode *ic)
6474 operand *left, *result;
6476 result=IC_RESULT(ic);
6477 pic16_aopOp (left,ic,FALSE);
6478 pic16_aopOp (result,ic,FALSE);
6480 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6481 /* get the highest order byte into a */
6482 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6483 if(AOP_TYPE(result) == AOP_CRY){
6484 pic16_emitcode("rlc","a");
6485 pic16_outBitC(result);
6488 pic16_emitcode("rl","a");
6489 pic16_emitcode("anl","a,#0x01");
6490 pic16_outAcc(result);
6494 pic16_freeAsmop(left,NULL,ic,TRUE);
6495 pic16_freeAsmop(result,NULL,ic,TRUE);
6499 /*-----------------------------------------------------------------*/
6500 /* AccRol - rotate left accumulator by known count */
6501 /*-----------------------------------------------------------------*/
6502 static void AccRol (int shCount)
6504 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6505 shCount &= 0x0007; // shCount : 0..7
6510 pic16_emitcode("rl","a");
6513 pic16_emitcode("rl","a");
6514 pic16_emitcode("rl","a");
6517 pic16_emitcode("swap","a");
6518 pic16_emitcode("rr","a");
6521 pic16_emitcode("swap","a");
6524 pic16_emitcode("swap","a");
6525 pic16_emitcode("rl","a");
6528 pic16_emitcode("rr","a");
6529 pic16_emitcode("rr","a");
6532 pic16_emitcode("rr","a");
6538 /*-----------------------------------------------------------------*/
6539 /* AccLsh - left shift accumulator by known count */
6540 /*-----------------------------------------------------------------*/
6541 static void AccLsh (int shCount)
6543 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6549 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6552 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6553 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6556 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6557 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6560 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6563 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6564 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6567 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6568 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6571 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6574 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
6578 /*-----------------------------------------------------------------*/
6579 /* AccRsh - right shift accumulator by known count */
6580 /*-----------------------------------------------------------------*/
6581 static void AccRsh (int shCount)
6583 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6589 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6592 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6593 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6596 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6597 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6600 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6603 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6604 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6607 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6608 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6611 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6614 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
6618 /*-----------------------------------------------------------------*/
6619 /* AccSRsh - signed right shift accumulator by known count */
6620 /*-----------------------------------------------------------------*/
6621 static void AccSRsh (int shCount)
6624 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6627 pic16_emitcode("mov","c,acc.7");
6628 pic16_emitcode("rrc","a");
6629 } else if(shCount == 2){
6630 pic16_emitcode("mov","c,acc.7");
6631 pic16_emitcode("rrc","a");
6632 pic16_emitcode("mov","c,acc.7");
6633 pic16_emitcode("rrc","a");
6635 tlbl = newiTempLabel(NULL);
6636 /* rotate right accumulator */
6637 AccRol(8 - shCount);
6638 /* and kill the higher order bits */
6639 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6640 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6641 pic16_emitcode("orl","a,#0x%02x",
6642 (unsigned char)~SRMask[shCount]);
6643 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6648 /*-----------------------------------------------------------------*/
6649 /* shiftR1Left2Result - shift right one byte from left to result */
6650 /*-----------------------------------------------------------------*/
6651 static void shiftR1Left2ResultSigned (operand *left, int offl,
6652 operand *result, int offr,
6657 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6659 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6663 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6665 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6667 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6668 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6674 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6676 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6678 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6679 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6681 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6682 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6688 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6690 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6691 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6694 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6695 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6696 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6698 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6699 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6701 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6705 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6706 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6707 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6708 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6709 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6713 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6715 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6716 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6718 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6719 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6720 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6721 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6722 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6727 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6728 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6729 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6730 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6731 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6732 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6734 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6735 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6736 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6737 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6738 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6744 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6745 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6746 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6747 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6749 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6750 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6751 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6759 /*-----------------------------------------------------------------*/
6760 /* shiftR1Left2Result - shift right one byte from left to result */
6761 /*-----------------------------------------------------------------*/
6762 static void shiftR1Left2Result (operand *left, int offl,
6763 operand *result, int offr,
6764 int shCount, int sign)
6768 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6770 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6772 /* Copy the msb into the carry if signed. */
6774 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6784 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6786 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6787 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6793 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6795 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6796 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6799 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6804 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6806 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6807 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6810 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6811 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6812 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6813 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6817 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6818 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6819 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6823 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6824 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6825 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6827 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6832 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6833 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6834 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6835 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6836 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6841 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6842 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6843 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6852 /*-----------------------------------------------------------------*/
6853 /* shiftL1Left2Result - shift left one byte from left to result */
6854 /*-----------------------------------------------------------------*/
6855 static void shiftL1Left2Result (operand *left, int offl,
6856 operand *result, int offr, int shCount)
6861 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6863 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6864 DEBUGpic16_emitcode ("; ***","same = %d",same);
6865 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6867 /* shift left accumulator */
6868 //AccLsh(shCount); // don't comment out just yet...
6869 // pic16_aopPut(AOP(result),"a",offr);
6873 /* Shift left 1 bit position */
6874 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6876 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6878 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6879 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6883 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6884 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6885 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6886 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6889 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6890 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6891 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6892 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6893 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6896 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6897 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6898 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6901 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6902 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6903 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6904 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6907 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6908 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6909 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6910 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6911 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6914 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6915 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6916 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6920 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6925 /*-----------------------------------------------------------------*/
6926 /* movLeft2Result - move byte from left to result */
6927 /*-----------------------------------------------------------------*/
6928 static void movLeft2Result (operand *left, int offl,
6929 operand *result, int offr)
6932 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6933 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6934 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6936 if (*l == '@' && (IS_AOP_PREG(result))) {
6937 pic16_emitcode("mov","a,%s",l);
6938 pic16_aopPut(AOP(result),"a",offr);
6940 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6941 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6946 /*-----------------------------------------------------------------*/
6947 /* shiftL2Left2Result - shift left two bytes from left to result */
6948 /*-----------------------------------------------------------------*/
6949 static void shiftL2Left2Result (operand *left, int offl,
6950 operand *result, int offr, int shCount)
6952 int same = pic16_sameRegs(AOP(result), AOP(left));
6955 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
6957 if (same && (offl != offr)) { // shift bytes
6960 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
6961 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
6963 } else { // just treat as different later on
6976 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6977 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6978 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6982 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6983 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6989 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6990 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6991 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6992 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6993 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6994 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6995 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6997 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6998 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7002 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7003 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7004 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7005 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7006 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7007 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7008 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7009 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7010 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7011 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7014 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7015 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7016 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7017 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7018 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7028 /* note, use a mov/add for the shift since the mov has a
7029 chance of getting optimized out */
7030 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7031 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7032 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7033 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7034 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7038 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7039 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7045 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7046 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7047 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7048 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7049 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7050 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7051 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7052 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7056 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7057 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7061 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7062 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7063 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7064 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7066 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7067 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7068 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7069 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7070 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7071 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7072 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7073 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7076 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7077 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7078 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7079 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7080 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7085 /*-----------------------------------------------------------------*/
7086 /* shiftR2Left2Result - shift right two bytes from left to result */
7087 /*-----------------------------------------------------------------*/
7088 static void shiftR2Left2Result (operand *left, int offl,
7089 operand *result, int offr,
7090 int shCount, int sign)
7092 int same = pic16_sameRegs(AOP(result), AOP(left));
7094 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7096 if (same && (offl != offr)) { // shift right bytes
7099 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7100 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7102 } else { // just treat as different later on
7114 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7119 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7120 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7122 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7123 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7124 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7125 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7130 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7133 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7134 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7141 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7142 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7143 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7145 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7146 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7147 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7148 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7150 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7151 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7152 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7154 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7155 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7156 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7157 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7158 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7162 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7163 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7167 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7168 pic16_emitpcode(POC_BTFSC,
7169 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7170 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7178 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7179 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7181 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7182 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7183 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7184 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7186 pic16_emitpcode(POC_BTFSC,
7187 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7188 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7190 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7191 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7192 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7193 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7195 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7196 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7197 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7198 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7199 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7200 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7201 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7202 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7204 pic16_emitpcode(POC_BTFSC,
7205 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7206 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7208 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7209 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7216 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7217 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7218 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7219 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7222 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7224 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7229 /*-----------------------------------------------------------------*/
7230 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7231 /*-----------------------------------------------------------------*/
7232 static void shiftLLeftOrResult (operand *left, int offl,
7233 operand *result, int offr, int shCount)
7235 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7237 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7238 /* shift left accumulator */
7240 /* or with result */
7241 /* back to result */
7242 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7245 /*-----------------------------------------------------------------*/
7246 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7247 /*-----------------------------------------------------------------*/
7248 static void shiftRLeftOrResult (operand *left, int offl,
7249 operand *result, int offr, int shCount)
7251 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7253 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7254 /* shift right accumulator */
7256 /* or with result */
7257 /* back to result */
7258 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7261 /*-----------------------------------------------------------------*/
7262 /* genlshOne - left shift a one byte quantity by known count */
7263 /*-----------------------------------------------------------------*/
7264 static void genlshOne (operand *result, operand *left, int shCount)
7266 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7267 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7270 /*-----------------------------------------------------------------*/
7271 /* genlshTwo - left shift two bytes by known amount != 0 */
7272 /*-----------------------------------------------------------------*/
7273 static void genlshTwo (operand *result,operand *left, int shCount)
7277 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7278 size = pic16_getDataSize(result);
7280 /* if shCount >= 8 */
7286 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7288 movLeft2Result(left, LSB, result, MSB16);
7290 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7293 /* 1 <= shCount <= 7 */
7296 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7298 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7302 /*-----------------------------------------------------------------*/
7303 /* shiftLLong - shift left one long from left to result */
7304 /* offr = LSB or MSB16 */
7305 /*-----------------------------------------------------------------*/
7306 static void shiftLLong (operand *left, operand *result, int offr )
7308 int size = AOP_SIZE(result);
7309 int same = pic16_sameRegs(AOP(left),AOP(result));
7312 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7314 if (same && (offr == MSB16)) { //shift one byte
7315 for(i=size-1;i>=MSB16;i--) {
7316 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7317 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7320 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7323 if (size >= LSB+offr ){
7325 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7327 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7328 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7332 if(size >= MSB16+offr){
7334 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7336 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7337 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7341 if(size >= MSB24+offr){
7343 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7345 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7346 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7350 if(size > MSB32+offr){
7352 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7354 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7355 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7359 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7363 /*-----------------------------------------------------------------*/
7364 /* genlshFour - shift four byte by a known amount != 0 */
7365 /*-----------------------------------------------------------------*/
7366 static void genlshFour (operand *result, operand *left, int shCount)
7370 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7371 size = AOP_SIZE(result);
7373 /* if shifting more that 3 bytes */
7374 if (shCount >= 24 ) {
7377 /* lowest order of left goes to the highest
7378 order of the destination */
7379 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7381 movLeft2Result(left, LSB, result, MSB32);
7383 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7384 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7385 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7390 /* more than two bytes */
7391 else if ( shCount >= 16 ) {
7392 /* lower order two bytes goes to higher order two bytes */
7394 /* if some more remaining */
7396 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7398 movLeft2Result(left, MSB16, result, MSB32);
7399 movLeft2Result(left, LSB, result, MSB24);
7401 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7402 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7406 /* if more than 1 byte */
7407 else if ( shCount >= 8 ) {
7408 /* lower order three bytes goes to higher order three bytes */
7412 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7414 movLeft2Result(left, LSB, result, MSB16);
7416 else{ /* size = 4 */
7418 movLeft2Result(left, MSB24, result, MSB32);
7419 movLeft2Result(left, MSB16, result, MSB24);
7420 movLeft2Result(left, LSB, result, MSB16);
7421 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7423 else if(shCount == 1)
7424 shiftLLong(left, result, MSB16);
7426 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7427 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7428 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7429 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7434 /* 1 <= shCount <= 7 */
7435 else if(shCount <= 3)
7437 shiftLLong(left, result, LSB);
7438 while(--shCount >= 1)
7439 shiftLLong(result, result, LSB);
7441 /* 3 <= shCount <= 7, optimize */
7443 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7444 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7445 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7449 /*-----------------------------------------------------------------*/
7450 /* genLeftShiftLiteral - left shifting by known count */
7451 /*-----------------------------------------------------------------*/
7452 static void genLeftShiftLiteral (operand *left,
7457 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7460 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7461 pic16_freeAsmop(right,NULL,ic,TRUE);
7463 pic16_aopOp(left,ic,FALSE);
7464 pic16_aopOp(result,ic,FALSE);
7466 size = getSize(operandType(result));
7469 pic16_emitcode("; shift left ","result %d, left %d",size,
7473 /* I suppose that the left size >= result size */
7476 movLeft2Result(left, size, result, size);
7480 else if(shCount >= (size * 8))
7482 pic16_aopPut(AOP(result),zero,size);
7486 genlshOne (result,left,shCount);
7491 genlshTwo (result,left,shCount);
7495 genlshFour (result,left,shCount);
7499 pic16_freeAsmop(left,NULL,ic,TRUE);
7500 pic16_freeAsmop(result,NULL,ic,TRUE);
7503 /*-----------------------------------------------------------------*
7504 * genMultiAsm - repeat assembly instruction for size of register.
7505 * if endian == 1, then the high byte (i.e base address + size of
7506 * register) is used first else the low byte is used first;
7507 *-----------------------------------------------------------------*/
7508 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7513 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7526 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7531 /*-----------------------------------------------------------------*/
7532 /* genLeftShift - generates code for left shifting */
7533 /*-----------------------------------------------------------------*/
7534 static void genLeftShift (iCode *ic)
7536 operand *left,*right, *result;
7539 symbol *tlbl , *tlbl1;
7542 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7544 right = IC_RIGHT(ic);
7546 result = IC_RESULT(ic);
7548 pic16_aopOp(right,ic,FALSE);
7550 /* if the shift count is known then do it
7551 as efficiently as possible */
7552 if (AOP_TYPE(right) == AOP_LIT) {
7553 genLeftShiftLiteral (left,right,result,ic);
7557 /* shift count is unknown then we have to form
7558 a loop get the loop count in B : Note: we take
7559 only the lower order byte since shifting
7560 more that 32 bits make no sense anyway, ( the
7561 largest size of an object can be only 32 bits ) */
7564 pic16_aopOp(left,ic,FALSE);
7565 pic16_aopOp(result,ic,FALSE);
7567 /* now move the left to the result if they are not the
7569 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7570 AOP_SIZE(result) > 1) {
7572 size = AOP_SIZE(result);
7575 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7576 if (*l == '@' && (IS_AOP_PREG(result))) {
7578 pic16_emitcode("mov","a,%s",l);
7579 pic16_aopPut(AOP(result),"a",offset);
7581 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7582 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7583 //pic16_aopPut(AOP(result),l,offset);
7589 size = AOP_SIZE(result);
7591 /* if it is only one byte then */
7593 if(optimized_for_speed) {
7594 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7595 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7596 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7597 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7598 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7599 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7600 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7601 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7602 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7603 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7604 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7605 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7608 tlbl = newiTempLabel(NULL);
7609 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7610 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7611 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7614 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7615 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7616 pic16_emitpLabel(tlbl->key);
7617 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7618 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7620 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7625 if (pic16_sameRegs(AOP(left),AOP(result))) {
7627 tlbl = newiTempLabel(NULL);
7628 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7629 genMultiAsm(POC_RRCF, result, size,1);
7630 pic16_emitpLabel(tlbl->key);
7631 genMultiAsm(POC_RLCF, result, size,0);
7632 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7634 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7638 //tlbl = newiTempLabel(NULL);
7640 //tlbl1 = newiTempLabel(NULL);
7642 //reAdjustPreg(AOP(result));
7644 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7645 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7646 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7648 //pic16_emitcode("add","a,acc");
7649 //pic16_aopPut(AOP(result),"a",offset++);
7651 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7653 // pic16_emitcode("rlc","a");
7654 // pic16_aopPut(AOP(result),"a",offset++);
7656 //reAdjustPreg(AOP(result));
7658 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7659 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7662 tlbl = newiTempLabel(NULL);
7663 tlbl1= newiTempLabel(NULL);
7665 size = AOP_SIZE(result);
7668 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7670 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7672 /* offset should be 0, 1 or 3 */
7674 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
7676 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7678 pic16_emitpcode(POC_MOVWF, pctemp);
7681 pic16_emitpLabel(tlbl->key);
7684 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7686 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7688 pic16_emitpcode(POC_DECFSZ, pctemp);
7689 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7690 pic16_emitpLabel(tlbl1->key);
7692 pic16_popReleaseTempReg(pctemp);
7696 pic16_freeAsmop (right,NULL,ic,TRUE);
7697 pic16_freeAsmop(left,NULL,ic,TRUE);
7698 pic16_freeAsmop(result,NULL,ic,TRUE);
7701 /*-----------------------------------------------------------------*/
7702 /* genrshOne - right shift a one byte quantity by known count */
7703 /*-----------------------------------------------------------------*/
7704 static void genrshOne (operand *result, operand *left,
7705 int shCount, int sign)
7707 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7708 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7711 /*-----------------------------------------------------------------*/
7712 /* genrshTwo - right shift two bytes by known amount != 0 */
7713 /*-----------------------------------------------------------------*/
7714 static void genrshTwo (operand *result,operand *left,
7715 int shCount, int sign)
7717 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7718 /* if shCount >= 8 */
7722 shiftR1Left2Result(left, MSB16, result, LSB,
7725 movLeft2Result(left, MSB16, result, LSB);
7727 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7730 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7731 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7735 /* 1 <= shCount <= 7 */
7737 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7740 /*-----------------------------------------------------------------*/
7741 /* shiftRLong - shift right one long from left to result */
7742 /* offl = LSB or MSB16 */
7743 /*-----------------------------------------------------------------*/
7744 static void shiftRLong (operand *left, int offl,
7745 operand *result, int sign)
7747 int size = AOP_SIZE(result);
7748 int same = pic16_sameRegs(AOP(left),AOP(result));
7750 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
7752 if (same && (offl == MSB16)) { //shift one byte right
7753 for(i=MSB16;i<size;i++) {
7754 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
7755 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
7760 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
7766 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
7768 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
7769 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
7773 /* add sign of "a" */
7774 pic16_addSign(result, MSB32, sign);
7778 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
7780 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
7781 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
7785 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
7787 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
7788 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
7792 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
7795 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
7796 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
7801 /*-----------------------------------------------------------------*/
7802 /* genrshFour - shift four byte by a known amount != 0 */
7803 /*-----------------------------------------------------------------*/
7804 static void genrshFour (operand *result, operand *left,
7805 int shCount, int sign)
7807 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7808 /* if shifting more that 3 bytes */
7809 if(shCount >= 24 ) {
7812 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7814 movLeft2Result(left, MSB32, result, LSB);
7816 pic16_addSign(result, MSB16, sign);
7818 else if(shCount >= 16){
7821 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7823 movLeft2Result(left, MSB24, result, LSB);
7824 movLeft2Result(left, MSB32, result, MSB16);
7826 pic16_addSign(result, MSB24, sign);
7828 else if(shCount >= 8){
7831 shiftRLong(left, MSB16, result, sign);
7832 else if(shCount == 0){
7833 movLeft2Result(left, MSB16, result, LSB);
7834 movLeft2Result(left, MSB24, result, MSB16);
7835 movLeft2Result(left, MSB32, result, MSB24);
7836 pic16_addSign(result, MSB32, sign);
7838 else{ //shcount >= 2
7839 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7840 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7841 /* the last shift is signed */
7842 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7843 pic16_addSign(result, MSB32, sign);
7846 else{ /* 1 <= shCount <= 7 */
7848 shiftRLong(left, LSB, result, sign);
7850 shiftRLong(result, LSB, result, sign);
7853 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7854 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7855 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7860 /*-----------------------------------------------------------------*/
7861 /* genRightShiftLiteral - right shifting by known count */
7862 /*-----------------------------------------------------------------*/
7863 static void genRightShiftLiteral (operand *left,
7869 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7872 pic16_freeAsmop(right,NULL,ic,TRUE);
7874 pic16_aopOp(left,ic,FALSE);
7875 pic16_aopOp(result,ic,FALSE);
7877 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
7880 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7884 lsize = pic16_getDataSize(left);
7885 res_size = pic16_getDataSize(result);
7886 /* test the LEFT size !!! */
7888 /* I suppose that the left size >= result size */
7891 movLeft2Result(left, lsize, result, res_size);
7894 else if(shCount >= (lsize * 8)){
7897 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7899 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7900 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7905 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7906 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7907 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7909 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7914 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7921 genrshOne (result,left,shCount,sign);
7925 genrshTwo (result,left,shCount,sign);
7929 genrshFour (result,left,shCount,sign);
7937 pic16_freeAsmop(left,NULL,ic,TRUE);
7938 pic16_freeAsmop(result,NULL,ic,TRUE);
7941 /*-----------------------------------------------------------------*/
7942 /* genSignedRightShift - right shift of signed number */
7943 /*-----------------------------------------------------------------*/
7944 static void genSignedRightShift (iCode *ic)
7946 operand *right, *left, *result;
7949 symbol *tlbl, *tlbl1 ;
7952 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7954 /* we do it the hard way put the shift count in b
7955 and loop thru preserving the sign */
7956 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7958 right = IC_RIGHT(ic);
7960 result = IC_RESULT(ic);
7962 pic16_aopOp(right,ic,FALSE);
7963 pic16_aopOp(left,ic,FALSE);
7964 pic16_aopOp(result,ic,FALSE);
7967 if ( AOP_TYPE(right) == AOP_LIT) {
7968 genRightShiftLiteral (left,right,result,ic,1);
7971 /* shift count is unknown then we have to form
7972 a loop get the loop count in B : Note: we take
7973 only the lower order byte since shifting
7974 more that 32 bits make no sense anyway, ( the
7975 largest size of an object can be only 32 bits ) */
7977 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7978 //pic16_emitcode("inc","b");
7979 //pic16_freeAsmop (right,NULL,ic,TRUE);
7980 //pic16_aopOp(left,ic,FALSE);
7981 //pic16_aopOp(result,ic,FALSE);
7983 /* now move the left to the result if they are not the
7985 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7986 AOP_SIZE(result) > 1) {
7988 size = AOP_SIZE(result);
7992 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7993 if (*l == '@' && IS_AOP_PREG(result)) {
7995 pic16_emitcode("mov","a,%s",l);
7996 pic16_aopPut(AOP(result),"a",offset);
7998 pic16_aopPut(AOP(result),l,offset);
8000 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8001 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8007 /* mov the highest order bit to OVR */
8008 tlbl = newiTempLabel(NULL);
8009 tlbl1= newiTempLabel(NULL);
8011 size = AOP_SIZE(result);
8014 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8016 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8018 /* offset should be 0, 1 or 3 */
8019 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8021 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8023 pic16_emitpcode(POC_MOVWF, pctemp);
8026 pic16_emitpLabel(tlbl->key);
8028 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8029 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8032 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8035 pic16_emitpcode(POC_DECFSZ, pctemp);
8036 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8037 pic16_emitpLabel(tlbl1->key);
8039 pic16_popReleaseTempReg(pctemp);
8041 size = AOP_SIZE(result);
8043 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8044 pic16_emitcode("rlc","a");
8045 pic16_emitcode("mov","ov,c");
8046 /* if it is only one byte then */
8048 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8050 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8051 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8052 pic16_emitcode("mov","c,ov");
8053 pic16_emitcode("rrc","a");
8054 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8055 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8056 pic16_aopPut(AOP(result),"a",0);
8060 reAdjustPreg(AOP(result));
8061 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8062 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8063 pic16_emitcode("mov","c,ov");
8065 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8067 pic16_emitcode("rrc","a");
8068 pic16_aopPut(AOP(result),"a",offset--);
8070 reAdjustPreg(AOP(result));
8071 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8072 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8077 pic16_freeAsmop(left,NULL,ic,TRUE);
8078 pic16_freeAsmop(result,NULL,ic,TRUE);
8079 pic16_freeAsmop(right,NULL,ic,TRUE);
8082 /*-----------------------------------------------------------------*/
8083 /* genRightShift - generate code for right shifting */
8084 /*-----------------------------------------------------------------*/
8085 static void genRightShift (iCode *ic)
8087 operand *right, *left, *result;
8091 symbol *tlbl, *tlbl1 ;
8093 /* if signed then we do it the hard way preserve the
8094 sign bit moving it inwards */
8095 letype = getSpec(operandType(IC_LEFT(ic)));
8096 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8098 if (!SPEC_USIGN(letype)) {
8099 genSignedRightShift (ic);
8103 /* signed & unsigned types are treated the same : i.e. the
8104 signed is NOT propagated inwards : quoting from the
8105 ANSI - standard : "for E1 >> E2, is equivalent to division
8106 by 2**E2 if unsigned or if it has a non-negative value,
8107 otherwise the result is implementation defined ", MY definition
8108 is that the sign does not get propagated */
8110 right = IC_RIGHT(ic);
8112 result = IC_RESULT(ic);
8114 pic16_aopOp(right,ic,FALSE);
8116 /* if the shift count is known then do it
8117 as efficiently as possible */
8118 if (AOP_TYPE(right) == AOP_LIT) {
8119 genRightShiftLiteral (left,right,result,ic, 0);
8123 /* shift count is unknown then we have to form
8124 a loop get the loop count in B : Note: we take
8125 only the lower order byte since shifting
8126 more that 32 bits make no sense anyway, ( the
8127 largest size of an object can be only 32 bits ) */
8129 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8130 pic16_emitcode("inc","b");
8131 pic16_aopOp(left,ic,FALSE);
8132 pic16_aopOp(result,ic,FALSE);
8134 /* now move the left to the result if they are not the
8136 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8137 AOP_SIZE(result) > 1) {
8139 size = AOP_SIZE(result);
8142 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8143 if (*l == '@' && IS_AOP_PREG(result)) {
8145 pic16_emitcode("mov","a,%s",l);
8146 pic16_aopPut(AOP(result),"a",offset);
8148 pic16_aopPut(AOP(result),l,offset);
8153 tlbl = newiTempLabel(NULL);
8154 tlbl1= newiTempLabel(NULL);
8155 size = AOP_SIZE(result);
8158 /* if it is only one byte then */
8161 tlbl = newiTempLabel(NULL);
8162 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8163 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8164 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8167 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8168 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8169 pic16_emitpLabel(tlbl->key);
8170 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8171 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8173 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8178 reAdjustPreg(AOP(result));
8179 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8180 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8183 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8185 pic16_emitcode("rrc","a");
8186 pic16_aopPut(AOP(result),"a",offset--);
8188 reAdjustPreg(AOP(result));
8190 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8191 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8194 pic16_freeAsmop(left,NULL,ic,TRUE);
8195 pic16_freeAsmop (right,NULL,ic,TRUE);
8196 pic16_freeAsmop(result,NULL,ic,TRUE);
8199 /*-----------------------------------------------------------------*/
8200 /* genUnpackBits - generates code for unpacking bits */
8201 /*-----------------------------------------------------------------*/
8202 static void genUnpackBits (operand *result, char *rname, int ptype)
8209 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8210 etype = getSpec(operandType(result));
8212 /* read the first byte */
8217 pic16_emitcode("mov","a,@%s",rname);
8221 pic16_emitcode("movx","a,@%s",rname);
8225 pic16_emitcode("movx","a,@dptr");
8229 pic16_emitcode("clr","a");
8230 pic16_emitcode("movc","a","@a+dptr");
8234 pic16_emitcode("lcall","__gptrget");
8238 /* if we have bitdisplacement then it fits */
8239 /* into this byte completely or if length is */
8240 /* less than a byte */
8241 if ((shCnt = SPEC_BSTR(etype)) ||
8242 (SPEC_BLEN(etype) <= 8)) {
8244 /* shift right acc */
8247 pic16_emitcode("anl","a,#0x%02x",
8248 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8249 pic16_aopPut(AOP(result),"a",offset);
8253 /* bit field did not fit in a byte */
8254 rlen = SPEC_BLEN(etype) - 8;
8255 pic16_aopPut(AOP(result),"a",offset++);
8262 pic16_emitcode("inc","%s",rname);
8263 pic16_emitcode("mov","a,@%s",rname);
8267 pic16_emitcode("inc","%s",rname);
8268 pic16_emitcode("movx","a,@%s",rname);
8272 pic16_emitcode("inc","dptr");
8273 pic16_emitcode("movx","a,@dptr");
8277 pic16_emitcode("clr","a");
8278 pic16_emitcode("inc","dptr");
8279 pic16_emitcode("movc","a","@a+dptr");
8283 pic16_emitcode("inc","dptr");
8284 pic16_emitcode("lcall","__gptrget");
8289 /* if we are done */
8293 pic16_aopPut(AOP(result),"a",offset++);
8298 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8299 pic16_aopPut(AOP(result),"a",offset);
8306 /*-----------------------------------------------------------------*/
8307 /* genDataPointerGet - generates code when ptr offset is known */
8308 /*-----------------------------------------------------------------*/
8309 static void genDataPointerGet (operand *left,
8313 int size , offset = 0;
8316 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8319 /* optimization - most of the time, left and result are the same
8320 * address, but different types. for the pic code, we could omit
8324 pic16_aopOp(result,ic,TRUE);
8326 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8328 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8330 size = AOP_SIZE(result);
8333 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8337 pic16_freeAsmop(left,NULL,ic,TRUE);
8338 pic16_freeAsmop(result,NULL,ic,TRUE);
8341 /*-----------------------------------------------------------------*/
8342 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8343 /*-----------------------------------------------------------------*/
8344 static void genNearPointerGet (operand *left,
8349 //regs *preg = NULL ;
8351 sym_link *rtype, *retype;
8352 sym_link *ltype = operandType(left);
8355 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8357 rtype = operandType(result);
8358 retype= getSpec(rtype);
8360 pic16_aopOp(left,ic,FALSE);
8362 /* if left is rematerialisable and
8363 result is not bit variable type and
8364 the left is pointer to data space i.e
8365 lower 128 bytes of space */
8366 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8367 !IS_BITVAR(retype) &&
8368 DCL_TYPE(ltype) == POINTER) {
8369 //genDataPointerGet (left,result,ic);
8373 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8375 /* if the value is already in a pointer register
8376 then don't need anything more */
8377 if (!AOP_INPREG(AOP(left))) {
8378 /* otherwise get a free pointer register */
8379 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8382 preg = getFreePtr(ic,&aop,FALSE);
8383 pic16_emitcode("mov","%s,%s",
8385 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8386 rname = preg->name ;
8390 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8392 pic16_aopOp (result,ic,FALSE);
8394 /* if bitfield then unpack the bits */
8395 if (IS_BITFIELD(retype))
8396 genUnpackBits (result,rname,POINTER);
8398 /* we have can just get the values */
8399 int size = AOP_SIZE(result);
8402 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8404 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8405 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8407 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8408 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8410 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8414 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8416 pic16_emitcode("mov","a,@%s",rname);
8417 pic16_aopPut(AOP(result),"a",offset);
8419 sprintf(buffer,"@%s",rname);
8420 pic16_aopPut(AOP(result),buffer,offset);
8424 pic16_emitcode("inc","%s",rname);
8429 /* now some housekeeping stuff */
8431 /* we had to allocate for this iCode */
8432 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8433 pic16_freeAsmop(NULL,aop,ic,TRUE);
8435 /* we did not allocate which means left
8436 already in a pointer register, then
8437 if size > 0 && this could be used again
8438 we have to point it back to where it
8440 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8441 if (AOP_SIZE(result) > 1 &&
8442 !OP_SYMBOL(left)->remat &&
8443 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8445 int size = AOP_SIZE(result) - 1;
8447 pic16_emitcode("dec","%s",rname);
8452 pic16_freeAsmop(left,NULL,ic,TRUE);
8453 pic16_freeAsmop(result,NULL,ic,TRUE);
8457 /*-----------------------------------------------------------------*/
8458 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8459 /*-----------------------------------------------------------------*/
8460 static void genPagedPointerGet (operand *left,
8467 sym_link *rtype, *retype;
8469 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8471 rtype = operandType(result);
8472 retype= getSpec(rtype);
8474 pic16_aopOp(left,ic,FALSE);
8476 /* if the value is already in a pointer register
8477 then don't need anything more */
8478 if (!AOP_INPREG(AOP(left))) {
8479 /* otherwise get a free pointer register */
8481 preg = getFreePtr(ic,&aop,FALSE);
8482 pic16_emitcode("mov","%s,%s",
8484 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8485 rname = preg->name ;
8487 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8489 pic16_freeAsmop(left,NULL,ic,TRUE);
8490 pic16_aopOp (result,ic,FALSE);
8492 /* if bitfield then unpack the bits */
8493 if (IS_BITFIELD(retype))
8494 genUnpackBits (result,rname,PPOINTER);
8496 /* we have can just get the values */
8497 int size = AOP_SIZE(result);
8502 pic16_emitcode("movx","a,@%s",rname);
8503 pic16_aopPut(AOP(result),"a",offset);
8508 pic16_emitcode("inc","%s",rname);
8512 /* now some housekeeping stuff */
8514 /* we had to allocate for this iCode */
8515 pic16_freeAsmop(NULL,aop,ic,TRUE);
8517 /* we did not allocate which means left
8518 already in a pointer register, then
8519 if size > 0 && this could be used again
8520 we have to point it back to where it
8522 if (AOP_SIZE(result) > 1 &&
8523 !OP_SYMBOL(left)->remat &&
8524 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8526 int size = AOP_SIZE(result) - 1;
8528 pic16_emitcode("dec","%s",rname);
8533 pic16_freeAsmop(result,NULL,ic,TRUE);
8538 /*-----------------------------------------------------------------*/
8539 /* genFarPointerGet - gget value from far space */
8540 /*-----------------------------------------------------------------*/
8541 static void genFarPointerGet (operand *left,
8542 operand *result, iCode *ic)
8545 sym_link *retype = getSpec(operandType(result));
8547 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8549 pic16_aopOp(left,ic,FALSE);
8551 /* if the operand is already in dptr
8552 then we do nothing else we move the value to dptr */
8553 if (AOP_TYPE(left) != AOP_STR) {
8554 /* if this is remateriazable */
8555 if (AOP_TYPE(left) == AOP_IMMD)
8556 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8557 else { /* we need to get it byte by byte */
8558 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8559 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8560 if (options.model == MODEL_FLAT24)
8562 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8566 /* so dptr know contains the address */
8567 pic16_freeAsmop(left,NULL,ic,TRUE);
8568 pic16_aopOp(result,ic,FALSE);
8570 /* if bit then unpack */
8571 if (IS_BITFIELD(retype))
8572 genUnpackBits(result,"dptr",FPOINTER);
8574 size = AOP_SIZE(result);
8578 pic16_emitcode("movx","a,@dptr");
8579 pic16_aopPut(AOP(result),"a",offset++);
8581 pic16_emitcode("inc","dptr");
8585 pic16_freeAsmop(result,NULL,ic,TRUE);
8588 /*-----------------------------------------------------------------*/
8589 /* genCodePointerGet - get value from code space */
8590 /*-----------------------------------------------------------------*/
8591 static void genCodePointerGet (operand *left,
8592 operand *result, iCode *ic)
8595 sym_link *retype = getSpec(operandType(result));
8597 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8599 pic16_aopOp(left,ic,FALSE);
8601 /* if the operand is already in dptr
8602 then we do nothing else we move the value to dptr */
8603 if (AOP_TYPE(left) != AOP_STR) {
8604 /* if this is remateriazable */
8605 if (AOP_TYPE(left) == AOP_IMMD)
8606 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8607 else { /* we need to get it byte by byte */
8608 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8609 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8610 if (options.model == MODEL_FLAT24)
8612 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8616 /* so dptr know contains the address */
8617 pic16_freeAsmop(left,NULL,ic,TRUE);
8618 pic16_aopOp(result,ic,FALSE);
8620 /* if bit then unpack */
8621 if (IS_BITFIELD(retype))
8622 genUnpackBits(result,"dptr",CPOINTER);
8624 size = AOP_SIZE(result);
8628 pic16_emitcode("clr","a");
8629 pic16_emitcode("movc","a,@a+dptr");
8630 pic16_aopPut(AOP(result),"a",offset++);
8632 pic16_emitcode("inc","dptr");
8636 pic16_freeAsmop(result,NULL,ic,TRUE);
8639 /*-----------------------------------------------------------------*/
8640 /* genGenPointerGet - gget value from generic pointer space */
8641 /*-----------------------------------------------------------------*/
8642 static void genGenPointerGet (operand *left,
8643 operand *result, iCode *ic)
8645 int size, offset, lit;
8646 sym_link *retype = getSpec(operandType(result));
8648 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8649 pic16_aopOp(left,ic,FALSE);
8650 pic16_aopOp(result,ic,FALSE);
8651 size = AOP_SIZE(result);
8653 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8655 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
8657 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
8658 // load FSR0 from immediate
8659 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
8663 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8665 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8672 else { /* we need to get it byte by byte */
8673 // set up FSR0 with address from left
8674 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
8675 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
8681 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
8683 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
8690 /* if bit then unpack */
8691 if (IS_BITFIELD(retype))
8692 genUnpackBits(result,"BAD",GPOINTER);
8695 pic16_freeAsmop(left,NULL,ic,TRUE);
8696 pic16_freeAsmop(result,NULL,ic,TRUE);
8700 /*-----------------------------------------------------------------*/
8701 /* genConstPointerGet - get value from const generic pointer space */
8702 /*-----------------------------------------------------------------*/
8703 static void genConstPointerGet (operand *left,
8704 operand *result, iCode *ic)
8706 //sym_link *retype = getSpec(operandType(result));
8707 symbol *albl = newiTempLabel(NULL);
8708 symbol *blbl = newiTempLabel(NULL);
8711 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8712 pic16_aopOp(left,ic,FALSE);
8713 pic16_aopOp(result,ic,FALSE);
8716 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8718 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8720 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8721 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8722 pic16_emitpLabel(albl->key);
8724 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8726 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8727 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8728 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8729 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8730 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8732 pic16_emitpLabel(blbl->key);
8734 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8737 pic16_freeAsmop(left,NULL,ic,TRUE);
8738 pic16_freeAsmop(result,NULL,ic,TRUE);
8741 /*-----------------------------------------------------------------*/
8742 /* genPointerGet - generate code for pointer get */
8743 /*-----------------------------------------------------------------*/
8744 static void genPointerGet (iCode *ic)
8746 operand *left, *result ;
8747 sym_link *type, *etype;
8750 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8753 result = IC_RESULT(ic) ;
8755 /* depending on the type of pointer we need to
8756 move it to the correct pointer register */
8757 type = operandType(left);
8758 etype = getSpec(type);
8761 if (IS_PTR_CONST(type))
8763 if (IS_CODEPTR(type))
8765 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8767 /* if left is of type of pointer then it is simple */
8768 if (IS_PTR(type) && !IS_FUNC(type->next))
8769 p_type = DCL_TYPE(type);
8771 /* we have to go by the storage class */
8772 p_type = PTR_TYPE(SPEC_OCLS(etype));
8774 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8776 if (SPEC_OCLS(etype)->codesp ) {
8777 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8778 //p_type = CPOINTER ;
8781 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8782 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8783 /*p_type = FPOINTER ;*/
8785 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8786 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8787 /* p_type = PPOINTER; */
8789 if (SPEC_OCLS(etype) == idata )
8790 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8791 /* p_type = IPOINTER; */
8793 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8794 /* p_type = POINTER ; */
8797 /* now that we have the pointer type we assign
8798 the pointer values */
8803 genNearPointerGet (left,result,ic);
8807 genPagedPointerGet(left,result,ic);
8811 genFarPointerGet (left,result,ic);
8815 genConstPointerGet (left,result,ic);
8816 //pic16_emitcodePointerGet (left,result,ic);
8821 if (IS_PTR_CONST(type))
8822 genConstPointerGet (left,result,ic);
8825 genGenPointerGet (left,result,ic);
8831 /*-----------------------------------------------------------------*/
8832 /* genPackBits - generates code for packed bit storage */
8833 /*-----------------------------------------------------------------*/
8834 static void genPackBits (sym_link *etype ,
8836 char *rname, int p_type)
8844 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8845 blen = SPEC_BLEN(etype);
8846 bstr = SPEC_BSTR(etype);
8848 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8851 /* if the bit lenth is less than or */
8852 /* it exactly fits a byte then */
8853 if (SPEC_BLEN(etype) <= 8 ) {
8854 shCount = SPEC_BSTR(etype) ;
8856 /* shift left acc */
8859 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8864 pic16_emitcode ("mov","b,a");
8865 pic16_emitcode("mov","a,@%s",rname);
8869 pic16_emitcode ("mov","b,a");
8870 pic16_emitcode("movx","a,@dptr");
8874 pic16_emitcode ("push","b");
8875 pic16_emitcode ("push","acc");
8876 pic16_emitcode ("lcall","__gptrget");
8877 pic16_emitcode ("pop","b");
8881 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8882 ((unsigned char)(0xFF << (blen+bstr)) |
8883 (unsigned char)(0xFF >> (8-bstr)) ) );
8884 pic16_emitcode ("orl","a,b");
8885 if (p_type == GPOINTER)
8886 pic16_emitcode("pop","b");
8892 pic16_emitcode("mov","@%s,a",rname);
8896 pic16_emitcode("movx","@dptr,a");
8900 DEBUGpic16_emitcode(";lcall","__gptrput");
8905 if ( SPEC_BLEN(etype) <= 8 )
8908 pic16_emitcode("inc","%s",rname);
8909 rLen = SPEC_BLEN(etype) ;
8911 /* now generate for lengths greater than one byte */
8914 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8924 pic16_emitcode("mov","@%s,a",rname);
8926 pic16_emitcode("mov","@%s,%s",rname,l);
8931 pic16_emitcode("movx","@dptr,a");
8936 DEBUGpic16_emitcode(";lcall","__gptrput");
8939 pic16_emitcode ("inc","%s",rname);
8944 /* last last was not complete */
8946 /* save the byte & read byte */
8949 pic16_emitcode ("mov","b,a");
8950 pic16_emitcode("mov","a,@%s",rname);
8954 pic16_emitcode ("mov","b,a");
8955 pic16_emitcode("movx","a,@dptr");
8959 pic16_emitcode ("push","b");
8960 pic16_emitcode ("push","acc");
8961 pic16_emitcode ("lcall","__gptrget");
8962 pic16_emitcode ("pop","b");
8966 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8967 pic16_emitcode ("orl","a,b");
8970 if (p_type == GPOINTER)
8971 pic16_emitcode("pop","b");
8976 pic16_emitcode("mov","@%s,a",rname);
8980 pic16_emitcode("movx","@dptr,a");
8984 DEBUGpic16_emitcode(";lcall","__gptrput");
8988 /*-----------------------------------------------------------------*/
8989 /* genDataPointerSet - remat pointer to data space */
8990 /*-----------------------------------------------------------------*/
8991 static void genDataPointerSet(operand *right,
8995 int size, offset = 0 ;
8996 char *l, buffer[256];
8998 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8999 pic16_aopOp(right,ic,FALSE);
9001 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
9002 size = AOP_SIZE(right);
9004 if ( AOP_TYPE(result) == AOP_PCODE) {
9005 fprintf(stderr,"genDataPointerSet %s, %d\n",
9006 AOP(result)->aopu.pcop->name,
9007 PCOI(AOP(result)->aopu.pcop)->offset);
9011 // tsd, was l+1 - the underline `_' prefix was being stripped
9014 sprintf(buffer,"(%s + %d)",l,offset);
9015 fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer);
9017 sprintf(buffer,"%s",l);
9019 if (AOP_TYPE(right) == AOP_LIT) {
9020 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9021 lit = lit >> (8*offset);
9023 pic16_emitcode("movlw","%d",lit);
9024 pic16_emitcode("movwf","%s",buffer);
9026 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9027 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
9028 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9031 pic16_emitcode("clrf","%s",buffer);
9032 //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer));
9033 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9036 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
9037 pic16_emitcode("movwf","%s",buffer);
9039 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9040 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
9041 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9048 pic16_freeAsmop(right,NULL,ic,TRUE);
9049 pic16_freeAsmop(result,NULL,ic,TRUE);
9052 /*-----------------------------------------------------------------*/
9053 /* genNearPointerSet - pic16_emitcode for near pointer put */
9054 /*-----------------------------------------------------------------*/
9055 static void genNearPointerSet (operand *right,
9062 sym_link *ptype = operandType(result);
9065 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9066 retype= getSpec(operandType(right));
9068 pic16_aopOp(result,ic,FALSE);
9071 /* if the result is rematerializable &
9072 in data space & not a bit variable */
9073 //if (AOP_TYPE(result) == AOP_IMMD &&
9074 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
9075 DCL_TYPE(ptype) == POINTER &&
9076 !IS_BITVAR(retype)) {
9077 genDataPointerSet (right,result,ic);
9078 pic16_freeAsmop(result,NULL,ic,TRUE);
9082 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9083 pic16_aopOp(right,ic,FALSE);
9084 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9086 /* if the value is already in a pointer register
9087 then don't need anything more */
9088 if (!AOP_INPREG(AOP(result))) {
9089 /* otherwise get a free pointer register */
9090 //aop = newAsmop(0);
9091 //preg = getFreePtr(ic,&aop,FALSE);
9092 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9093 //pic16_emitcode("mov","%s,%s",
9095 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
9096 //rname = preg->name ;
9097 //pic16_emitcode("movwf","fsr0");
9098 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
9099 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
9100 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9101 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9105 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9107 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9109 /* if bitfield then unpack the bits */
9110 if (IS_BITFIELD(retype)) {
9111 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9112 "The programmer is obviously confused");
9113 // genPackBits (retype,right,"BAD",POINTER);
9117 /* we have can just get the values */
9118 int size = AOP_SIZE(right);
9121 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9123 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9126 //pic16_emitcode("mov","@%s,a",rname);
9127 pic16_emitcode("movf","indf0,w ;1");
9130 if (AOP_TYPE(right) == AOP_LIT) {
9131 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9133 pic16_emitcode("movlw","%s",l);
9134 pic16_emitcode("movwf","indf0 ;2");
9136 pic16_emitcode("clrf","indf0");
9138 pic16_emitcode("movf","%s,w",l);
9139 pic16_emitcode("movwf","indf0 ;2");
9141 //pic16_emitcode("mov","@%s,%s",rname,l);
9144 pic16_emitcode("incf","fsr0,f ;3");
9145 //pic16_emitcode("inc","%s",rname);
9150 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9151 /* now some housekeeping stuff */
9153 /* we had to allocate for this iCode */
9154 pic16_freeAsmop(NULL,aop,ic,TRUE);
9156 /* we did not allocate which means left
9157 already in a pointer register, then
9158 if size > 0 && this could be used again
9159 we have to point it back to where it
9161 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9162 if (AOP_SIZE(right) > 1 &&
9163 !OP_SYMBOL(result)->remat &&
9164 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9166 int size = AOP_SIZE(right) - 1;
9168 pic16_emitcode("decf","fsr0,f");
9169 //pic16_emitcode("dec","%s",rname);
9173 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9176 pic16_freeAsmop(right,NULL,ic,TRUE);
9177 pic16_freeAsmop(result,NULL,ic,TRUE);
9180 /*-----------------------------------------------------------------*/
9181 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9182 /*-----------------------------------------------------------------*/
9183 static void genPagedPointerSet (operand *right,
9192 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9194 retype= getSpec(operandType(right));
9196 pic16_aopOp(result,ic,FALSE);
9198 /* if the value is already in a pointer register
9199 then don't need anything more */
9200 if (!AOP_INPREG(AOP(result))) {
9201 /* otherwise get a free pointer register */
9203 preg = getFreePtr(ic,&aop,FALSE);
9204 pic16_emitcode("mov","%s,%s",
9206 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9207 rname = preg->name ;
9209 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9211 pic16_freeAsmop(result,NULL,ic,TRUE);
9212 pic16_aopOp (right,ic,FALSE);
9214 /* if bitfield then unpack the bits */
9215 if (IS_BITFIELD(retype))
9216 genPackBits (retype,right,rname,PPOINTER);
9218 /* we have can just get the values */
9219 int size = AOP_SIZE(right);
9223 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9226 pic16_emitcode("movx","@%s,a",rname);
9229 pic16_emitcode("inc","%s",rname);
9235 /* now some housekeeping stuff */
9237 /* we had to allocate for this iCode */
9238 pic16_freeAsmop(NULL,aop,ic,TRUE);
9240 /* we did not allocate which means left
9241 already in a pointer register, then
9242 if size > 0 && this could be used again
9243 we have to point it back to where it
9245 if (AOP_SIZE(right) > 1 &&
9246 !OP_SYMBOL(result)->remat &&
9247 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9249 int size = AOP_SIZE(right) - 1;
9251 pic16_emitcode("dec","%s",rname);
9256 pic16_freeAsmop(right,NULL,ic,TRUE);
9261 /*-----------------------------------------------------------------*/
9262 /* genFarPointerSet - set value from far space */
9263 /*-----------------------------------------------------------------*/
9264 static void genFarPointerSet (operand *right,
9265 operand *result, iCode *ic)
9268 sym_link *retype = getSpec(operandType(right));
9270 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9271 pic16_aopOp(result,ic,FALSE);
9273 /* if the operand is already in dptr
9274 then we do nothing else we move the value to dptr */
9275 if (AOP_TYPE(result) != AOP_STR) {
9276 /* if this is remateriazable */
9277 if (AOP_TYPE(result) == AOP_IMMD)
9278 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9279 else { /* we need to get it byte by byte */
9280 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9281 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9282 if (options.model == MODEL_FLAT24)
9284 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9288 /* so dptr know contains the address */
9289 pic16_freeAsmop(result,NULL,ic,TRUE);
9290 pic16_aopOp(right,ic,FALSE);
9292 /* if bit then unpack */
9293 if (IS_BITFIELD(retype))
9294 genPackBits(retype,right,"dptr",FPOINTER);
9296 size = AOP_SIZE(right);
9300 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9302 pic16_emitcode("movx","@dptr,a");
9304 pic16_emitcode("inc","dptr");
9308 pic16_freeAsmop(right,NULL,ic,TRUE);
9311 /*-----------------------------------------------------------------*/
9312 /* genGenPointerSet - set value from generic pointer space */
9313 /*-----------------------------------------------------------------*/
9314 static void genGenPointerSet (operand *right,
9315 operand *result, iCode *ic)
9317 int size, offset, lit;
9318 sym_link *retype = getSpec(operandType(right));
9320 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9322 pic16_aopOp(result,ic,FALSE);
9323 pic16_aopOp(right,ic,FALSE);
9324 size = AOP_SIZE(right);
9327 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9330 /* if the operand is already in dptr
9331 then we do nothing else we move the value to dptr */
9332 if (AOP_TYPE(result) != AOP_STR) {
9333 /* if this is remateriazable */
9334 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9335 // WARNING: anythig until "else" is untested!
9336 if (AOP_TYPE(result) == AOP_IMMD) {
9337 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9338 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
9339 // load FSR0 from immediate
9340 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9344 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9346 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9352 else { /* we need to get it byte by byte */
9353 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9354 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9356 // set up FSR0 with address of result
9357 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9358 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9360 /* hack hack! see if this the FSR. If so don't load W */
9361 if(AOP_TYPE(right) != AOP_ACC) {
9363 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9367 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9369 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9376 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9378 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9380 } // if (AOP_TYPE(result) != AOP_IMMD)
9382 } // if (AOP_TYPE(result) != AOP_STR)
9383 /* so dptr know contains the address */
9386 /* if bit then unpack */
9387 if (IS_BITFIELD(retype))
9388 genPackBits(retype,right,"dptr",GPOINTER);
9390 size = AOP_SIZE(right);
9393 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9395 // set up FSR0 with address of result
9396 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9397 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9400 if (AOP_TYPE(right) == AOP_LIT) {
9401 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9403 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
9405 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9407 } else { // no literal
9409 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
9411 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
9419 pic16_freeAsmop(right,NULL,ic,TRUE);
9420 pic16_freeAsmop(result,NULL,ic,TRUE);
9423 /*-----------------------------------------------------------------*/
9424 /* genPointerSet - stores the value into a pointer location */
9425 /*-----------------------------------------------------------------*/
9426 static void genPointerSet (iCode *ic)
9428 operand *right, *result ;
9429 sym_link *type, *etype;
9432 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9434 right = IC_RIGHT(ic);
9435 result = IC_RESULT(ic) ;
9437 /* depending on the type of pointer we need to
9438 move it to the correct pointer register */
9439 type = operandType(result);
9440 etype = getSpec(type);
9441 /* if left is of type of pointer then it is simple */
9442 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9443 p_type = DCL_TYPE(type);
9446 /* we have to go by the storage class */
9447 p_type = PTR_TYPE(SPEC_OCLS(etype));
9449 /* if (SPEC_OCLS(etype)->codesp ) { */
9450 /* p_type = CPOINTER ; */
9453 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9454 /* p_type = FPOINTER ; */
9456 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9457 /* p_type = PPOINTER ; */
9459 /* if (SPEC_OCLS(etype) == idata ) */
9460 /* p_type = IPOINTER ; */
9462 /* p_type = POINTER ; */
9465 /* now that we have the pointer type we assign
9466 the pointer values */
9471 genNearPointerSet (right,result,ic);
9475 genPagedPointerSet (right,result,ic);
9479 genFarPointerSet (right,result,ic);
9483 genGenPointerSet (right,result,ic);
9487 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9488 "genPointerSet: illegal pointer type");
9492 /*-----------------------------------------------------------------*/
9493 /* genIfx - generate code for Ifx statement */
9494 /*-----------------------------------------------------------------*/
9495 static void genIfx (iCode *ic, iCode *popIc)
9497 operand *cond = IC_COND(ic);
9500 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9502 pic16_aopOp(cond,ic,FALSE);
9504 /* get the value into acc */
9505 if (AOP_TYPE(cond) != AOP_CRY)
9506 pic16_toBoolean(cond);
9509 /* the result is now in the accumulator */
9510 pic16_freeAsmop(cond,NULL,ic,TRUE);
9512 /* if there was something to be popped then do it */
9516 /* if the condition is a bit variable */
9517 if (isbit && IS_ITEMP(cond) &&
9519 genIfxJump(ic,SPIL_LOC(cond)->rname);
9520 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9523 if (isbit && !IS_ITEMP(cond))
9524 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9532 /*-----------------------------------------------------------------*/
9533 /* genAddrOf - generates code for address of */
9534 /*-----------------------------------------------------------------*/
9536 static void genAddrOf (iCode *ic)
9538 operand *right, *result, *left;
9541 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9544 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9546 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9547 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9548 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9550 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9552 size = AOP_SIZE(IC_RESULT(ic));
9557 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9558 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9563 pic16_freeAsmop(left,NULL,ic,FALSE);
9564 pic16_freeAsmop(result,NULL,ic,TRUE);
9568 #else /* new genAddrOf */
9570 static void genAddrOf (iCode *ic)
9572 operand *result, *left;
9574 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9575 pCodeOp *pcop0, *pcop1, *pcop2;
9577 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9579 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9580 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9582 sym = OP_SYMBOL( left );
9584 size = AOP_SIZE(IC_RESULT(ic));
9586 if(pic16_debug_verbose) {
9587 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9588 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9591 /* Assume that what we want the address of is in data space
9592 * since there is no stack on the PIC, yet! -- VR */
9594 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9597 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9600 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9604 pic16_emitpcode(POC_MOVLW, pcop0);
9605 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9606 pic16_emitpcode(POC_MOVLW, pcop1);
9607 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9608 pic16_emitpcode(POC_MOVLW, pcop2);
9609 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9612 pic16_emitpcode(POC_MOVLW, pcop0);
9613 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9614 pic16_emitpcode(POC_MOVLW, pcop1);
9615 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9617 pic16_emitpcode(POC_MOVLW, pcop0);
9618 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9621 pic16_freeAsmop(result,NULL,ic,TRUE);
9622 pic16_freeAsmop(left, NULL, ic, FALSE);
9625 #endif /* new genAddrOf */
9628 /*-----------------------------------------------------------------*/
9629 /* genFarFarAssign - assignment when both are in far space */
9630 /*-----------------------------------------------------------------*/
9631 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9633 int size = AOP_SIZE(right);
9636 /* first push the right side on to the stack */
9638 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9640 pic16_emitcode ("push","acc");
9643 pic16_freeAsmop(right,NULL,ic,FALSE);
9644 /* now assign DPTR to result */
9645 pic16_aopOp(result,ic,FALSE);
9646 size = AOP_SIZE(result);
9648 pic16_emitcode ("pop","acc");
9649 pic16_aopPut(AOP(result),"a",--offset);
9651 pic16_freeAsmop(result,NULL,ic,FALSE);
9656 /*-----------------------------------------------------------------*/
9657 /* genAssign - generate code for assignment */
9658 /*-----------------------------------------------------------------*/
9659 static void genAssign (iCode *ic)
9661 operand *result, *right;
9662 int size, offset,know_W;
9663 unsigned long lit = 0L;
9665 result = IC_RESULT(ic);
9666 right = IC_RIGHT(ic) ;
9668 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9670 /* if they are the same */
9671 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9674 pic16_aopOp(right,ic,FALSE);
9675 pic16_aopOp(result,ic,TRUE);
9677 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9679 /* if they are the same registers */
9680 if (pic16_sameRegs(AOP(right),AOP(result)))
9683 /* if the result is a bit */
9684 if (AOP_TYPE(result) == AOP_CRY) {
9685 /* if the right size is a literal then
9686 we know what the value is */
9687 if (AOP_TYPE(right) == AOP_LIT) {
9689 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9690 pic16_popGet(AOP(result),0));
9692 if (((int) operandLitValue(right)))
9693 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9694 AOP(result)->aopu.aop_dir,
9695 AOP(result)->aopu.aop_dir);
9697 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9698 AOP(result)->aopu.aop_dir,
9699 AOP(result)->aopu.aop_dir);
9703 /* the right is also a bit variable */
9704 if (AOP_TYPE(right) == AOP_CRY) {
9705 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9706 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9707 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9709 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9710 AOP(result)->aopu.aop_dir,
9711 AOP(result)->aopu.aop_dir);
9712 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9713 AOP(right)->aopu.aop_dir,
9714 AOP(right)->aopu.aop_dir);
9715 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9716 AOP(result)->aopu.aop_dir,
9717 AOP(result)->aopu.aop_dir);
9722 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9723 pic16_toBoolean(right);
9725 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9726 //pic16_aopPut(AOP(result),"a",0);
9730 /* bit variables done */
9732 size = AOP_SIZE(result);
9734 if(AOP_TYPE(right) == AOP_LIT)
9735 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9737 /* VR - What is this?! */
9738 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9739 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9740 if(aopIdx(AOP(result),0) == 4) {
9741 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9742 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9743 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9746 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9751 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9752 if(AOP_TYPE(right) == AOP_LIT) {
9754 if(know_W != (lit&0xff))
9755 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9757 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9759 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9763 } else if (AOP_TYPE(right) == AOP_CRY) {
9764 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9766 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9767 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9770 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9773 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9774 normally should work, but mind that the W register live range
9775 is not checked, so if the code generator assumes that the W
9776 is already loaded after such a pair, wrong code will be generated.
9778 Checking the live range is the next step.
9779 This is experimental code yet and has not been fully tested yet.
9780 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9781 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9783 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9785 /* This is the old code, which is assumed(?!) that works fine(!?) */
9787 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9788 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9797 pic16_freeAsmop (right,NULL,ic,FALSE);
9798 pic16_freeAsmop (result,NULL,ic,TRUE);
9801 /*-----------------------------------------------------------------*/
9802 /* genJumpTab - generates code for jump table */
9803 /*-----------------------------------------------------------------*/
9804 static void genJumpTab (iCode *ic)
9809 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9811 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9812 /* get the condition into accumulator */
9813 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9815 /* multiply by three */
9816 pic16_emitcode("add","a,acc");
9817 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9819 jtab = newiTempLabel(NULL);
9820 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9821 pic16_emitcode("jmp","@a+dptr");
9822 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9824 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9825 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9827 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9828 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9829 pic16_emitpLabel(jtab->key);
9831 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9833 /* now generate the jump labels */
9834 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9835 jtab = setNextItem(IC_JTLABELS(ic))) {
9836 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9837 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9843 /*-----------------------------------------------------------------*/
9844 /* genMixedOperation - gen code for operators between mixed types */
9845 /*-----------------------------------------------------------------*/
9847 TSD - Written for the PIC port - but this unfortunately is buggy.
9848 This routine is good in that it is able to efficiently promote
9849 types to different (larger) sizes. Unfortunately, the temporary
9850 variables that are optimized out by this routine are sometimes
9851 used in other places. So until I know how to really parse the
9852 iCode tree, I'm going to not be using this routine :(.
9854 static int genMixedOperation (iCode *ic)
9857 operand *result = IC_RESULT(ic);
9858 sym_link *ctype = operandType(IC_LEFT(ic));
9859 operand *right = IC_RIGHT(ic);
9865 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9867 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9873 nextright = IC_RIGHT(nextic);
9874 nextleft = IC_LEFT(nextic);
9875 nextresult = IC_RESULT(nextic);
9877 pic16_aopOp(right,ic,FALSE);
9878 pic16_aopOp(result,ic,FALSE);
9879 pic16_aopOp(nextright, nextic, FALSE);
9880 pic16_aopOp(nextleft, nextic, FALSE);
9881 pic16_aopOp(nextresult, nextic, FALSE);
9883 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9889 pic16_emitcode(";remove right +","");
9891 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9897 pic16_emitcode(";remove left +","");
9901 big = AOP_SIZE(nextleft);
9902 small = AOP_SIZE(nextright);
9904 switch(nextic->op) {
9907 pic16_emitcode(";optimize a +","");
9908 /* if unsigned or not an integral type */
9909 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9910 pic16_emitcode(";add a bit to something","");
9913 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9915 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9916 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9917 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9919 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9927 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9928 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9929 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9932 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9934 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9935 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9936 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9937 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9938 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9941 pic16_emitcode("rlf","known_zero,w");
9948 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9949 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9950 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9952 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9962 pic16_freeAsmop(right,NULL,ic,TRUE);
9963 pic16_freeAsmop(result,NULL,ic,TRUE);
9964 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9965 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9967 nextic->generated = 1;
9974 /*-----------------------------------------------------------------*/
9975 /* genCast - gen code for casting */
9976 /*-----------------------------------------------------------------*/
9977 static void genCast (iCode *ic)
9979 operand *result = IC_RESULT(ic);
9980 sym_link *ctype = operandType(IC_LEFT(ic));
9981 sym_link *rtype = operandType(IC_RIGHT(ic));
9982 operand *right = IC_RIGHT(ic);
9985 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9986 /* if they are equivalent then do nothing */
9987 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9990 pic16_aopOp(right,ic,FALSE) ;
9991 pic16_aopOp(result,ic,FALSE);
9993 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9995 /* if the result is a bit */
9996 if (AOP_TYPE(result) == AOP_CRY) {
9998 /* if the right size is a literal then
9999 * we know what the value is */
10000 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10002 if (AOP_TYPE(right) == AOP_LIT) {
10003 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10004 pic16_popGet(AOP(result),0));
10006 if (((int) operandLitValue(right)))
10007 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10008 AOP(result)->aopu.aop_dir,
10009 AOP(result)->aopu.aop_dir);
10011 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10012 AOP(result)->aopu.aop_dir,
10013 AOP(result)->aopu.aop_dir);
10017 /* the right is also a bit variable */
10018 if (AOP_TYPE(right) == AOP_CRY) {
10020 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10022 pic16_emitcode("clrc","");
10023 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10024 AOP(right)->aopu.aop_dir,
10025 AOP(right)->aopu.aop_dir);
10026 pic16_aopPut(AOP(result),"c",0);
10030 /* we need to or */
10031 if (AOP_TYPE(right) == AOP_REG) {
10032 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10033 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10034 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10036 pic16_toBoolean(right);
10037 pic16_aopPut(AOP(result),"a",0);
10041 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10044 size = AOP_SIZE(result);
10046 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10048 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10049 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10050 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10053 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10058 /* if they are the same size : or less */
10059 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10061 /* if they are in the same place */
10062 if (pic16_sameRegs(AOP(right),AOP(result)))
10065 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10067 if (IS_PTR_CONST(rtype))
10069 if (IS_CODEPTR(rtype))
10071 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10074 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10076 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10078 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10081 if(AOP_TYPE(right) == AOP_IMMD) {
10082 pCodeOp *pcop0, *pcop1, *pcop2;
10083 symbol *sym = OP_SYMBOL( right );
10085 size = AOP_SIZE(result);
10087 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10089 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10091 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10094 pic16_emitpcode(POC_MOVLW, pcop0);
10095 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10096 pic16_emitpcode(POC_MOVLW, pcop1);
10097 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10098 pic16_emitpcode(POC_MOVLW, pcop2);
10099 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10102 pic16_emitpcode(POC_MOVLW, pcop0);
10103 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10104 pic16_emitpcode(POC_MOVLW, pcop1);
10105 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10107 pic16_emitpcode(POC_MOVLW, pcop0);
10108 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10112 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10113 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10114 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10115 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10116 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10117 if(AOP_SIZE(result) <2)
10118 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10120 /* if they in different places then copy */
10121 size = AOP_SIZE(result);
10124 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10125 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10132 /* if the result is of type pointer */
10133 if (IS_PTR(ctype)) {
10135 sym_link *type = operandType(right);
10136 sym_link *etype = getSpec(type);
10138 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10140 /* pointer to generic pointer */
10141 if (IS_GENPTR(ctype)) {
10145 p_type = DCL_TYPE(type);
10147 /* we have to go by the storage class */
10148 p_type = PTR_TYPE(SPEC_OCLS(etype));
10150 /* if (SPEC_OCLS(etype)->codesp ) */
10151 /* p_type = CPOINTER ; */
10153 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10154 /* p_type = FPOINTER ; */
10156 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10157 /* p_type = PPOINTER; */
10159 /* if (SPEC_OCLS(etype) == idata ) */
10160 /* p_type = IPOINTER ; */
10162 /* p_type = POINTER ; */
10165 /* the first two bytes are known */
10166 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10167 size = GPTRSIZE - 1;
10170 if(offset < AOP_SIZE(right)) {
10171 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10172 if ((AOP_TYPE(right) == AOP_PCODE) &&
10173 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10174 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10175 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10177 pic16_aopPut(AOP(result),
10178 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10182 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10185 /* the last byte depending on type */
10189 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10192 pic16_emitcode(";BUG!? ","%d",__LINE__);
10196 pic16_emitcode(";BUG!? ","%d",__LINE__);
10200 pic16_emitcode(";BUG!? ","%d",__LINE__);
10205 /* this should never happen */
10206 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10207 "got unknown pointer type");
10210 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10214 /* just copy the pointers */
10215 size = AOP_SIZE(result);
10218 pic16_aopPut(AOP(result),
10219 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10228 /* so we now know that the size of destination is greater
10229 than the size of the source.
10230 Now, if the next iCode is an operator then we might be
10231 able to optimize the operation without performing a cast.
10233 if(genMixedOperation(ic))
10236 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10238 /* we move to result for the size of source */
10239 size = AOP_SIZE(right);
10242 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10243 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10247 /* now depending on the sign of the destination */
10248 size = AOP_SIZE(result) - AOP_SIZE(right);
10249 /* if unsigned or not an integral type */
10250 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10252 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10254 /* we need to extend the sign :( */
10257 /* Save one instruction of casting char to int */
10258 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10259 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10260 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10262 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10265 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10267 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10269 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10272 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10277 pic16_freeAsmop(right,NULL,ic,TRUE);
10278 pic16_freeAsmop(result,NULL,ic,TRUE);
10282 /*-----------------------------------------------------------------*/
10283 /* genDjnz - generate decrement & jump if not zero instrucion */
10284 /*-----------------------------------------------------------------*/
10285 static int genDjnz (iCode *ic, iCode *ifx)
10287 symbol *lbl, *lbl1;
10288 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10293 /* if the if condition has a false label
10294 then we cannot save */
10298 /* if the minus is not of the form
10300 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10301 !IS_OP_LITERAL(IC_RIGHT(ic)))
10304 if (operandLitValue(IC_RIGHT(ic)) != 1)
10307 /* if the size of this greater than one then no
10309 if (getSize(operandType(IC_RESULT(ic))) > 1)
10312 /* otherwise we can save BIG */
10313 lbl = newiTempLabel(NULL);
10314 lbl1= newiTempLabel(NULL);
10316 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10318 if (IS_AOP_PREG(IC_RESULT(ic))) {
10319 pic16_emitcode("dec","%s",
10320 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10321 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10322 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10326 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10327 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10329 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10330 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10333 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10334 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10335 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10336 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10339 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10340 ifx->generated = 1;
10344 /*-----------------------------------------------------------------*/
10345 /* genReceive - generate code for a receive iCode */
10346 /*-----------------------------------------------------------------*/
10347 static void genReceive (iCode *ic)
10349 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10351 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10352 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10353 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10355 int size = getSize(operandType(IC_RESULT(ic)));
10356 int offset = pic16_fReturnSizePic - size;
10359 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10360 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10364 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10366 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10367 size = AOP_SIZE(IC_RESULT(ic));
10370 pic16_emitcode ("pop","acc");
10371 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10374 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10377 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10379 assignResultValue(IC_RESULT(ic));
10382 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10385 /*-----------------------------------------------------------------*/
10386 /* genDummyRead - generate code for dummy read of volatiles */
10387 /*-----------------------------------------------------------------*/
10389 genDummyRead (iCode * ic)
10391 pic16_emitcode ("; genDummyRead","");
10392 pic16_emitcode ("; not implemented","");
10397 /*-----------------------------------------------------------------*/
10398 /* genpic16Code - generate code for pic16 based controllers */
10399 /*-----------------------------------------------------------------*/
10401 * At this point, ralloc.c has gone through the iCode and attempted
10402 * to optimize in a way suitable for a PIC. Now we've got to generate
10403 * PIC instructions that correspond to the iCode.
10405 * Once the instructions are generated, we'll pass through both the
10406 * peep hole optimizer and the pCode optimizer.
10407 *-----------------------------------------------------------------*/
10409 void genpic16Code (iCode *lic)
10414 lineHead = lineCurr = NULL;
10416 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10417 pic16_addpBlock(pb);
10420 /* if debug information required */
10421 if (options.debug && currFunc) {
10423 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10425 if (IS_STATIC(currFunc->etype)) {
10426 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10427 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10429 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10430 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10439 for (ic = lic ; ic ; ic = ic->next ) {
10441 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10442 // DEBUGpic16_emitcode("; VR", "");
10443 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10444 if ( cln != ic->lineno ) {
10445 if ( options.debug ) {
10447 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10448 FileBaseName(ic->filename),ic->lineno,
10449 ic->level,ic->block);
10453 if(!options.noCcodeInAsm) {
10454 pic16_addpCode2pBlock(pb,
10455 pic16_newpCodeCSource(ic->lineno, ic->filename,
10456 printCLine(ic->filename, ic->lineno)));
10462 if(options.iCodeInAsm) {
10463 /* insert here code to print iCode as comment */
10464 pic16_emitcomment("; ic:%d: %s", ic->seq, printILine(ic));
10467 /* if the result is marked as
10468 spilt and rematerializable or code for
10469 this has already been generated then
10471 if (resultRemat(ic) || ic->generated )
10474 /* depending on the operation */
10493 /* IPOP happens only when trying to restore a
10494 spilt live range, if there is an ifx statement
10495 following this pop then the if statement might
10496 be using some of the registers being popped which
10497 would destroy the contents of the register so
10498 we need to check for this condition and handle it */
10500 ic->next->op == IFX &&
10501 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10502 genIfx (ic->next,ic);
10520 genEndFunction (ic);
10536 pic16_genPlus (ic) ;
10540 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10541 pic16_genMinus (ic);
10557 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10561 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10568 /* note these two are xlated by algebraic equivalence
10569 during parsing SDCC.y */
10570 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10571 "got '>=' or '<=' shouldn't have come here");
10575 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10587 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10591 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10595 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10619 genRightShift (ic);
10622 case GET_VALUE_AT_ADDRESS:
10627 if (POINTER_SET(ic))
10654 addSet(&_G.sendSet,ic);
10657 case DUMMY_READ_VOLATILE:
10667 /* now we are ready to call the
10668 peep hole optimizer */
10669 if (!options.nopeep) {
10670 peepHole (&lineHead);
10672 /* now do the actual printing */
10673 printLine (lineHead,codeOutFile);
10676 DFPRINTF((stderr,"printing pBlock\n\n"));
10677 pic16_printpBlock(stdout,pb);