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);
468 /*-----------------------------------------------------------------*/
469 /* pointerCode - returns the code for a pointer type */
470 /*-----------------------------------------------------------------*/
471 static int pointerCode (sym_link *etype)
474 return PTR_TYPE(SPEC_OCLS(etype));
478 /*-----------------------------------------------------------------*/
479 /* aopForSym - for a true symbol */
480 /*-----------------------------------------------------------------*/
481 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
484 memmap *space= SPEC_OCLS(sym->etype);
486 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
487 /* if already has one */
489 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
493 /* assign depending on the storage class */
494 /* if it is on the stack or indirectly addressable */
495 /* space we need to assign either r0 or r1 to it */
496 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
497 sym->aop = aop = newAsmop(0);
498 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
499 aop->size = getSize(sym->type);
501 /* now assign the address of the variable to
502 the pointer register */
503 if (aop->type != AOP_STK) {
507 pic16_emitcode("push","acc");
509 pic16_emitcode("mov","a,_bp");
510 pic16_emitcode("add","a,#0x%02x",
512 ((char)(sym->stack - _G.nRegsSaved )) :
513 ((char)sym->stack)) & 0xff);
514 pic16_emitcode("mov","%s,a",
515 aop->aopu.aop_ptr->name);
518 pic16_emitcode("pop","acc");
520 pic16_emitcode("mov","%s,#%s",
521 aop->aopu.aop_ptr->name,
523 aop->paged = space->paged;
525 aop->aopu.aop_stk = sym->stack;
529 if (sym->onStack && options.stack10bit)
531 /* It's on the 10 bit stack, which is located in
535 //DEBUGpic16_emitcode(";","%d",__LINE__);
538 pic16_emitcode("push","acc");
540 pic16_emitcode("mov","a,_bp");
541 pic16_emitcode("add","a,#0x%02x",
543 ((char)(sym->stack - _G.nRegsSaved )) :
544 ((char)sym->stack)) & 0xff);
547 pic16_emitcode ("mov","dpx1,#0x40");
548 pic16_emitcode ("mov","dph1,#0x00");
549 pic16_emitcode ("mov","dpl1, a");
553 pic16_emitcode("pop","acc");
555 sym->aop = aop = newAsmop(AOP_DPTR2);
556 aop->size = getSize(sym->type);
560 //DEBUGpic16_emitcode(";","%d",__LINE__);
561 /* if in bit space */
562 if (IN_BITSPACE(space)) {
563 sym->aop = aop = newAsmop (AOP_CRY);
564 aop->aopu.aop_dir = sym->rname ;
565 aop->size = getSize(sym->type);
566 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
569 /* if it is in direct space */
570 if (IN_DIRSPACE(space)) {
571 sym->aop = aop = newAsmop (AOP_DIR);
572 aop->aopu.aop_dir = sym->rname ;
573 aop->size = getSize(sym->type);
574 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
578 /* special case for a function */
579 if (IS_FUNC(sym->type)) {
580 sym->aop = aop = newAsmop(AOP_IMMD);
581 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
582 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
583 strcpy(aop->aopu.aop_immd,sym->rname);
584 aop->size = FPTRSIZE;
585 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
590 /* only remaining is far space */
591 /* in which case DPTR gets the address */
592 sym->aop = aop = newAsmop(AOP_PCODE);
594 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
595 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
596 PCOI(aop->aopu.pcop)->index = 0;
598 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
599 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
601 pic16_allocDirReg (IC_LEFT(ic));
603 aop->size = FPTRSIZE;
605 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
606 sym->aop = aop = newAsmop(AOP_DPTR);
607 pic16_emitcode ("mov","dptr,#%s", sym->rname);
608 aop->size = getSize(sym->type);
610 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
613 /* if it is in code space */
614 if (IN_CODESPACE(space))
620 /*-----------------------------------------------------------------*/
621 /* aopForRemat - rematerialzes an object */
622 /*-----------------------------------------------------------------*/
623 static asmop *aopForRemat (operand *op) // x symbol *sym)
625 symbol *sym = OP_SYMBOL(op);
627 asmop *aop = newAsmop(AOP_PCODE);
631 ic = sym->rematiCode;
633 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
634 if(IS_OP_POINTER(op)) {
635 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
639 val += (int) operandLitValue(IC_RIGHT(ic));
640 } else if (ic->op == '-') {
641 val -= (int) operandLitValue(IC_RIGHT(ic));
645 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
648 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
649 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
651 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
653 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
655 PCOI(aop->aopu.pcop)->index = val;
657 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
658 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
660 val, IS_PTR_CONST(operandType(op)));
662 val, IS_CODEPTR(operandType(op)));
665 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
667 pic16_allocDirReg (IC_LEFT(ic));
672 static int aopIdx (asmop *aop, int offset)
677 if(aop->type != AOP_REG)
680 return aop->aopu.aop_reg[offset]->rIdx;
683 /*-----------------------------------------------------------------*/
684 /* regsInCommon - two operands have some registers in common */
685 /*-----------------------------------------------------------------*/
686 static bool regsInCommon (operand *op1, operand *op2)
691 /* if they have registers in common */
692 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
695 sym1 = OP_SYMBOL(op1);
696 sym2 = OP_SYMBOL(op2);
698 if (sym1->nRegs == 0 || sym2->nRegs == 0)
701 for (i = 0 ; i < sym1->nRegs ; i++) {
706 for (j = 0 ; j < sym2->nRegs ;j++ ) {
710 if (sym2->regs[j] == sym1->regs[i])
718 /*-----------------------------------------------------------------*/
719 /* operandsEqu - equivalent */
720 /*-----------------------------------------------------------------*/
721 static bool operandsEqu ( operand *op1, operand *op2)
725 /* if they not symbols */
726 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
729 sym1 = OP_SYMBOL(op1);
730 sym2 = OP_SYMBOL(op2);
732 /* if both are itemps & one is spilt
733 and the other is not then false */
734 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
735 sym1->isspilt != sym2->isspilt )
738 /* if they are the same */
742 if (strcmp(sym1->rname,sym2->rname) == 0)
746 /* if left is a tmp & right is not */
750 (sym1->usl.spillLoc == sym2))
757 (sym2->usl.spillLoc == sym1))
763 /*-----------------------------------------------------------------*/
764 /* pic16_sameRegs - two asmops have the same registers */
765 /*-----------------------------------------------------------------*/
766 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
773 if (aop1->type != AOP_REG ||
774 aop2->type != AOP_REG )
777 if (aop1->size != aop2->size )
780 for (i = 0 ; i < aop1->size ; i++ )
781 if (aop1->aopu.aop_reg[i] !=
782 aop2->aopu.aop_reg[i] )
788 /*-----------------------------------------------------------------*/
789 /* pic16_aopOp - allocates an asmop for an operand : */
790 /*-----------------------------------------------------------------*/
791 void pic16_aopOp (operand *op, iCode *ic, bool result)
800 // DEBUGpic16_emitcode(";","%d",__LINE__);
802 /* if this a literal */
803 if (IS_OP_LITERAL(op)) {
804 op->aop = aop = newAsmop(AOP_LIT);
805 aop->aopu.aop_lit = op->operand.valOperand;
806 aop->size = getSize(operandType(op));
811 sym_link *type = operandType(op);
813 if(IS_PTR_CONST(type))
817 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
820 /* if already has a asmop then continue */
824 /* if the underlying symbol has a aop */
825 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
826 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
827 op->aop = OP_SYMBOL(op)->aop;
831 /* if this is a true symbol */
832 if (IS_TRUE_SYMOP(op)) {
833 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
834 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
838 /* this is a temporary : this has
844 e) can be a return use only */
848 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
849 /* if the type is a conditional */
850 if (sym->regType == REG_CND) {
851 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
856 /* if it is spilt then two situations
858 b) has a spill location */
859 if (sym->isspilt || sym->nRegs == 0) {
861 DEBUGpic16_emitcode(";","%d",__LINE__);
862 /* rematerialize it NOW */
865 sym->aop = op->aop = aop =
867 aop->size = getSize(sym->type);
868 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
874 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
875 aop->size = getSize(sym->type);
876 for ( i = 0 ; i < 2 ; i++ )
877 aop->aopu.aop_str[i] = accUse[i];
878 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
884 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
885 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
886 //pic16_allocDirReg (IC_LEFT(ic));
887 aop->size = getSize(sym->type);
892 aop = op->aop = sym->aop = newAsmop(AOP_STR);
893 aop->size = getSize(sym->type);
894 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
895 aop->aopu.aop_str[i] = fReturn[i];
897 DEBUGpic16_emitcode(";","%d",__LINE__);
901 /* else spill location */
902 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
903 /* force a new aop if sizes differ */
904 sym->usl.spillLoc->aop = NULL;
906 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
907 __FUNCTION__,__LINE__,
908 sym->usl.spillLoc->rname,
909 sym->rname, sym->usl.spillLoc->offset);
911 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
912 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
913 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
915 sym->usl.spillLoc->offset);
916 aop->size = getSize(sym->type);
922 sym_link *type = operandType(op);
924 if(IS_PTR_CONST(type))
928 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
931 /* must be in a register */
932 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
933 sym->aop = op->aop = aop = newAsmop(AOP_REG);
934 aop->size = sym->nRegs;
935 for ( i = 0 ; i < sym->nRegs ;i++)
936 aop->aopu.aop_reg[i] = sym->regs[i];
939 /*-----------------------------------------------------------------*/
940 /* pic16_freeAsmop - free up the asmop given to an operand */
941 /*----------------------------------------------------------------*/
942 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
959 /* depending on the asmop type only three cases need work AOP_RO
960 , AOP_R1 && AOP_STK */
966 pic16_emitcode ("pop","ar0");
970 bitVectUnSetBit(ic->rUsed,R0_IDX);
976 pic16_emitcode ("pop","ar1");
980 bitVectUnSetBit(ic->rUsed,R1_IDX);
986 int stk = aop->aopu.aop_stk + aop->size;
987 bitVectUnSetBit(ic->rUsed,R0_IDX);
988 bitVectUnSetBit(ic->rUsed,R1_IDX);
990 getFreePtr(ic,&aop,FALSE);
992 if (options.stack10bit)
994 /* I'm not sure what to do here yet... */
997 "*** Warning: probably generating bad code for "
998 "10 bit stack mode.\n");
1002 pic16_emitcode ("mov","a,_bp");
1003 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1004 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1006 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1010 pic16_emitcode("pop","acc");
1011 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1013 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1016 pic16_freeAsmop(op,NULL,ic,TRUE);
1018 pic16_emitcode("pop","ar0");
1023 pic16_emitcode("pop","ar1");
1031 /* all other cases just dealloc */
1035 OP_SYMBOL(op)->aop = NULL;
1036 /* if the symbol has a spill */
1038 SPIL_LOC(op)->aop = NULL;
1043 /*-----------------------------------------------------------------*/
1044 /* pic16_aopGet - for fetching value of the aop */
1045 /*-----------------------------------------------------------------*/
1046 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1051 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1052 /* offset is greater than
1054 if (offset > (aop->size - 1) &&
1055 aop->type != AOP_LIT)
1058 /* depending on type */
1059 switch (aop->type) {
1063 DEBUGpic16_emitcode(";","%d",__LINE__);
1064 /* if we need to increment it */
1065 while (offset > aop->coff) {
1066 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1070 while (offset < aop->coff) {
1071 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1075 aop->coff = offset ;
1077 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1078 return (dname ? "acc" : "a");
1080 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1081 rs = Safe_calloc(1,strlen(s)+1);
1087 DEBUGpic16_emitcode(";","%d",__LINE__);
1088 if (aop->type == AOP_DPTR2)
1093 while (offset > aop->coff) {
1094 pic16_emitcode ("inc","dptr");
1098 while (offset < aop->coff) {
1099 pic16_emitcode("lcall","__decdptr");
1105 pic16_emitcode("clr","a");
1106 pic16_emitcode("movc","a,@a+dptr");
1109 pic16_emitcode("movx","a,@dptr");
1112 if (aop->type == AOP_DPTR2)
1117 return (dname ? "acc" : "a");
1122 sprintf (s,"%s",aop->aopu.aop_immd);
1125 sprintf(s,"(%s >> %d)",
1130 aop->aopu.aop_immd);
1131 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1132 rs = Safe_calloc(1,strlen(s)+1);
1138 sprintf(s,"(%s + %d)",
1141 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1143 sprintf(s,"%s",aop->aopu.aop_dir);
1144 rs = Safe_calloc(1,strlen(s)+1);
1150 // return aop->aopu.aop_reg[offset]->dname;
1152 return aop->aopu.aop_reg[offset]->name;
1155 //pic16_emitcode(";","%d",__LINE__);
1156 return aop->aopu.aop_dir;
1159 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1160 return "AOP_accumulator_bug";
1163 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1164 rs = Safe_calloc(1,strlen(s)+1);
1169 aop->coff = offset ;
1170 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1173 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1175 return aop->aopu.aop_str[offset];
1179 pCodeOp *pcop = aop->aopu.pcop;
1180 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1182 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1183 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1184 sprintf(s,"%s", pcop->name);
1186 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1189 rs = Safe_calloc(1,strlen(s)+1);
1195 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1196 "aopget got unsupported aop->type");
1201 /*-----------------------------------------------------------------*/
1202 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1203 /*-----------------------------------------------------------------*/
1204 pCodeOp *pic16_popGetTempReg(void)
1209 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1210 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1211 PCOR(pcop)->r->wasUsed=1;
1212 PCOR(pcop)->r->isFree=0;
1218 /*-----------------------------------------------------------------*/
1219 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1220 /*-----------------------------------------------------------------*/
1221 void pic16_popReleaseTempReg(pCodeOp *pcop)
1224 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1225 PCOR(pcop)->r->isFree = 1;
1228 /*-----------------------------------------------------------------*/
1229 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1230 /*-----------------------------------------------------------------*/
1231 pCodeOp *pic16_popGetLabel(unsigned int key)
1234 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1239 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1242 /*-----------------------------------------------------------------*/
1243 /* pic16_popCopyReg - copy a pcode operator */
1244 /*-----------------------------------------------------------------*/
1245 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1249 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1250 pcor->pcop.type = pc->pcop.type;
1252 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1253 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1255 pcor->pcop.name = NULL;
1258 pcor->rIdx = pc->rIdx;
1261 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1266 /*-----------------------------------------------------------------*/
1267 /* pic16_popGetLit - asm operator to pcode operator conversion */
1268 /*-----------------------------------------------------------------*/
1269 pCodeOp *pic16_popGetLit(unsigned int lit)
1271 return pic16_newpCodeOpLit(lit);
1274 /*-----------------------------------------------------------------*/
1275 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1276 /*-----------------------------------------------------------------*/
1277 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1279 return pic16_newpCodeOpLit2(lit, arg2);
1283 /*-----------------------------------------------------------------*/
1284 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1289 return pic16_newpCodeOpImmd(name, offset,index, 0);
1293 /*-----------------------------------------------------------------*/
1294 /* pic16_popGet - asm operator to pcode operator conversion */
1295 /*-----------------------------------------------------------------*/
1296 pCodeOp *pic16_popGetWithString(char *str)
1302 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1306 pcop = pic16_newpCodeOp(str,PO_STR);
1311 /*-----------------------------------------------------------------*/
1312 /* pic16_popRegFromString - */
1313 /*-----------------------------------------------------------------*/
1314 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1317 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1318 pcop->type = PO_DIR;
1320 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1321 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1326 pcop->name = Safe_calloc(1,strlen(str)+1);
1327 strcpy(pcop->name,str);
1329 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1331 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1332 if(PCOR(pcop)->r == NULL) {
1333 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1334 // __FUNCTION__, __LINE__, str, size, offset);
1335 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1337 //fprintf(stderr, "allocating new register -> %s\n", str);
1339 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1341 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1343 PCOR(pcop)->instance = offset;
1348 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1352 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1354 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1355 PCOR(pcop)->rIdx = rIdx;
1356 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1357 PCOR(pcop)->r->isFree = 0;
1358 PCOR(pcop)->r->wasUsed = 1;
1360 pcop->type = PCOR(pcop)->r->pc_type;
1365 /*---------------------------------------------------------------------------------*/
1366 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1368 /*---------------------------------------------------------------------------------*/
1369 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1374 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1376 /* comment the following check, so errors to throw up */
1377 // if(!pcop2)return NULL;
1379 temp = pic16_popGet(aop_dst, offset);
1380 pcop2->pcop2 = temp;
1385 /*---------------------------------------------------------------------------------*/
1386 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1387 /* movff instruction */
1388 /*---------------------------------------------------------------------------------*/
1389 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1394 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1395 pcop2->pcop2 = pic16_popCopyReg(dst);
1397 /* the pCodeOp may be already allocated */
1398 pcop2 = (pCodeOpReg2 *)(src);
1399 pcop2->pcop2 = (pCodeOp *)(dst);
1406 /*-----------------------------------------------------------------*/
1407 /* pic16_popGet - asm operator to pcode operator conversion */
1408 /*-----------------------------------------------------------------*/
1409 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1411 //char *s = buffer ;
1416 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1417 /* offset is greater than
1420 if (offset > (aop->size - 1) &&
1421 aop->type != AOP_LIT)
1422 return NULL; //zero;
1424 /* depending on type */
1425 switch (aop->type) {
1432 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1433 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1437 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1438 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1441 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1442 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1446 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1448 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1449 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1450 PCOR(pcop)->rIdx = rIdx;
1451 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1452 PCOR(pcop)->r->wasUsed=1;
1453 PCOR(pcop)->r->isFree=0;
1455 PCOR(pcop)->instance = offset;
1456 pcop->type = PCOR(pcop)->r->pc_type;
1457 //rs = aop->aopu.aop_reg[offset]->name;
1458 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1463 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1465 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1466 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1467 //if(PCOR(pcop)->r == NULL)
1468 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1472 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1473 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1476 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1477 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1480 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1481 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1482 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1483 pcop->type = PCOR(pcop)->r->pc_type;
1484 pcop->name = PCOR(pcop)->r->name;
1490 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1492 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1493 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1494 PCOI(pcop)->offset = offset;
1498 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1499 "pic16_popGet got unsupported aop->type");
1502 /*-----------------------------------------------------------------*/
1503 /* pic16_aopPut - puts a string for a aop */
1504 /*-----------------------------------------------------------------*/
1505 void pic16_aopPut (asmop *aop, char *s, int offset)
1510 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1512 if (aop->size && offset > ( aop->size - 1)) {
1513 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1514 "pic16_aopPut got offset > aop->size");
1518 /* will assign value to value */
1519 /* depending on where it is ofcourse */
1520 switch (aop->type) {
1523 sprintf(d,"(%s + %d)",
1524 aop->aopu.aop_dir,offset);
1525 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1528 sprintf(d,"%s",aop->aopu.aop_dir);
1531 DEBUGpic16_emitcode(";","%d",__LINE__);
1533 pic16_emitcode("movf","%s,w",s);
1534 pic16_emitcode("movwf","%s",d);
1537 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1538 if(offset >= aop->size) {
1539 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1542 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1545 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1552 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1553 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1556 strcmp(s,"r0") == 0 ||
1557 strcmp(s,"r1") == 0 ||
1558 strcmp(s,"r2") == 0 ||
1559 strcmp(s,"r3") == 0 ||
1560 strcmp(s,"r4") == 0 ||
1561 strcmp(s,"r5") == 0 ||
1562 strcmp(s,"r6") == 0 ||
1563 strcmp(s,"r7") == 0 )
1564 pic16_emitcode("mov","%s,%s ; %d",
1565 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1569 if(strcmp(s,"W")==0 )
1570 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1572 pic16_emitcode("movwf","%s",
1573 aop->aopu.aop_reg[offset]->name);
1575 if(strcmp(s,zero)==0) {
1576 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1578 } else if(strcmp(s,"W")==0) {
1579 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1580 pcop->type = PO_GPR_REGISTER;
1582 PCOR(pcop)->rIdx = -1;
1583 PCOR(pcop)->r = NULL;
1585 DEBUGpic16_emitcode(";","%d",__LINE__);
1586 pcop->name = Safe_strdup(s);
1587 pic16_emitpcode(POC_MOVFW,pcop);
1588 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1589 } else if(strcmp(s,one)==0) {
1590 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1591 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1593 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1601 if (aop->type == AOP_DPTR2)
1607 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1608 "pic16_aopPut writting to code space");
1612 while (offset > aop->coff) {
1614 pic16_emitcode ("inc","dptr");
1617 while (offset < aop->coff) {
1619 pic16_emitcode("lcall","__decdptr");
1624 /* if not in accumulater */
1627 pic16_emitcode ("movx","@dptr,a");
1629 if (aop->type == AOP_DPTR2)
1637 while (offset > aop->coff) {
1639 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1641 while (offset < aop->coff) {
1643 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1649 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1654 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1656 if (strcmp(s,"r0") == 0 ||
1657 strcmp(s,"r1") == 0 ||
1658 strcmp(s,"r2") == 0 ||
1659 strcmp(s,"r3") == 0 ||
1660 strcmp(s,"r4") == 0 ||
1661 strcmp(s,"r5") == 0 ||
1662 strcmp(s,"r6") == 0 ||
1663 strcmp(s,"r7") == 0 ) {
1665 sprintf(buffer,"a%s",s);
1666 pic16_emitcode("mov","@%s,%s",
1667 aop->aopu.aop_ptr->name,buffer);
1669 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1674 if (strcmp(s,"a") == 0)
1675 pic16_emitcode("push","acc");
1677 pic16_emitcode("push","%s",s);
1682 /* if bit variable */
1683 if (!aop->aopu.aop_dir) {
1684 pic16_emitcode("clr","a");
1685 pic16_emitcode("rlc","a");
1688 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1691 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1694 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1696 lbl = newiTempLabel(NULL);
1698 if (strcmp(s,"a")) {
1701 pic16_emitcode("clr","c");
1702 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1703 pic16_emitcode("cpl","c");
1704 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1705 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1712 if (strcmp(aop->aopu.aop_str[offset],s))
1713 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1718 if (!offset && (strcmp(s,"acc") == 0))
1721 if (strcmp(aop->aopu.aop_str[offset],s))
1722 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1726 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1727 "pic16_aopPut got unsupported aop->type");
1733 /*-----------------------------------------------------------------*/
1734 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1735 /*-----------------------------------------------------------------*/
1736 static void mov2w (asmop *aop, int offset)
1742 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1744 if ( aop->type == AOP_PCODE ||
1745 aop->type == AOP_LIT )
1746 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1748 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1753 void pic16_pushpCodeOpReg(pCodeOpReg *pcop)
1755 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pcop, &pic16_pc_postdec1, 0));
1758 void pic16_poppCodeOpReg(pCodeOpReg *pcop)
1760 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, pcop, 0));
1764 /*-----------------------------------------------------------------*/
1765 /* pushw - pushes wreg to stack */
1766 /*-----------------------------------------------------------------*/
1769 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1770 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1774 /*-----------------------------------------------------------------*/
1775 /* pushaop - pushes aop to stack */
1776 /*-----------------------------------------------------------------*/
1777 void pushaop(asmop *aop, int offset)
1779 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1780 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1783 /*-----------------------------------------------------------------*/
1784 /* popaop - pops aop from stack */
1785 /*-----------------------------------------------------------------*/
1786 void popaop(asmop *aop, int offset)
1788 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1789 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1792 void popaopidx(asmop *aop, int offset, int index)
1796 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1798 if(STACK_MODEL_LARGE)ofs++;
1800 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1801 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1804 /*-----------------------------------------------------------------*/
1805 /* reAdjustPreg - points a register back to where it should */
1806 /*-----------------------------------------------------------------*/
1807 static void reAdjustPreg (asmop *aop)
1811 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1813 if ((size = aop->size) <= 1)
1816 switch (aop->type) {
1820 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1824 if (aop->type == AOP_DPTR2)
1830 pic16_emitcode("lcall","__decdptr");
1833 if (aop->type == AOP_DPTR2)
1845 /*-----------------------------------------------------------------*/
1846 /* opIsGptr: returns non-zero if the passed operand is */
1847 /* a generic pointer type. */
1848 /*-----------------------------------------------------------------*/
1849 static int opIsGptr(operand *op)
1851 sym_link *type = operandType(op);
1853 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1854 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1862 /*-----------------------------------------------------------------*/
1863 /* pic16_getDataSize - get the operand data size */
1864 /*-----------------------------------------------------------------*/
1865 int pic16_getDataSize(operand *op)
1867 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1870 return AOP_SIZE(op);
1872 // tsd- in the pic port, the genptr size is 1, so this code here
1873 // fails. ( in the 8051 port, the size was 4).
1876 size = AOP_SIZE(op);
1877 if (size == GPTRSIZE)
1879 sym_link *type = operandType(op);
1880 if (IS_GENPTR(type))
1882 /* generic pointer; arithmetic operations
1883 * should ignore the high byte (pointer type).
1886 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1893 /*-----------------------------------------------------------------*/
1894 /* pic16_outAcc - output Acc */
1895 /*-----------------------------------------------------------------*/
1896 void pic16_outAcc(operand *result)
1899 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1900 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1903 size = pic16_getDataSize(result);
1905 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1908 /* unsigned or positive */
1910 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1915 /*-----------------------------------------------------------------*/
1916 /* pic16_outBitC - output a bit C */
1917 /*-----------------------------------------------------------------*/
1918 void pic16_outBitC(operand *result)
1921 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1922 /* if the result is bit */
1923 if (AOP_TYPE(result) == AOP_CRY)
1924 pic16_aopPut(AOP(result),"c",0);
1926 pic16_emitcode("clr","a ; %d", __LINE__);
1927 pic16_emitcode("rlc","a");
1928 pic16_outAcc(result);
1932 /*-----------------------------------------------------------------*/
1933 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1934 /*-----------------------------------------------------------------*/
1935 void pic16_toBoolean(operand *oper)
1937 int size = AOP_SIZE(oper) - 1;
1940 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1942 if ( AOP_TYPE(oper) != AOP_ACC) {
1943 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1946 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1951 #if !defined(GEN_Not)
1952 /*-----------------------------------------------------------------*/
1953 /* genNot - generate code for ! operation */
1954 /*-----------------------------------------------------------------*/
1955 static void pic16_genNot (iCode *ic)
1960 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1961 /* assign asmOps to operand & result */
1962 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1963 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1965 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1966 /* if in bit space then a special case */
1967 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1968 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1969 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1970 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1972 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1973 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1974 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1979 size = AOP_SIZE(IC_LEFT(ic));
1981 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1982 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1983 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1986 pic16_toBoolean(IC_LEFT(ic));
1988 tlbl = newiTempLabel(NULL);
1989 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1990 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1991 pic16_outBitC(IC_RESULT(ic));
1994 /* release the aops */
1995 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1996 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2001 #if !defined(GEN_Cpl)
2002 /*-----------------------------------------------------------------*/
2003 /* genCpl - generate code for complement */
2004 /*-----------------------------------------------------------------*/
2005 static void pic16_genCpl (iCode *ic)
2011 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2012 /* assign asmOps to operand & result */
2013 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2014 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2016 /* if both are in bit space then
2018 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2019 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2021 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2022 pic16_emitcode("cpl","c");
2023 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2027 size = AOP_SIZE(IC_RESULT(ic));
2030 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2032 pic16_emitcode("cpl","a");
2033 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2035 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2036 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2038 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2039 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2047 /* release the aops */
2048 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2049 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2053 /*-----------------------------------------------------------------*/
2054 /* genUminusFloat - unary minus for floating points */
2055 /*-----------------------------------------------------------------*/
2056 static void genUminusFloat(operand *op,operand *result)
2058 int size ,offset =0 ;
2061 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2062 /* for this we just need to flip the
2063 first it then copy the rest in place */
2064 size = AOP_SIZE(op) - 1;
2065 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2069 pic16_emitcode("cpl","acc.7");
2070 pic16_aopPut(AOP(result),"a",3);
2073 pic16_aopPut(AOP(result),
2074 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2080 /*-----------------------------------------------------------------*/
2081 /* genUminus - unary minus code generation */
2082 /*-----------------------------------------------------------------*/
2083 static void genUminus (iCode *ic)
2086 sym_link *optype, *rtype;
2089 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2091 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2092 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2094 /* if both in bit space then special
2096 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2097 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2099 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2100 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2101 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2106 optype = operandType(IC_LEFT(ic));
2107 rtype = operandType(IC_RESULT(ic));
2109 /* if float then do float stuff */
2110 if (IS_FLOAT(optype)) {
2111 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2115 /* otherwise subtract from zero by taking the 2's complement */
2116 size = AOP_SIZE(IC_LEFT(ic));
2118 for(i=0; i<size; i++) {
2119 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2120 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2122 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2123 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2127 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2128 for(i=1; i<size; i++) {
2130 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2134 /* release the aops */
2135 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2136 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2139 /*-----------------------------------------------------------------*/
2140 /* saveRegisters - will look for a call and save the registers */
2141 /*-----------------------------------------------------------------*/
2142 static void saveRegisters(iCode *lic)
2149 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2151 for (ic = lic ; ic ; ic = ic->next)
2152 if (ic->op == CALL || ic->op == PCALL)
2156 fprintf(stderr,"found parameter push with no function call\n");
2160 /* if the registers have been saved already then
2162 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2165 /* find the registers in use at this time
2166 and push them away to safety */
2167 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2171 if (options.useXstack) {
2172 if (bitVectBitValue(rsave,R0_IDX))
2173 pic16_emitcode("mov","b,r0");
2174 pic16_emitcode("mov","r0,%s",spname);
2175 for (i = 0 ; i < pic16_nRegs ; i++) {
2176 if (bitVectBitValue(rsave,i)) {
2178 pic16_emitcode("mov","a,b");
2180 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2181 pic16_emitcode("movx","@r0,a");
2182 pic16_emitcode("inc","r0");
2185 pic16_emitcode("mov","%s,r0",spname);
2186 if (bitVectBitValue(rsave,R0_IDX))
2187 pic16_emitcode("mov","r0,b");
2189 //for (i = 0 ; i < pic16_nRegs ; i++) {
2190 // if (bitVectBitValue(rsave,i))
2191 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2194 dtype = operandType(IC_LEFT(ic));
2195 if (currFunc && dtype &&
2196 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2197 IFFUNC_ISISR(currFunc->type) &&
2200 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2203 /*-----------------------------------------------------------------*/
2204 /* unsaveRegisters - pop the pushed registers */
2205 /*-----------------------------------------------------------------*/
2206 static void unsaveRegisters (iCode *ic)
2211 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2212 /* find the registers in use at this time
2213 and push them away to safety */
2214 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2217 if (options.useXstack) {
2218 pic16_emitcode("mov","r0,%s",spname);
2219 for (i = pic16_nRegs ; i >= 0 ; i--) {
2220 if (bitVectBitValue(rsave,i)) {
2221 pic16_emitcode("dec","r0");
2222 pic16_emitcode("movx","a,@r0");
2224 pic16_emitcode("mov","b,a");
2226 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2230 pic16_emitcode("mov","%s,r0",spname);
2231 if (bitVectBitValue(rsave,R0_IDX))
2232 pic16_emitcode("mov","r0,b");
2234 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2235 // if (bitVectBitValue(rsave,i))
2236 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2242 /*-----------------------------------------------------------------*/
2244 /*-----------------------------------------------------------------*/
2245 static void pushSide(operand * oper, int size)
2249 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2251 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2252 if (AOP_TYPE(oper) != AOP_REG &&
2253 AOP_TYPE(oper) != AOP_DIR &&
2255 pic16_emitcode("mov","a,%s",l);
2256 pic16_emitcode("push","acc");
2258 pic16_emitcode("push","%s",l);
2263 /*-----------------------------------------------------------------*/
2264 /* assignResultValue - */
2265 /*-----------------------------------------------------------------*/
2266 static void assignResultValue(operand * oper)
2268 int size = AOP_SIZE(oper);
2270 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2271 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2273 if(!GpsuedoStkPtr) {
2274 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2275 /* The last byte in the assignment is in W */
2277 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2282 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2283 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2287 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2289 pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2292 pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2293 #endif /* STACK_SUPPORT */
2298 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2300 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2308 /*-----------------------------------------------------------------*/
2309 /* genIpush - genrate code for pushing this gets a little complex */
2310 /*-----------------------------------------------------------------*/
2311 static void genIpush (iCode *ic)
2314 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2316 int size, offset = 0 ;
2320 /* if this is not a parm push : ie. it is spill push
2321 and spill push is always done on the local stack */
2322 if (!ic->parmPush) {
2324 /* and the item is spilt then do nothing */
2325 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2328 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2329 size = AOP_SIZE(IC_LEFT(ic));
2330 /* push it on the stack */
2332 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2337 pic16_emitcode("push","%s",l);
2342 /* this is a paramter push: in this case we call
2343 the routine to find the call and save those
2344 registers that need to be saved */
2347 /* then do the push */
2348 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2351 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2352 size = AOP_SIZE(IC_LEFT(ic));
2355 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2356 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2357 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2359 pic16_emitcode("mov","a,%s",l);
2360 pic16_emitcode("push","acc");
2362 pic16_emitcode("push","%s",l);
2365 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2369 /*-----------------------------------------------------------------*/
2370 /* genIpop - recover the registers: can happen only for spilling */
2371 /*-----------------------------------------------------------------*/
2372 static void genIpop (iCode *ic)
2374 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2379 /* if the temp was not pushed then */
2380 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2383 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2384 size = AOP_SIZE(IC_LEFT(ic));
2387 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2390 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2394 /*-----------------------------------------------------------------*/
2395 /* unsaverbank - restores the resgister bank from stack */
2396 /*-----------------------------------------------------------------*/
2397 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2399 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2407 if (options.useXstack) {
2409 r = getFreePtr(ic,&aop,FALSE);
2412 pic16_emitcode("mov","%s,_spx",r->name);
2413 pic16_emitcode("movx","a,@%s",r->name);
2414 pic16_emitcode("mov","psw,a");
2415 pic16_emitcode("dec","%s",r->name);
2418 pic16_emitcode ("pop","psw");
2421 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2422 if (options.useXstack) {
2423 pic16_emitcode("movx","a,@%s",r->name);
2424 //pic16_emitcode("mov","(%s+%d),a",
2425 // regspic16[i].base,8*bank+regspic16[i].offset);
2426 pic16_emitcode("dec","%s",r->name);
2429 pic16_emitcode("pop",""); //"(%s+%d)",
2430 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2433 if (options.useXstack) {
2435 pic16_emitcode("mov","_spx,%s",r->name);
2436 pic16_freeAsmop(NULL,aop,ic,TRUE);
2442 /*-----------------------------------------------------------------*/
2443 /* saverbank - saves an entire register bank on the stack */
2444 /*-----------------------------------------------------------------*/
2445 static void saverbank (int bank, iCode *ic, bool pushPsw)
2447 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2453 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2454 if (options.useXstack) {
2457 r = getFreePtr(ic,&aop,FALSE);
2458 pic16_emitcode("mov","%s,_spx",r->name);
2462 for (i = 0 ; i < pic16_nRegs ;i++) {
2463 if (options.useXstack) {
2464 pic16_emitcode("inc","%s",r->name);
2465 //pic16_emitcode("mov","a,(%s+%d)",
2466 // regspic16[i].base,8*bank+regspic16[i].offset);
2467 pic16_emitcode("movx","@%s,a",r->name);
2469 pic16_emitcode("push","");// "(%s+%d)",
2470 //regspic16[i].base,8*bank+regspic16[i].offset);
2474 if (options.useXstack) {
2475 pic16_emitcode("mov","a,psw");
2476 pic16_emitcode("movx","@%s,a",r->name);
2477 pic16_emitcode("inc","%s",r->name);
2478 pic16_emitcode("mov","_spx,%s",r->name);
2479 pic16_freeAsmop (NULL,aop,ic,TRUE);
2482 pic16_emitcode("push","psw");
2484 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2492 /*-----------------------------------------------------------------*/
2493 /* genCall - generates a call statement */
2494 /*-----------------------------------------------------------------*/
2495 static void genCall (iCode *ic)
2500 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2502 /* if caller saves & we have not saved then */
2506 /* if we are calling a function that is not using
2507 * the same register bank then we need to save the
2508 * destination registers on the stack */
2509 dtype = operandType(IC_LEFT(ic));
2510 if (currFunc && dtype &&
2511 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2512 IFFUNC_ISISR(currFunc->type) &&
2515 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2517 /* if send set is not empty the assign */
2521 /* For the Pic port, there is no data stack.
2522 * So parameters passed to functions are stored
2523 * in registers. (The pCode optimizer will get
2524 * rid of most of these :). */
2526 int psuedoStkPtr=-1;
2527 int firstTimeThruLoop = 1;
2529 _G.sendSet = reverseSet(_G.sendSet);
2531 /* First figure how many parameters are getting passed */
2532 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2533 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2534 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2535 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2538 stackParms = psuedoStkPtr;
2540 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2541 int size, offset = 0;
2543 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2544 size = AOP_SIZE(IC_LEFT(sic));
2547 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2548 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2549 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2551 if(!firstTimeThruLoop) {
2552 /* If this is not the first time we've been through the loop
2553 * then we need to save the parameter in a temporary
2554 * register. The last byte of the last parameter is
2560 --psuedoStkPtr; // sanity check
2562 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2565 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2566 #endif /* STACK_SUPPORT */
2569 firstTimeThruLoop=0;
2571 mov2w (AOP(IC_LEFT(sic)), offset);
2574 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2580 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2581 OP_SYMBOL(IC_LEFT(ic))->rname :
2582 OP_SYMBOL(IC_LEFT(ic))->name));
2585 /* if we need assign a result value */
2586 if ((IS_ITEMP(IC_RESULT(ic)) &&
2587 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2588 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2589 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2592 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2595 assignResultValue(IC_RESULT(ic));
2597 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2598 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2600 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2604 if(USE_STACK && stackParms>0) {
2605 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2606 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2607 if(STACK_MODEL_LARGE) {
2609 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2614 /* adjust the stack for parameters if required */
2615 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2617 if (ic->parmBytes) {
2620 if (ic->parmBytes > 3) {
2621 pic16_emitcode("mov","a,%s",spname);
2622 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2623 pic16_emitcode("mov","%s,a",spname);
2625 for ( i = 0 ; i < ic->parmBytes ;i++)
2626 pic16_emitcode("dec","%s",spname);
2629 /* if register bank was saved then pop them */
2631 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2633 /* if we hade saved some registers then unsave them */
2634 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2635 unsaveRegisters (ic);
2638 /*-----------------------------------------------------------------*/
2639 /* genPcall - generates a call by pointer statement */
2640 /*-----------------------------------------------------------------*/
2641 static void genPcall (iCode *ic)
2644 symbol *rlbl = newiTempLabel(NULL);
2647 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2648 /* if caller saves & we have not saved then */
2652 /* if we are calling a function that is not using
2653 the same register bank then we need to save the
2654 destination registers on the stack */
2655 dtype = operandType(IC_LEFT(ic));
2656 if (currFunc && dtype &&
2657 IFFUNC_ISISR(currFunc->type) &&
2658 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2659 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2662 /* push the return address on to the stack */
2663 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2664 pic16_emitcode("push","acc");
2665 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2666 pic16_emitcode("push","acc");
2668 if (options.model == MODEL_FLAT24)
2670 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2671 pic16_emitcode("push","acc");
2674 /* now push the calling address */
2675 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2677 pushSide(IC_LEFT(ic), FPTRSIZE);
2679 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2681 /* if send set is not empty the assign */
2685 for (sic = setFirstItem(_G.sendSet) ; sic ;
2686 sic = setNextItem(_G.sendSet)) {
2687 int size, offset = 0;
2688 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2689 size = AOP_SIZE(IC_LEFT(sic));
2691 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2693 if (strcmp(l,fReturn[offset]))
2694 pic16_emitcode("mov","%s,%s",
2699 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2704 pic16_emitcode("ret","");
2705 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2708 /* if we need assign a result value */
2709 if ((IS_ITEMP(IC_RESULT(ic)) &&
2710 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2711 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2712 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2715 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2718 assignResultValue(IC_RESULT(ic));
2720 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2723 /* adjust the stack for parameters if
2725 if (ic->parmBytes) {
2727 if (ic->parmBytes > 3) {
2728 pic16_emitcode("mov","a,%s",spname);
2729 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2730 pic16_emitcode("mov","%s,a",spname);
2732 for ( i = 0 ; i < ic->parmBytes ;i++)
2733 pic16_emitcode("dec","%s",spname);
2737 /* if register bank was saved then unsave them */
2738 if (currFunc && dtype &&
2739 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2740 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2742 /* if we hade saved some registers then
2745 unsaveRegisters (ic);
2749 /*-----------------------------------------------------------------*/
2750 /* resultRemat - result is rematerializable */
2751 /*-----------------------------------------------------------------*/
2752 static int resultRemat (iCode *ic)
2754 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2755 if (SKIP_IC(ic) || ic->op == IFX)
2758 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2759 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2760 if (sym->remat && !POINTER_SET(ic))
2767 #if defined(__BORLANDC__) || defined(_MSC_VER)
2768 #define STRCASECMP stricmp
2770 #define STRCASECMP strcasecmp
2774 /*-----------------------------------------------------------------*/
2775 /* inExcludeList - return 1 if the string is in exclude Reg list */
2776 /*-----------------------------------------------------------------*/
2777 static bool inExcludeList(char *s)
2779 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2782 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2783 if (options.excludeRegs[i] &&
2784 STRCASECMP(options.excludeRegs[i],"none") == 0)
2787 for ( i = 0 ; options.excludeRegs[i]; i++) {
2788 if (options.excludeRegs[i] &&
2789 STRCASECMP(s,options.excludeRegs[i]) == 0)
2796 /*-----------------------------------------------------------------*/
2797 /* genFunction - generated code for function entry */
2798 /*-----------------------------------------------------------------*/
2799 static void genFunction (iCode *ic)
2804 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2806 labelOffset += (max_key+4);
2810 /* create the function header */
2811 pic16_emitcode(";","-----------------------------------------");
2812 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2813 pic16_emitcode(";","-----------------------------------------");
2815 pic16_emitcode("","%s:",sym->rname);
2816 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
2821 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
2822 if(strcmp(ab->name, sym->name)) {
2823 pic16_pBlockConvert2Absolute(pb);
2829 ftype = operandType(IC_LEFT(ic));
2831 if(IFFUNC_ISNAKED(ftype)) {
2832 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
2837 /* if critical function then turn interrupts off */
2838 if (IFFUNC_ISCRITICAL(ftype))
2839 pic16_emitcode("clr","ea");
2841 /* here we need to generate the equates for the
2842 * register bank if required */
2844 if (FUNC_REGBANK(ftype) != rbank) {
2847 rbank = FUNC_REGBANK(ftype);
2848 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2849 if (strcmp(regspic16[i].base,"0") == 0)
2850 pic16_emitcode("","%s = 0x%02x",
2852 8*rbank+regspic16[i].offset);
2854 pic16_emitcode ("","%s = %s + 0x%02x",
2857 *rbank+regspic16[i].offset);
2862 /* if this is an interrupt service routine then
2863 * save acc, b, dpl, dph */
2864 if (IFFUNC_ISISR(sym->type)) {
2865 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2866 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2867 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2868 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2870 pic16_pBlockConvert2ISR(pb);
2872 if (!inExcludeList("acc"))
2873 pic16_emitcode ("push","acc");
2874 if (!inExcludeList("b"))
2875 pic16_emitcode ("push","b");
2876 if (!inExcludeList("dpl"))
2877 pic16_emitcode ("push","dpl");
2878 if (!inExcludeList("dph"))
2879 pic16_emitcode ("push","dph");
2881 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) {
2882 pic16_emitcode ("push", "dpx");
2884 /* Make sure we're using standard DPTR */
2885 pic16_emitcode ("push", "dps");
2886 pic16_emitcode ("mov", "dps, #0x00");
2887 if (options.stack10bit) {
2888 /* This ISR could conceivably use DPTR2. Better save it. */
2889 pic16_emitcode ("push", "dpl1");
2890 pic16_emitcode ("push", "dph1");
2891 pic16_emitcode ("push", "dpx1");
2895 /* if this isr has no bank i.e. is going to
2896 * run with bank 0 , then we need to save more
2898 if (!FUNC_REGBANK(sym->type)) {
2900 /* if this function does not call any other
2901 * function then we can be economical and
2902 * save only those registers that are used */
2903 if (! IFFUNC_HASFCALL(sym->type)) {
2906 /* if any registers used */
2907 if (sym->regsUsed) {
2908 /* save the registers used */
2909 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2910 if (bitVectBitValue(sym->regsUsed,i) ||
2911 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2912 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2917 /* this function has a function call cannot
2918 * determines register usage so we will have the
2920 saverbank(0,ic,FALSE);
2926 /* emit code to setup stack frame if user enabled,
2927 * and function is not main() */
2929 // fprintf(stderr, "function name: %s\n", sym->name);
2930 if(USE_STACK && strcmp(sym->name, "main")) {
2931 if(!options.ommitFramePtr || sym->regsUsed) {
2932 /* setup the stack frame */
2933 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
2934 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
2935 if(STACK_MODEL_LARGE)
2936 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
2941 /* if callee-save to be used for this function
2942 * then save the registers being used in this function */
2943 if (IFFUNC_CALLEESAVES(sym->type)) {
2946 // fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
2948 /* if any registers used */
2954 /* save the registers used */
2955 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
2956 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2957 if (bitVectBitValue(sym->regsUsed,i)) {
2958 // fprintf(stderr, "%s:%d function %s uses register %s\n",
2959 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
2960 // pic16_regWithIdx(i)->name);
2962 pic16_pushpCodeOpReg( PCOR(pic16_popRegFromIdx(i) ));
2963 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
2964 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
2965 // &pic16_pc_postdec1, 0));
2976 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2978 if (options.useXstack) {
2979 pic16_emitcode("mov","r0,%s",spname);
2980 pic16_emitcode("mov","a,_bp");
2981 pic16_emitcode("movx","@r0,a");
2982 pic16_emitcode("inc","%s",spname);
2984 /* set up the stack */
2985 pic16_emitcode ("push","_bp"); /* save the callers stack */
2987 pic16_emitcode ("mov","_bp,%s",spname);
2990 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
2992 /* adjust the stack for the function */
2997 werror(W_STACK_OVERFLOW,sym->name);
2999 if (i > 3 && sym->recvSize < 4) {
3000 pic16_emitcode ("mov","a,sp");
3001 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3002 pic16_emitcode ("mov","sp,a");
3005 pic16_emitcode("inc","sp");
3009 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3011 pic16_emitcode ("mov","a,_spx");
3012 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3013 pic16_emitcode ("mov","_spx,a");
3018 /*-----------------------------------------------------------------*/
3019 /* genEndFunction - generates epilogue for functions */
3020 /*-----------------------------------------------------------------*/
3021 static void genEndFunction (iCode *ic)
3023 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3027 if(IFFUNC_ISNAKED(sym->type)) {
3028 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3033 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3035 pic16_emitcode ("mov","%s,_bp",spname);
3039 /* if use external stack but some variables were
3040 added to the local stack then decrement the
3042 if (options.useXstack && sym->stack) {
3043 pic16_emitcode("mov","a,sp");
3044 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3045 pic16_emitcode("mov","sp,a");
3050 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3051 if (options.useXstack) {
3052 pic16_emitcode("mov","r0,%s",spname);
3053 pic16_emitcode("movx","a,@r0");
3054 pic16_emitcode("mov","_bp,a");
3055 pic16_emitcode("dec","%s",spname);
3059 pic16_emitcode ("pop","_bp");
3064 /* restore the register bank */
3065 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
3066 pic16_emitcode ("pop","psw");
3068 if (IFFUNC_ISISR(sym->type)) {
3070 /* now we need to restore the registers */
3071 /* if this isr has no bank i.e. is going to
3072 run with bank 0 , then we need to save more
3074 if (!FUNC_REGBANK(sym->type)) {
3076 /* if this function does not call any other
3077 function then we can be economical and
3078 save only those registers that are used */
3079 if (! IFFUNC_HASFCALL(sym->type)) {
3082 /* if any registers used */
3083 if (sym->regsUsed) {
3084 /* save the registers used */
3085 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3086 if (bitVectBitValue(sym->regsUsed,i) ||
3087 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3088 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
3093 /* this function has a function call cannot
3094 determines register usage so we will have the
3096 unsaverbank(0,ic,FALSE);
3100 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
3102 if (options.stack10bit)
3104 pic16_emitcode ("pop", "dpx1");
3105 pic16_emitcode ("pop", "dph1");
3106 pic16_emitcode ("pop", "dpl1");
3108 pic16_emitcode ("pop", "dps");
3109 pic16_emitcode ("pop", "dpx");
3111 if (!inExcludeList("dph"))
3112 pic16_emitcode ("pop","dph");
3113 if (!inExcludeList("dpl"))
3114 pic16_emitcode ("pop","dpl");
3115 if (!inExcludeList("b"))
3116 pic16_emitcode ("pop","b");
3117 if (!inExcludeList("acc"))
3118 pic16_emitcode ("pop","acc");
3120 if (IFFUNC_ISCRITICAL(sym->type))
3121 pic16_emitcode("setb","ea");
3124 /* if debug then send end of function */
3125 /* if (options.debug && currFunc) { */
3128 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3129 FileBaseName(ic->filename),currFunc->lastLine,
3130 ic->level,ic->block);
3131 if (IS_STATIC(currFunc->etype))
3132 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3134 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3138 // pic16_emitcode ("reti","");
3140 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
3141 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
3142 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
3143 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
3144 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
3147 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
3150 pic16_emitpcodeNULLop(POC_RETFIE);
3154 if (IFFUNC_ISCRITICAL(sym->type))
3155 pic16_emitcode("setb","ea");
3157 /* if any registers used */
3164 /* save the registers used */
3165 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3166 for ( i = sym->regsUsed->size; i >= 0; i--) {
3167 if (bitVectBitValue(sym->regsUsed,i)) {
3168 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3169 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3170 // pic16_regWithIdx(i)->name);
3172 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3174 PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3180 /* if debug then send end of function */
3183 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3184 FileBaseName(ic->filename),currFunc->lastLine,
3185 ic->level,ic->block);
3186 if (IS_STATIC(currFunc->etype))
3187 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3189 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3194 /* insert code to restore stack frame, if user enabled it
3195 * and function is not main() */
3197 if(USE_STACK && strcmp(sym->name, "main")) {
3198 if(!options.ommitFramePtr || sym->regsUsed) {
3199 /* restore stack frame */
3200 if(STACK_MODEL_LARGE)
3201 pic16_emitpcode(POC_MOVFF,
3202 pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h, 0));
3203 pic16_emitpcode(POC_MOVFF,
3204 pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l, 0));
3209 pic16_emitcode ("return","");
3210 pic16_emitpcodeNULLop(POC_RETURN);
3212 /* Mark the end of a function */
3213 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3218 /*-----------------------------------------------------------------*/
3219 /* genRet - generate code for return statement */
3220 /*-----------------------------------------------------------------*/
3221 static void genRet (iCode *ic)
3223 int size,offset = 0 , pushed = 0;
3225 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3226 /* if we have no return value then
3227 just generate the "ret" */
3231 /* we have something to return then
3232 move the return value into place */
3233 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3234 size = AOP_SIZE(IC_LEFT(ic));
3238 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3240 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3242 pic16_emitcode("push","%s",l);
3245 DEBUGpic16_emitcode(";", "%d", __LINE__);
3246 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3248 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3249 if (strcmp(fReturn[offset],l)) {
3250 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3251 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3252 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3254 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3257 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3267 if (strcmp(fReturn[pushed],"a"))
3268 pic16_emitcode("pop",fReturn[pushed]);
3270 pic16_emitcode("pop","acc");
3273 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3276 /* generate a jump to the return label
3277 if the next is not the return statement */
3278 if (!(ic->next && ic->next->op == LABEL &&
3279 IC_LABEL(ic->next) == returnLabel)) {
3281 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3282 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3287 /*-----------------------------------------------------------------*/
3288 /* genLabel - generates a label */
3289 /*-----------------------------------------------------------------*/
3290 static void genLabel (iCode *ic)
3292 /* special case never generate */
3293 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3294 if (IC_LABEL(ic) == entryLabel)
3297 pic16_emitpLabel(IC_LABEL(ic)->key);
3298 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3301 /*-----------------------------------------------------------------*/
3302 /* genGoto - generates a goto */
3303 /*-----------------------------------------------------------------*/
3305 static void genGoto (iCode *ic)
3307 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3308 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3312 /*-----------------------------------------------------------------*/
3313 /* genMultbits :- multiplication of bits */
3314 /*-----------------------------------------------------------------*/
3315 static void genMultbits (operand *left,
3319 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3321 if(!pic16_sameRegs(AOP(result),AOP(right)))
3322 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3324 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3325 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3326 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3331 /*-----------------------------------------------------------------*/
3332 /* genMultOneByte : 8 bit multiplication & division */
3333 /*-----------------------------------------------------------------*/
3334 static void genMultOneByte (operand *left,
3338 sym_link *opetype = operandType(result);
3343 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3344 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3345 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3347 /* (if two literals, the value is computed before) */
3348 /* if one literal, literal on the right */
3349 if (AOP_TYPE(left) == AOP_LIT){
3355 size = AOP_SIZE(result);
3358 if (AOP_TYPE(right) == AOP_LIT){
3359 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3360 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3361 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3362 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3363 pic16_emitcode("call","genMultLit");
3365 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3366 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3367 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3368 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3369 pic16_emitcode("call","pic16_genMult8X8_8");
3372 pic16_genMult8X8_8 (left, right,result);
3375 /* signed or unsigned */
3376 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3377 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3379 //pic16_emitcode("mul","ab");
3380 /* if result size = 1, mul signed = mul unsigned */
3381 //pic16_aopPut(AOP(result),"a",0);
3383 } else { // (size > 1)
3385 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3386 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3387 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3388 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3390 if (SPEC_USIGN(opetype)){
3391 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3392 pic16_genUMult8X8_16 (left, right, result, NULL);
3395 /* for filling the MSBs */
3396 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3397 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3401 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3403 pic16_emitcode("mov","a,b");
3405 /* adjust the MSB if left or right neg */
3407 /* if one literal */
3408 if (AOP_TYPE(right) == AOP_LIT){
3409 pic16_emitcode("multiply ","right is a lit");
3410 /* AND literal negative */
3411 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3412 /* adjust MSB (c==0 after mul) */
3413 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3417 pic16_genSMult8X8_16 (left, right, result, NULL);
3421 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3423 pic16_emitcode("rlc","a");
3424 pic16_emitcode("subb","a,acc");
3432 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3433 //pic16_aopPut(AOP(result),"a",offset++);
3437 /*-----------------------------------------------------------------*/
3438 /* genMult - generates code for multiplication */
3439 /*-----------------------------------------------------------------*/
3440 static void genMult (iCode *ic)
3442 operand *left = IC_LEFT(ic);
3443 operand *right = IC_RIGHT(ic);
3444 operand *result= IC_RESULT(ic);
3446 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3447 /* assign the amsops */
3448 pic16_aopOp (left,ic,FALSE);
3449 pic16_aopOp (right,ic,FALSE);
3450 pic16_aopOp (result,ic,TRUE);
3452 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3454 /* special cases first */
3456 if (AOP_TYPE(left) == AOP_CRY &&
3457 AOP_TYPE(right)== AOP_CRY) {
3458 genMultbits(left,right,result);
3462 /* if both are of size == 1 */
3463 if (AOP_SIZE(left) == 1 &&
3464 AOP_SIZE(right) == 1 ) {
3465 genMultOneByte(left,right,result);
3469 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3471 /* should have been converted to function call */
3475 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3476 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3477 pic16_freeAsmop(result,NULL,ic,TRUE);
3480 /*-----------------------------------------------------------------*/
3481 /* genDivbits :- division of bits */
3482 /*-----------------------------------------------------------------*/
3483 static void genDivbits (operand *left,
3490 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3491 /* the result must be bit */
3492 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3493 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3497 pic16_emitcode("div","ab");
3498 pic16_emitcode("rrc","a");
3499 pic16_aopPut(AOP(result),"c",0);
3502 /*-----------------------------------------------------------------*/
3503 /* genDivOneByte : 8 bit division */
3504 /*-----------------------------------------------------------------*/
3505 static void genDivOneByte (operand *left,
3509 sym_link *opetype = operandType(result);
3514 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3515 size = AOP_SIZE(result) - 1;
3517 /* signed or unsigned */
3518 if (SPEC_USIGN(opetype)) {
3519 /* unsigned is easy */
3520 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3521 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3523 pic16_emitcode("div","ab");
3524 pic16_aopPut(AOP(result),"a",0);
3526 pic16_aopPut(AOP(result),zero,offset++);
3530 /* signed is a little bit more difficult */
3532 /* save the signs of the operands */
3533 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3535 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3536 pic16_emitcode("push","acc"); /* save it on the stack */
3538 /* now sign adjust for both left & right */
3539 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3541 lbl = newiTempLabel(NULL);
3542 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3543 pic16_emitcode("cpl","a");
3544 pic16_emitcode("inc","a");
3545 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3546 pic16_emitcode("mov","b,a");
3548 /* sign adjust left side */
3549 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3552 lbl = newiTempLabel(NULL);
3553 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3554 pic16_emitcode("cpl","a");
3555 pic16_emitcode("inc","a");
3556 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3558 /* now the division */
3559 pic16_emitcode("div","ab");
3560 /* we are interested in the lower order
3562 pic16_emitcode("mov","b,a");
3563 lbl = newiTempLabel(NULL);
3564 pic16_emitcode("pop","acc");
3565 /* if there was an over flow we don't
3566 adjust the sign of the result */
3567 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3568 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3570 pic16_emitcode("clr","a");
3571 pic16_emitcode("subb","a,b");
3572 pic16_emitcode("mov","b,a");
3573 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3575 /* now we are done */
3576 pic16_aopPut(AOP(result),"b",0);
3578 pic16_emitcode("mov","c,b.7");
3579 pic16_emitcode("subb","a,acc");
3582 pic16_aopPut(AOP(result),"a",offset++);
3586 /*-----------------------------------------------------------------*/
3587 /* genDiv - generates code for division */
3588 /*-----------------------------------------------------------------*/
3589 static void genDiv (iCode *ic)
3591 operand *left = IC_LEFT(ic);
3592 operand *right = IC_RIGHT(ic);
3593 operand *result= IC_RESULT(ic);
3595 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3596 /* assign the amsops */
3597 pic16_aopOp (left,ic,FALSE);
3598 pic16_aopOp (right,ic,FALSE);
3599 pic16_aopOp (result,ic,TRUE);
3601 /* special cases first */
3603 if (AOP_TYPE(left) == AOP_CRY &&
3604 AOP_TYPE(right)== AOP_CRY) {
3605 genDivbits(left,right,result);
3609 /* if both are of size == 1 */
3610 if (AOP_SIZE(left) == 1 &&
3611 AOP_SIZE(right) == 1 ) {
3612 genDivOneByte(left,right,result);
3616 /* should have been converted to function call */
3619 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3620 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3621 pic16_freeAsmop(result,NULL,ic,TRUE);
3624 /*-----------------------------------------------------------------*/
3625 /* genModbits :- modulus of bits */
3626 /*-----------------------------------------------------------------*/
3627 static void genModbits (operand *left,
3634 /* the result must be bit */
3635 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3636 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3640 pic16_emitcode("div","ab");
3641 pic16_emitcode("mov","a,b");
3642 pic16_emitcode("rrc","a");
3643 pic16_aopPut(AOP(result),"c",0);
3646 /*-----------------------------------------------------------------*/
3647 /* genModOneByte : 8 bit modulus */
3648 /*-----------------------------------------------------------------*/
3649 static void genModOneByte (operand *left,
3653 sym_link *opetype = operandType(result);
3657 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3658 /* signed or unsigned */
3659 if (SPEC_USIGN(opetype)) {
3660 /* unsigned is easy */
3661 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3662 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3664 pic16_emitcode("div","ab");
3665 pic16_aopPut(AOP(result),"b",0);
3669 /* signed is a little bit more difficult */
3671 /* save the signs of the operands */
3672 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3675 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3676 pic16_emitcode("push","acc"); /* save it on the stack */
3678 /* now sign adjust for both left & right */
3679 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3682 lbl = newiTempLabel(NULL);
3683 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3684 pic16_emitcode("cpl","a");
3685 pic16_emitcode("inc","a");
3686 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3687 pic16_emitcode("mov","b,a");
3689 /* sign adjust left side */
3690 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3693 lbl = newiTempLabel(NULL);
3694 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3695 pic16_emitcode("cpl","a");
3696 pic16_emitcode("inc","a");
3697 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3699 /* now the multiplication */
3700 pic16_emitcode("div","ab");
3701 /* we are interested in the lower order
3703 lbl = newiTempLabel(NULL);
3704 pic16_emitcode("pop","acc");
3705 /* if there was an over flow we don't
3706 adjust the sign of the result */
3707 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3708 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3710 pic16_emitcode("clr","a");
3711 pic16_emitcode("subb","a,b");
3712 pic16_emitcode("mov","b,a");
3713 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3715 /* now we are done */
3716 pic16_aopPut(AOP(result),"b",0);
3720 /*-----------------------------------------------------------------*/
3721 /* genMod - generates code for division */
3722 /*-----------------------------------------------------------------*/
3723 static void genMod (iCode *ic)
3725 operand *left = IC_LEFT(ic);
3726 operand *right = IC_RIGHT(ic);
3727 operand *result= IC_RESULT(ic);
3729 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3730 /* assign the amsops */
3731 pic16_aopOp (left,ic,FALSE);
3732 pic16_aopOp (right,ic,FALSE);
3733 pic16_aopOp (result,ic,TRUE);
3735 /* special cases first */
3737 if (AOP_TYPE(left) == AOP_CRY &&
3738 AOP_TYPE(right)== AOP_CRY) {
3739 genModbits(left,right,result);
3743 /* if both are of size == 1 */
3744 if (AOP_SIZE(left) == 1 &&
3745 AOP_SIZE(right) == 1 ) {
3746 genModOneByte(left,right,result);
3750 /* should have been converted to function call */
3754 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3755 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3756 pic16_freeAsmop(result,NULL,ic,TRUE);
3759 /*-----------------------------------------------------------------*/
3760 /* genIfxJump :- will create a jump depending on the ifx */
3761 /*-----------------------------------------------------------------*/
3763 note: May need to add parameter to indicate when a variable is in bit space.
3765 static void genIfxJump (iCode *ic, char *jval)
3768 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3769 /* if true label then we jump if condition
3771 if ( IC_TRUE(ic) ) {
3773 if(strcmp(jval,"a") == 0)
3775 else if (strcmp(jval,"c") == 0)
3778 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3779 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3782 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3783 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3787 /* false label is present */
3788 if(strcmp(jval,"a") == 0)
3790 else if (strcmp(jval,"c") == 0)
3793 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3794 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3797 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3798 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3803 /* mark the icode as generated */
3807 /*-----------------------------------------------------------------*/
3809 /*-----------------------------------------------------------------*/
3810 static void genSkip(iCode *ifx,int status_bit)
3812 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3816 if ( IC_TRUE(ifx) ) {
3817 switch(status_bit) {
3832 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3833 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3837 switch(status_bit) {
3851 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3852 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3858 /*-----------------------------------------------------------------*/
3860 /*-----------------------------------------------------------------*/
3861 static void genSkipc(resolvedIfx *rifx)
3871 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3872 rifx->generated = 1;
3875 /*-----------------------------------------------------------------*/
3877 /*-----------------------------------------------------------------*/
3878 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3883 if( (rifx->condition ^ invert_condition) & 1)
3888 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3889 rifx->generated = 1;
3893 /*-----------------------------------------------------------------*/
3895 /*-----------------------------------------------------------------*/
3896 static void genSkipz(iCode *ifx, int condition)
3907 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3909 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3912 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3914 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3919 /*-----------------------------------------------------------------*/
3921 /*-----------------------------------------------------------------*/
3922 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3928 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3930 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3933 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3934 rifx->generated = 1;
3938 /*-----------------------------------------------------------------*/
3939 /* genChkZeroes :- greater or less than comparison */
3940 /* For each byte in a literal that is zero, inclusive or the */
3941 /* the corresponding byte in the operand with W */
3942 /* returns true if any of the bytes are zero */
3943 /*-----------------------------------------------------------------*/
3944 static int genChkZeroes(operand *op, int lit, int size)
3951 i = (lit >> (size*8)) & 0xff;
3955 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3957 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3966 /*-----------------------------------------------------------------*/
3967 /* genCmp :- greater or less than comparison */
3968 /*-----------------------------------------------------------------*/
3969 static void genCmp (operand *left,operand *right,
3970 operand *result, iCode *ifx, int sign)
3972 int size; //, offset = 0 ;
3973 unsigned long lit = 0L,i = 0;
3974 resolvedIfx rFalseIfx;
3975 // resolvedIfx rTrueIfx;
3977 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3980 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3981 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3985 resolveIfx(&rFalseIfx,ifx);
3986 truelbl = newiTempLabel(NULL);
3987 size = max(AOP_SIZE(left),AOP_SIZE(right));
3989 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3993 /* if literal is on the right then swap with left */
3994 if ((AOP_TYPE(right) == AOP_LIT)) {
3995 operand *tmp = right ;
3996 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3997 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4000 lit = (lit - 1) & mask;
4003 rFalseIfx.condition ^= 1;
4006 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4007 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4011 //if(IC_TRUE(ifx) == NULL)
4012 /* if left & right are bit variables */
4013 if (AOP_TYPE(left) == AOP_CRY &&
4014 AOP_TYPE(right) == AOP_CRY ) {
4015 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4016 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4018 /* subtract right from left if at the
4019 end the carry flag is set then we know that
4020 left is greater than right */
4024 symbol *lbl = newiTempLabel(NULL);
4027 if(AOP_TYPE(right) == AOP_LIT) {
4029 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4031 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4038 genSkipCond(&rFalseIfx,left,size-1,7);
4040 /* no need to compare to 0...*/
4041 /* NOTE: this is a de-generate compare that most certainly
4042 * creates some dead code. */
4043 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4045 if(ifx) ifx->generated = 1;
4052 //i = (lit >> (size*8)) & 0xff;
4053 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4055 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4057 i = ((0-lit) & 0xff);
4060 /* lit is 0x7f, all signed chars are less than
4061 * this except for 0x7f itself */
4062 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4063 genSkipz2(&rFalseIfx,0);
4065 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4066 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4067 genSkipc(&rFalseIfx);
4072 genSkipz2(&rFalseIfx,1);
4074 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4075 genSkipc(&rFalseIfx);
4079 if(ifx) ifx->generated = 1;
4083 /* chars are out of the way. now do ints and longs */
4086 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4093 genSkipCond(&rFalseIfx,left,size,7);
4094 if(ifx) ifx->generated = 1;
4099 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4101 //rFalseIfx.condition ^= 1;
4102 //genSkipCond(&rFalseIfx,left,size,7);
4103 //rFalseIfx.condition ^= 1;
4105 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4106 if(rFalseIfx.condition)
4107 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4109 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4111 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4112 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4113 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4116 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4118 if(rFalseIfx.condition) {
4120 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4126 genSkipc(&rFalseIfx);
4127 pic16_emitpLabel(truelbl->key);
4128 if(ifx) ifx->generated = 1;
4135 if( (lit & 0xff) == 0) {
4136 /* lower byte is zero */
4137 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4138 i = ((lit >> 8) & 0xff) ^0x80;
4139 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4140 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4141 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4142 genSkipc(&rFalseIfx);
4145 if(ifx) ifx->generated = 1;
4150 /* Special cases for signed longs */
4151 if( (lit & 0xffffff) == 0) {
4152 /* lower byte is zero */
4153 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4154 i = ((lit >> 8*3) & 0xff) ^0x80;
4155 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4156 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4157 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4158 genSkipc(&rFalseIfx);
4161 if(ifx) ifx->generated = 1;
4169 if(lit & (0x80 << (size*8))) {
4170 /* lit is negative */
4171 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4173 //genSkipCond(&rFalseIfx,left,size,7);
4175 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4177 if(rFalseIfx.condition)
4178 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4180 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4184 /* lit is positive */
4185 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4186 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4187 if(rFalseIfx.condition)
4188 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4190 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4195 This works, but is only good for ints.
4196 It also requires a "known zero" register.
4197 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4198 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4199 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4200 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4201 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4202 genSkipc(&rFalseIfx);
4204 pic16_emitpLabel(truelbl->key);
4205 if(ifx) ifx->generated = 1;
4209 /* There are no more special cases, so perform a general compare */
4211 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4212 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4216 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4218 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4220 //rFalseIfx.condition ^= 1;
4221 genSkipc(&rFalseIfx);
4223 pic16_emitpLabel(truelbl->key);
4225 if(ifx) ifx->generated = 1;
4232 /* sign is out of the way. So now do an unsigned compare */
4233 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4236 /* General case - compare to an unsigned literal on the right.*/
4238 i = (lit >> (size*8)) & 0xff;
4239 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4240 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4242 i = (lit >> (size*8)) & 0xff;
4245 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4247 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4249 /* this byte of the lit is zero,
4250 *if it's not the last then OR in the variable */
4252 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4257 pic16_emitpLabel(lbl->key);
4258 //if(emitFinalCheck)
4259 genSkipc(&rFalseIfx);
4261 pic16_emitpLabel(truelbl->key);
4263 if(ifx) ifx->generated = 1;
4270 if(AOP_TYPE(left) == AOP_LIT) {
4271 //symbol *lbl = newiTempLabel(NULL);
4273 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4276 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4279 if((lit == 0) && (sign == 0)){
4282 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4284 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4286 genSkipz2(&rFalseIfx,0);
4287 if(ifx) ifx->generated = 1;
4294 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4295 /* degenerate compare can never be true */
4296 if(rFalseIfx.condition == 0)
4297 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4299 if(ifx) ifx->generated = 1;
4304 /* signed comparisons to a literal byte */
4306 int lp1 = (lit+1) & 0xff;
4308 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4311 rFalseIfx.condition ^= 1;
4312 genSkipCond(&rFalseIfx,right,0,7);
4315 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4316 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4317 genSkipz2(&rFalseIfx,1);
4320 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4321 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4322 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4323 rFalseIfx.condition ^= 1;
4324 genSkipc(&rFalseIfx);
4328 /* unsigned comparisons to a literal byte */
4330 switch(lit & 0xff ) {
4332 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4333 genSkipz2(&rFalseIfx,0);
4336 rFalseIfx.condition ^= 1;
4337 genSkipCond(&rFalseIfx,right,0,7);
4341 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4342 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4343 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4344 rFalseIfx.condition ^= 1;
4345 if (AOP_TYPE(result) == AOP_CRY)
4346 genSkipc(&rFalseIfx);
4348 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4349 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4355 if(ifx) ifx->generated = 1;
4361 /* Size is greater than 1 */
4369 /* this means lit = 0xffffffff, or -1 */
4372 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4373 rFalseIfx.condition ^= 1;
4374 genSkipCond(&rFalseIfx,right,size,7);
4375 if(ifx) ifx->generated = 1;
4382 if(rFalseIfx.condition) {
4383 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4384 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4387 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4389 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4393 if(rFalseIfx.condition) {
4394 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4395 pic16_emitpLabel(truelbl->key);
4397 rFalseIfx.condition ^= 1;
4398 genSkipCond(&rFalseIfx,right,s,7);
4401 if(ifx) ifx->generated = 1;
4405 if((size == 1) && (0 == (lp1&0xff))) {
4406 /* lower byte of signed word is zero */
4407 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4408 i = ((lp1 >> 8) & 0xff) ^0x80;
4409 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4410 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4411 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4412 rFalseIfx.condition ^= 1;
4413 genSkipc(&rFalseIfx);
4416 if(ifx) ifx->generated = 1;
4420 if(lit & (0x80 << (size*8))) {
4421 /* Lit is less than zero */
4422 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4423 //rFalseIfx.condition ^= 1;
4424 //genSkipCond(&rFalseIfx,left,size,7);
4425 //rFalseIfx.condition ^= 1;
4426 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4427 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4429 if(rFalseIfx.condition)
4430 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4432 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4436 /* Lit is greater than or equal to zero */
4437 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4438 //rFalseIfx.condition ^= 1;
4439 //genSkipCond(&rFalseIfx,right,size,7);
4440 //rFalseIfx.condition ^= 1;
4442 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4443 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4445 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4446 if(rFalseIfx.condition)
4447 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4449 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4454 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4455 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4459 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4461 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4463 rFalseIfx.condition ^= 1;
4464 //rFalseIfx.condition = 1;
4465 genSkipc(&rFalseIfx);
4467 pic16_emitpLabel(truelbl->key);
4469 if(ifx) ifx->generated = 1;
4474 /* compare word or long to an unsigned literal on the right.*/
4479 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4482 break; /* handled above */
4485 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4487 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4488 genSkipz2(&rFalseIfx,0);
4492 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4494 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4497 if(rFalseIfx.condition)
4498 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4500 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4503 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4504 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4506 rFalseIfx.condition ^= 1;
4507 genSkipc(&rFalseIfx);
4510 pic16_emitpLabel(truelbl->key);
4512 if(ifx) ifx->generated = 1;
4518 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4519 i = (lit >> (size*8)) & 0xff;
4521 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4522 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4525 i = (lit >> (size*8)) & 0xff;
4528 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4530 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4532 /* this byte of the lit is zero,
4533 *if it's not the last then OR in the variable */
4535 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4540 pic16_emitpLabel(lbl->key);
4542 rFalseIfx.condition ^= 1;
4543 genSkipc(&rFalseIfx);
4547 pic16_emitpLabel(truelbl->key);
4548 if(ifx) ifx->generated = 1;
4552 /* Compare two variables */
4554 DEBUGpic16_emitcode(";sign","%d",sign);
4558 /* Sigh. thus sucks... */
4560 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4561 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4562 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4563 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4564 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4565 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4567 /* Signed char comparison */
4568 /* Special thanks to Nikolai Golovchenko for this snippet */
4569 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4570 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4571 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4572 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4573 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4574 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4576 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4577 genSkipc(&rFalseIfx);
4579 if(ifx) ifx->generated = 1;
4585 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4586 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4590 /* The rest of the bytes of a multi-byte compare */
4594 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4597 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4598 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4603 pic16_emitpLabel(lbl->key);
4605 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4606 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4607 (AOP_TYPE(result) == AOP_REG)) {
4608 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4609 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4611 genSkipc(&rFalseIfx);
4613 //genSkipc(&rFalseIfx);
4614 if(ifx) ifx->generated = 1;
4621 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4622 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4623 pic16_outBitC(result);
4625 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4626 /* if the result is used in the next
4627 ifx conditional branch then generate
4628 code a little differently */
4630 genIfxJump (ifx,"c");
4632 pic16_outBitC(result);
4633 /* leave the result in acc */
4638 /*-----------------------------------------------------------------*/
4639 /* genCmpGt :- greater than comparison */
4640 /*-----------------------------------------------------------------*/
4641 static void genCmpGt (iCode *ic, iCode *ifx)
4643 operand *left, *right, *result;
4644 sym_link *letype , *retype;
4647 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4649 right= IC_RIGHT(ic);
4650 result = IC_RESULT(ic);
4652 letype = getSpec(operandType(left));
4653 retype =getSpec(operandType(right));
4654 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4655 /* assign the amsops */
4656 pic16_aopOp (left,ic,FALSE);
4657 pic16_aopOp (right,ic,FALSE);
4658 pic16_aopOp (result,ic,TRUE);
4660 genCmp(right, left, result, ifx, sign);
4662 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4663 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4664 pic16_freeAsmop(result,NULL,ic,TRUE);
4667 /*-----------------------------------------------------------------*/
4668 /* genCmpLt - less than comparisons */
4669 /*-----------------------------------------------------------------*/
4670 static void genCmpLt (iCode *ic, iCode *ifx)
4672 operand *left, *right, *result;
4673 sym_link *letype , *retype;
4676 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4678 right= IC_RIGHT(ic);
4679 result = IC_RESULT(ic);
4681 letype = getSpec(operandType(left));
4682 retype =getSpec(operandType(right));
4683 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4685 /* assign the amsops */
4686 pic16_aopOp (left,ic,FALSE);
4687 pic16_aopOp (right,ic,FALSE);
4688 pic16_aopOp (result,ic,TRUE);
4690 genCmp(left, right, result, ifx, sign);
4692 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4693 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4694 pic16_freeAsmop(result,NULL,ic,TRUE);
4697 /*-----------------------------------------------------------------*/
4698 /* genc16bit2lit - compare a 16 bit value to a literal */
4699 /*-----------------------------------------------------------------*/
4700 static void genc16bit2lit(operand *op, int lit, int offset)
4704 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4705 if( (lit&0xff) == 0)
4710 switch( BYTEofLONG(lit,i)) {
4712 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4715 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4718 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4721 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4722 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4727 switch( BYTEofLONG(lit,i)) {
4729 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4733 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_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4742 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4748 /*-----------------------------------------------------------------*/
4749 /* gencjneshort - compare and jump if not equal */
4750 /*-----------------------------------------------------------------*/
4751 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4753 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4755 int res_offset = 0; /* the result may be a different size then left or right */
4756 int res_size = AOP_SIZE(result);
4760 unsigned long lit = 0L;
4761 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4762 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4764 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4765 resolveIfx(&rIfx,ifx);
4766 lbl = newiTempLabel(NULL);
4769 /* if the left side is a literal or
4770 if the right is in a pointer register and left
4772 if ((AOP_TYPE(left) == AOP_LIT) ||
4773 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4778 if(AOP_TYPE(right) == AOP_LIT)
4779 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4781 /* if the right side is a literal then anything goes */
4782 if (AOP_TYPE(right) == AOP_LIT &&
4783 AOP_TYPE(left) != AOP_DIR ) {
4786 genc16bit2lit(left, lit, 0);
4788 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4793 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4794 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4796 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4800 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4802 if(res_offset < res_size-1)
4810 /* if the right side is in a register or in direct space or
4811 if the left is a pointer register & right is not */
4812 else if (AOP_TYPE(right) == AOP_REG ||
4813 AOP_TYPE(right) == AOP_DIR ||
4814 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4815 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4816 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4817 int lbl_key = lbl->key;
4820 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4821 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4823 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4824 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4825 __FUNCTION__,__LINE__);
4829 /* switch(size) { */
4831 /* genc16bit2lit(left, lit, 0); */
4833 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4838 if((AOP_TYPE(left) == AOP_DIR) &&
4839 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4841 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4842 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4844 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4846 switch (lit & 0xff) {
4848 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4851 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4852 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4853 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4857 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4858 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4859 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4860 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4864 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4865 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4870 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4873 if(AOP_TYPE(result) == AOP_CRY) {
4874 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4879 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4881 /* fix me. probably need to check result size too */
4882 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4887 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4888 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4895 if(res_offset < res_size-1)
4900 } else if(AOP_TYPE(right) == AOP_REG &&
4901 AOP_TYPE(left) != AOP_DIR){
4904 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4905 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4906 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4911 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4913 if(res_offset < res_size-1)
4918 /* right is a pointer reg need both a & b */
4920 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4922 pic16_emitcode("mov","b,%s",l);
4923 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4924 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4929 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4931 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4933 pic16_emitpLabel(lbl->key);
4935 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4942 /*-----------------------------------------------------------------*/
4943 /* gencjne - compare and jump if not equal */
4944 /*-----------------------------------------------------------------*/
4945 static void gencjne(operand *left, operand *right, iCode *ifx)
4947 symbol *tlbl = newiTempLabel(NULL);
4949 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4950 gencjneshort(left, right, lbl);
4952 pic16_emitcode("mov","a,%s",one);
4953 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4954 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4955 pic16_emitcode("clr","a");
4956 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4958 pic16_emitpLabel(lbl->key);
4959 pic16_emitpLabel(tlbl->key);
4964 /*-----------------------------------------------------------------*/
4965 /* genCmpEq - generates code for equal to */
4966 /*-----------------------------------------------------------------*/
4967 static void genCmpEq (iCode *ic, iCode *ifx)
4969 operand *left, *right, *result;
4970 unsigned long lit = 0L;
4972 symbol *falselbl = newiTempLabel(NULL);
4975 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4978 DEBUGpic16_emitcode ("; ifx is non-null","");
4980 DEBUGpic16_emitcode ("; ifx is null","");
4982 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4983 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4984 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4986 size = max(AOP_SIZE(left),AOP_SIZE(right));
4988 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4990 /* if literal, literal on the right or
4991 if the right is in a pointer register and left
4993 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4994 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4995 operand *tmp = right ;
5001 if(ifx && !AOP_SIZE(result)){
5003 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5004 /* if they are both bit variables */
5005 if (AOP_TYPE(left) == AOP_CRY &&
5006 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5007 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5008 if(AOP_TYPE(right) == AOP_LIT){
5009 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5011 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5012 pic16_emitcode("cpl","c");
5013 } else if(lit == 1L) {
5014 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5016 pic16_emitcode("clr","c");
5018 /* AOP_TYPE(right) == AOP_CRY */
5020 symbol *lbl = newiTempLabel(NULL);
5021 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5022 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5023 pic16_emitcode("cpl","c");
5024 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5026 /* if true label then we jump if condition
5028 tlbl = newiTempLabel(NULL);
5029 if ( IC_TRUE(ifx) ) {
5030 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5031 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5033 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5034 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5036 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5039 /* left and right are both bit variables, result is carry */
5042 resolveIfx(&rIfx,ifx);
5044 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5045 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5046 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5047 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5052 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5054 /* They're not both bit variables. Is the right a literal? */
5055 if(AOP_TYPE(right) == AOP_LIT) {
5056 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5061 switch(lit & 0xff) {
5063 if ( IC_TRUE(ifx) ) {
5064 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5066 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5068 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5069 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5073 if ( IC_TRUE(ifx) ) {
5074 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5076 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5078 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5079 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5083 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5085 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5090 /* end of size == 1 */
5094 genc16bit2lit(left,lit,offset);
5097 /* end of size == 2 */
5102 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5103 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5104 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5105 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5108 /* search for patterns that can be optimized */
5110 genc16bit2lit(left,lit,0);
5114 emitSKPZ; // if hi word unequal
5116 emitSKPNZ; // if hi word equal
5118 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5119 genc16bit2lit(left,lit,2);
5122 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5123 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5127 pic16_emitpLabel(falselbl->key);
5136 } else if(AOP_TYPE(right) == AOP_CRY ) {
5137 /* we know the left is not a bit, but that the right is */
5138 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5139 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5140 pic16_popGet(AOP(right),offset));
5141 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5143 /* if the two are equal, then W will be 0 and the Z bit is set
5144 * we could test Z now, or go ahead and check the high order bytes if
5145 * the variable we're comparing is larger than a byte. */
5148 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5150 if ( IC_TRUE(ifx) ) {
5152 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5153 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5156 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5157 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5161 /* They're both variables that are larger than bits */
5164 tlbl = newiTempLabel(NULL);
5167 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5168 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5170 if ( IC_TRUE(ifx) ) {
5174 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5176 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5177 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5181 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5184 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5185 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5190 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5192 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5193 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5197 if(s>1 && IC_TRUE(ifx)) {
5198 pic16_emitpLabel(tlbl->key);
5199 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5203 /* mark the icode as generated */
5208 /* if they are both bit variables */
5209 if (AOP_TYPE(left) == AOP_CRY &&
5210 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5211 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5212 if(AOP_TYPE(right) == AOP_LIT){
5213 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5215 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5216 pic16_emitcode("cpl","c");
5217 } else if(lit == 1L) {
5218 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5220 pic16_emitcode("clr","c");
5222 /* AOP_TYPE(right) == AOP_CRY */
5224 symbol *lbl = newiTempLabel(NULL);
5225 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5226 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5227 pic16_emitcode("cpl","c");
5228 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5231 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5232 pic16_outBitC(result);
5236 genIfxJump (ifx,"c");
5239 /* if the result is used in an arithmetic operation
5240 then put the result in place */
5241 pic16_outBitC(result);
5244 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5245 gencjne(left,right,result,ifx);
5248 gencjne(left,right,newiTempLabel(NULL));
5250 if(IC_TRUE(ifx)->key)
5251 gencjne(left,right,IC_TRUE(ifx)->key);
5253 gencjne(left,right,IC_FALSE(ifx)->key);
5257 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5258 pic16_aopPut(AOP(result),"a",0);
5263 genIfxJump (ifx,"a");
5267 /* if the result is used in an arithmetic operation
5268 then put the result in place */
5270 if (AOP_TYPE(result) != AOP_CRY)
5271 pic16_outAcc(result);
5273 /* leave the result in acc */
5277 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5278 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5279 pic16_freeAsmop(result,NULL,ic,TRUE);
5282 /*-----------------------------------------------------------------*/
5283 /* ifxForOp - returns the icode containing the ifx for operand */
5284 /*-----------------------------------------------------------------*/
5285 static iCode *ifxForOp ( operand *op, iCode *ic )
5287 /* if true symbol then needs to be assigned */
5288 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5289 if (IS_TRUE_SYMOP(op))
5292 /* if this has register type condition and
5293 the next instruction is ifx with the same operand
5294 and live to of the operand is upto the ifx only then */
5296 ic->next->op == IFX &&
5297 IC_COND(ic->next)->key == op->key &&
5298 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5302 ic->next->op == IFX &&
5303 IC_COND(ic->next)->key == op->key) {
5304 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5308 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5310 ic->next->op == IFX)
5311 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5314 ic->next->op == IFX &&
5315 IC_COND(ic->next)->key == op->key) {
5316 DEBUGpic16_emitcode ("; "," key is okay");
5317 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5318 OP_SYMBOL(op)->liveTo,
5325 /*-----------------------------------------------------------------*/
5326 /* genAndOp - for && operation */
5327 /*-----------------------------------------------------------------*/
5328 static void genAndOp (iCode *ic)
5330 operand *left,*right, *result;
5333 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5334 /* note here that && operations that are in an
5335 if statement are taken away by backPatchLabels
5336 only those used in arthmetic operations remain */
5337 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5338 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5339 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5341 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5343 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5344 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5345 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5347 /* if both are bit variables */
5348 /* if (AOP_TYPE(left) == AOP_CRY && */
5349 /* AOP_TYPE(right) == AOP_CRY ) { */
5350 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5351 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5352 /* pic16_outBitC(result); */
5354 /* tlbl = newiTempLabel(NULL); */
5355 /* pic16_toBoolean(left); */
5356 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5357 /* pic16_toBoolean(right); */
5358 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5359 /* pic16_outBitAcc(result); */
5362 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5363 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5364 pic16_freeAsmop(result,NULL,ic,TRUE);
5368 /*-----------------------------------------------------------------*/
5369 /* genOrOp - for || operation */
5370 /*-----------------------------------------------------------------*/
5373 modified this code, but it doesn't appear to ever get called
5376 static void genOrOp (iCode *ic)
5378 operand *left,*right, *result;
5381 /* note here that || operations that are in an
5382 if statement are taken away by backPatchLabels
5383 only those used in arthmetic operations remain */
5384 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5385 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5386 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5387 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5389 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5391 /* if both are bit variables */
5392 if (AOP_TYPE(left) == AOP_CRY &&
5393 AOP_TYPE(right) == AOP_CRY ) {
5394 pic16_emitcode("clrc","");
5395 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5396 AOP(left)->aopu.aop_dir,
5397 AOP(left)->aopu.aop_dir);
5398 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5399 AOP(right)->aopu.aop_dir,
5400 AOP(right)->aopu.aop_dir);
5401 pic16_emitcode("setc","");
5404 tlbl = newiTempLabel(NULL);
5405 pic16_toBoolean(left);
5407 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5408 pic16_toBoolean(right);
5409 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5411 pic16_outBitAcc(result);
5414 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5415 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5416 pic16_freeAsmop(result,NULL,ic,TRUE);
5419 /*-----------------------------------------------------------------*/
5420 /* isLiteralBit - test if lit == 2^n */
5421 /*-----------------------------------------------------------------*/
5422 static int isLiteralBit(unsigned long lit)
5424 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5425 0x100L,0x200L,0x400L,0x800L,
5426 0x1000L,0x2000L,0x4000L,0x8000L,
5427 0x10000L,0x20000L,0x40000L,0x80000L,
5428 0x100000L,0x200000L,0x400000L,0x800000L,
5429 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5430 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5433 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5434 for(idx = 0; idx < 32; idx++)
5440 /*-----------------------------------------------------------------*/
5441 /* continueIfTrue - */
5442 /*-----------------------------------------------------------------*/
5443 static void continueIfTrue (iCode *ic)
5445 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5447 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5451 /*-----------------------------------------------------------------*/
5453 /*-----------------------------------------------------------------*/
5454 static void jumpIfTrue (iCode *ic)
5456 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5458 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5462 /*-----------------------------------------------------------------*/
5463 /* jmpTrueOrFalse - */
5464 /*-----------------------------------------------------------------*/
5465 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5467 // ugly but optimized by peephole
5468 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5470 symbol *nlbl = newiTempLabel(NULL);
5471 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5472 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5473 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5474 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5477 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5478 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5483 /*-----------------------------------------------------------------*/
5484 /* genAnd - code for and */
5485 /*-----------------------------------------------------------------*/
5486 static void genAnd (iCode *ic, iCode *ifx)
5488 operand *left, *right, *result;
5490 unsigned long lit = 0L;
5495 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5496 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5497 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5498 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5500 resolveIfx(&rIfx,ifx);
5502 /* if left is a literal & right is not then exchange them */
5503 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5504 AOP_NEEDSACC(left)) {
5505 operand *tmp = right ;
5510 /* if result = right then exchange them */
5511 if(pic16_sameRegs(AOP(result),AOP(right))){
5512 operand *tmp = right ;
5517 /* if right is bit then exchange them */
5518 if (AOP_TYPE(right) == AOP_CRY &&
5519 AOP_TYPE(left) != AOP_CRY){
5520 operand *tmp = right ;
5524 if(AOP_TYPE(right) == AOP_LIT)
5525 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5527 size = AOP_SIZE(result);
5529 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5532 // result = bit & yy;
5533 if (AOP_TYPE(left) == AOP_CRY){
5534 // c = bit & literal;
5535 if(AOP_TYPE(right) == AOP_LIT){
5537 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5540 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5543 if(size && (AOP_TYPE(result) == AOP_CRY)){
5544 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5547 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5551 pic16_emitcode("clr","c");
5554 if (AOP_TYPE(right) == AOP_CRY){
5556 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5557 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5560 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5562 pic16_emitcode("rrc","a");
5563 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5569 pic16_outBitC(result);
5571 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5572 genIfxJump(ifx, "c");
5576 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5577 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5578 if((AOP_TYPE(right) == AOP_LIT) &&
5579 (AOP_TYPE(result) == AOP_CRY) &&
5580 (AOP_TYPE(left) != AOP_CRY)){
5581 int posbit = isLiteralBit(lit);
5585 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5588 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5594 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5595 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5597 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5598 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5601 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5602 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5603 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5610 symbol *tlbl = newiTempLabel(NULL);
5611 int sizel = AOP_SIZE(left);
5613 pic16_emitcode("setb","c");
5615 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5616 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5618 if((posbit = isLiteralBit(bytelit)) != 0)
5619 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5621 if(bytelit != 0x0FFL)
5622 pic16_emitcode("anl","a,%s",
5623 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5624 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5629 // bit = left & literal
5631 pic16_emitcode("clr","c");
5632 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5634 // if(left & literal)
5637 jmpTrueOrFalse(ifx, tlbl);
5641 pic16_outBitC(result);
5645 /* if left is same as result */
5646 if(pic16_sameRegs(AOP(result),AOP(left))){
5648 for(;size--; offset++,lit>>=8) {
5649 if(AOP_TYPE(right) == AOP_LIT){
5650 switch(lit & 0xff) {
5652 /* and'ing with 0 has clears the result */
5653 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5654 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5657 /* and'ing with 0xff is a nop when the result and left are the same */
5662 int p = my_powof2( (~lit) & 0xff );
5664 /* only one bit is set in the literal, so use a bcf instruction */
5665 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5666 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5669 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5670 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5671 if(know_W != (lit&0xff))
5672 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5674 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5679 if (AOP_TYPE(left) == AOP_ACC) {
5680 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5682 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5683 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5690 // left & result in different registers
5691 if(AOP_TYPE(result) == AOP_CRY){
5693 // if(size), result in bit
5694 // if(!size && ifx), conditional oper: if(left & right)
5695 symbol *tlbl = newiTempLabel(NULL);
5696 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5698 pic16_emitcode("setb","c");
5700 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5701 pic16_emitcode("anl","a,%s",
5702 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5703 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5708 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5709 pic16_outBitC(result);
5711 jmpTrueOrFalse(ifx, tlbl);
5713 for(;(size--);offset++) {
5715 // result = left & right
5716 if(AOP_TYPE(right) == AOP_LIT){
5717 int t = (lit >> (offset*8)) & 0x0FFL;
5720 pic16_emitcode("clrf","%s",
5721 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5722 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5725 pic16_emitcode("movf","%s,w",
5726 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5727 pic16_emitcode("movwf","%s",
5728 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5729 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5730 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5733 pic16_emitcode("movlw","0x%x",t);
5734 pic16_emitcode("andwf","%s,w",
5735 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5736 pic16_emitcode("movwf","%s",
5737 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5739 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5740 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5741 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5746 if (AOP_TYPE(left) == AOP_ACC) {
5747 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5748 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5750 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5751 pic16_emitcode("andwf","%s,w",
5752 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5753 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5754 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5756 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5757 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5763 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5764 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5765 pic16_freeAsmop(result,NULL,ic,TRUE);
5768 /*-----------------------------------------------------------------*/
5769 /* genOr - code for or */
5770 /*-----------------------------------------------------------------*/
5771 static void genOr (iCode *ic, iCode *ifx)
5773 operand *left, *right, *result;
5775 unsigned long lit = 0L;
5777 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5779 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5780 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5781 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5783 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5785 /* if left is a literal & right is not then exchange them */
5786 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5787 AOP_NEEDSACC(left)) {
5788 operand *tmp = right ;
5793 /* if result = right then exchange them */
5794 if(pic16_sameRegs(AOP(result),AOP(right))){
5795 operand *tmp = right ;
5800 /* if right is bit then exchange them */
5801 if (AOP_TYPE(right) == AOP_CRY &&
5802 AOP_TYPE(left) != AOP_CRY){
5803 operand *tmp = right ;
5808 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5810 if(AOP_TYPE(right) == AOP_LIT)
5811 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5813 size = AOP_SIZE(result);
5817 if (AOP_TYPE(left) == AOP_CRY){
5818 if(AOP_TYPE(right) == AOP_LIT){
5819 // c = bit & literal;
5821 // lit != 0 => result = 1
5822 if(AOP_TYPE(result) == AOP_CRY){
5824 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5825 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5826 // AOP(result)->aopu.aop_dir,
5827 // AOP(result)->aopu.aop_dir);
5829 continueIfTrue(ifx);
5833 // lit == 0 => result = left
5834 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5836 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5839 if (AOP_TYPE(right) == AOP_CRY){
5840 if(pic16_sameRegs(AOP(result),AOP(left))){
5842 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5843 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5844 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5846 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5847 AOP(result)->aopu.aop_dir,
5848 AOP(result)->aopu.aop_dir);
5849 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5850 AOP(right)->aopu.aop_dir,
5851 AOP(right)->aopu.aop_dir);
5852 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5853 AOP(result)->aopu.aop_dir,
5854 AOP(result)->aopu.aop_dir);
5856 if( AOP_TYPE(result) == AOP_ACC) {
5857 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5858 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5859 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5860 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5864 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5865 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5866 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5867 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5869 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5870 AOP(result)->aopu.aop_dir,
5871 AOP(result)->aopu.aop_dir);
5872 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5873 AOP(right)->aopu.aop_dir,
5874 AOP(right)->aopu.aop_dir);
5875 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5876 AOP(left)->aopu.aop_dir,
5877 AOP(left)->aopu.aop_dir);
5878 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5879 AOP(result)->aopu.aop_dir,
5880 AOP(result)->aopu.aop_dir);
5885 symbol *tlbl = newiTempLabel(NULL);
5886 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5889 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5890 if( AOP_TYPE(right) == AOP_ACC) {
5891 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5893 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5894 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5899 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5900 pic16_emitcode(";XXX setb","c");
5901 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5902 AOP(left)->aopu.aop_dir,tlbl->key+100);
5903 pic16_toBoolean(right);
5904 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5905 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5906 jmpTrueOrFalse(ifx, tlbl);
5910 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5917 pic16_outBitC(result);
5919 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5920 genIfxJump(ifx, "c");
5924 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5925 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5926 if((AOP_TYPE(right) == AOP_LIT) &&
5927 (AOP_TYPE(result) == AOP_CRY) &&
5928 (AOP_TYPE(left) != AOP_CRY)){
5930 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5933 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5935 continueIfTrue(ifx);
5938 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5939 // lit = 0, result = boolean(left)
5941 pic16_emitcode(";XXX setb","c");
5942 pic16_toBoolean(right);
5944 symbol *tlbl = newiTempLabel(NULL);
5945 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5947 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5949 genIfxJump (ifx,"a");
5953 pic16_outBitC(result);
5957 /* if left is same as result */
5958 if(pic16_sameRegs(AOP(result),AOP(left))){
5960 for(;size--; offset++,lit>>=8) {
5961 if(AOP_TYPE(right) == AOP_LIT){
5962 if((lit & 0xff) == 0)
5963 /* or'ing with 0 has no effect */
5966 int p = my_powof2(lit & 0xff);
5968 /* only one bit is set in the literal, so use a bsf instruction */
5969 pic16_emitpcode(POC_BSF,
5970 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5972 if(know_W != (lit & 0xff))
5973 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5974 know_W = lit & 0xff;
5975 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5980 if (AOP_TYPE(left) == AOP_ACC) {
5981 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5982 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5984 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5985 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5987 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5988 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5994 // left & result in different registers
5995 if(AOP_TYPE(result) == AOP_CRY){
5997 // if(size), result in bit
5998 // if(!size && ifx), conditional oper: if(left | right)
5999 symbol *tlbl = newiTempLabel(NULL);
6000 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6001 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6005 pic16_emitcode(";XXX setb","c");
6007 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6008 pic16_emitcode(";XXX orl","a,%s",
6009 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6010 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6015 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6016 pic16_outBitC(result);
6018 jmpTrueOrFalse(ifx, tlbl);
6019 } else for(;(size--);offset++){
6021 // result = left & right
6022 if(AOP_TYPE(right) == AOP_LIT){
6023 int t = (lit >> (offset*8)) & 0x0FFL;
6026 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6027 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6029 pic16_emitcode("movf","%s,w",
6030 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6031 pic16_emitcode("movwf","%s",
6032 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6035 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6036 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6037 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6039 pic16_emitcode("movlw","0x%x",t);
6040 pic16_emitcode("iorwf","%s,w",
6041 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6042 pic16_emitcode("movwf","%s",
6043 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6049 // faster than result <- left, anl result,right
6050 // and better if result is SFR
6051 if (AOP_TYPE(left) == AOP_ACC) {
6052 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6053 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6055 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6056 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6058 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6059 pic16_emitcode("iorwf","%s,w",
6060 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6062 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6063 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6068 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6069 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6070 pic16_freeAsmop(result,NULL,ic,TRUE);
6073 /*-----------------------------------------------------------------*/
6074 /* genXor - code for xclusive or */
6075 /*-----------------------------------------------------------------*/
6076 static void genXor (iCode *ic, iCode *ifx)
6078 operand *left, *right, *result;
6080 unsigned long lit = 0L;
6082 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6084 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6085 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6086 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6088 /* if left is a literal & right is not ||
6089 if left needs acc & right does not */
6090 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6091 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6092 operand *tmp = right ;
6097 /* if result = right then exchange them */
6098 if(pic16_sameRegs(AOP(result),AOP(right))){
6099 operand *tmp = right ;
6104 /* if right is bit then exchange them */
6105 if (AOP_TYPE(right) == AOP_CRY &&
6106 AOP_TYPE(left) != AOP_CRY){
6107 operand *tmp = right ;
6111 if(AOP_TYPE(right) == AOP_LIT)
6112 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6114 size = AOP_SIZE(result);
6118 if (AOP_TYPE(left) == AOP_CRY){
6119 if(AOP_TYPE(right) == AOP_LIT){
6120 // c = bit & literal;
6122 // lit>>1 != 0 => result = 1
6123 if(AOP_TYPE(result) == AOP_CRY){
6125 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6126 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6128 continueIfTrue(ifx);
6131 pic16_emitcode("setb","c");
6135 // lit == 0, result = left
6136 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6138 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6140 // lit == 1, result = not(left)
6141 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6142 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6143 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6144 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6147 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6148 pic16_emitcode("cpl","c");
6155 symbol *tlbl = newiTempLabel(NULL);
6156 if (AOP_TYPE(right) == AOP_CRY){
6158 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6161 int sizer = AOP_SIZE(right);
6163 // if val>>1 != 0, result = 1
6164 pic16_emitcode("setb","c");
6166 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6168 // test the msb of the lsb
6169 pic16_emitcode("anl","a,#0xfe");
6170 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6174 pic16_emitcode("rrc","a");
6176 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6177 pic16_emitcode("cpl","c");
6178 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6183 pic16_outBitC(result);
6185 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6186 genIfxJump(ifx, "c");
6190 if(pic16_sameRegs(AOP(result),AOP(left))){
6191 /* if left is same as result */
6192 for(;size--; offset++) {
6193 if(AOP_TYPE(right) == AOP_LIT){
6194 int t = (lit >> (offset*8)) & 0x0FFL;
6198 if (IS_AOP_PREG(left)) {
6199 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6200 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6201 pic16_aopPut(AOP(result),"a",offset);
6203 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6204 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6205 pic16_emitcode("xrl","%s,%s",
6206 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6207 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6210 if (AOP_TYPE(left) == AOP_ACC)
6211 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6213 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6214 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6216 if (IS_AOP_PREG(left)) {
6217 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6218 pic16_aopPut(AOP(result),"a",offset);
6220 pic16_emitcode("xrl","%s,a",
6221 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6227 // left & result in different registers
6228 if(AOP_TYPE(result) == AOP_CRY){
6230 // if(size), result in bit
6231 // if(!size && ifx), conditional oper: if(left ^ right)
6232 symbol *tlbl = newiTempLabel(NULL);
6233 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6235 pic16_emitcode("setb","c");
6237 if((AOP_TYPE(right) == AOP_LIT) &&
6238 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6239 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6241 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6242 pic16_emitcode("xrl","a,%s",
6243 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6245 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6250 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6251 pic16_outBitC(result);
6253 jmpTrueOrFalse(ifx, tlbl);
6254 } else for(;(size--);offset++){
6256 // result = left & right
6257 if(AOP_TYPE(right) == AOP_LIT){
6258 int t = (lit >> (offset*8)) & 0x0FFL;
6261 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6262 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6263 pic16_emitcode("movf","%s,w",
6264 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6265 pic16_emitcode("movwf","%s",
6266 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6269 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6270 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6271 pic16_emitcode("comf","%s,w",
6272 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6273 pic16_emitcode("movwf","%s",
6274 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6277 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6278 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6279 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6280 pic16_emitcode("movlw","0x%x",t);
6281 pic16_emitcode("xorwf","%s,w",
6282 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6283 pic16_emitcode("movwf","%s",
6284 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6290 // faster than result <- left, anl result,right
6291 // and better if result is SFR
6292 if (AOP_TYPE(left) == AOP_ACC) {
6293 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6294 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6296 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6297 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6298 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6299 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6301 if ( AOP_TYPE(result) != AOP_ACC){
6302 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6303 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6309 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6310 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6311 pic16_freeAsmop(result,NULL,ic,TRUE);
6314 /*-----------------------------------------------------------------*/
6315 /* genInline - write the inline code out */
6316 /*-----------------------------------------------------------------*/
6317 static void genInline (iCode *ic)
6319 char *buffer, *bp, *bp1;
6321 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6323 _G.inLine += (!options.asmpeep);
6325 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6326 strcpy(buffer,IC_INLINE(ic));
6328 /* emit each line as a code */
6334 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6335 // inline directly, no process
6342 pic16_emitcode(bp1,"");
6348 if ((bp1 != bp) && *bp1)
6349 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6353 _G.inLine -= (!options.asmpeep);
6356 /*-----------------------------------------------------------------*/
6357 /* genRRC - rotate right with carry */
6358 /*-----------------------------------------------------------------*/
6359 static void genRRC (iCode *ic)
6361 operand *left , *result ;
6362 int size, offset = 0, same;
6364 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6366 /* rotate right with carry */
6368 result=IC_RESULT(ic);
6369 pic16_aopOp (left,ic,FALSE);
6370 pic16_aopOp (result,ic,FALSE);
6372 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6374 same = pic16_sameRegs(AOP(result),AOP(left));
6376 size = AOP_SIZE(result);
6378 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6380 /* get the lsb and put it into the carry */
6381 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6388 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6390 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6391 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6397 pic16_freeAsmop(left,NULL,ic,TRUE);
6398 pic16_freeAsmop(result,NULL,ic,TRUE);
6401 /*-----------------------------------------------------------------*/
6402 /* genRLC - generate code for rotate left with carry */
6403 /*-----------------------------------------------------------------*/
6404 static void genRLC (iCode *ic)
6406 operand *left , *result ;
6407 int size, offset = 0;
6410 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6411 /* rotate right with carry */
6413 result=IC_RESULT(ic);
6414 pic16_aopOp (left,ic,FALSE);
6415 pic16_aopOp (result,ic,FALSE);
6417 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6419 same = pic16_sameRegs(AOP(result),AOP(left));
6421 /* move it to the result */
6422 size = AOP_SIZE(result);
6424 /* get the msb and put it into the carry */
6425 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6432 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6434 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6435 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6442 pic16_freeAsmop(left,NULL,ic,TRUE);
6443 pic16_freeAsmop(result,NULL,ic,TRUE);
6446 /*-----------------------------------------------------------------*/
6447 /* genGetHbit - generates code get highest order bit */
6448 /*-----------------------------------------------------------------*/
6449 static void genGetHbit (iCode *ic)
6451 operand *left, *result;
6453 result=IC_RESULT(ic);
6454 pic16_aopOp (left,ic,FALSE);
6455 pic16_aopOp (result,ic,FALSE);
6457 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6458 /* get the highest order byte into a */
6459 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6460 if(AOP_TYPE(result) == AOP_CRY){
6461 pic16_emitcode("rlc","a");
6462 pic16_outBitC(result);
6465 pic16_emitcode("rl","a");
6466 pic16_emitcode("anl","a,#0x01");
6467 pic16_outAcc(result);
6471 pic16_freeAsmop(left,NULL,ic,TRUE);
6472 pic16_freeAsmop(result,NULL,ic,TRUE);
6476 /*-----------------------------------------------------------------*/
6477 /* AccRol - rotate left accumulator by known count */
6478 /*-----------------------------------------------------------------*/
6479 static void AccRol (int shCount)
6481 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6482 shCount &= 0x0007; // shCount : 0..7
6487 pic16_emitcode("rl","a");
6490 pic16_emitcode("rl","a");
6491 pic16_emitcode("rl","a");
6494 pic16_emitcode("swap","a");
6495 pic16_emitcode("rr","a");
6498 pic16_emitcode("swap","a");
6501 pic16_emitcode("swap","a");
6502 pic16_emitcode("rl","a");
6505 pic16_emitcode("rr","a");
6506 pic16_emitcode("rr","a");
6509 pic16_emitcode("rr","a");
6515 /*-----------------------------------------------------------------*/
6516 /* AccLsh - left shift accumulator by known count */
6517 /*-----------------------------------------------------------------*/
6518 static void AccLsh (int shCount)
6520 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6526 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6529 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6530 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6533 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6534 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6537 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6540 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6541 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6544 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6545 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6548 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6551 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
6555 /*-----------------------------------------------------------------*/
6556 /* AccRsh - right shift accumulator by known count */
6557 /*-----------------------------------------------------------------*/
6558 static void AccRsh (int shCount)
6560 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6566 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6569 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6570 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6573 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6574 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6577 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6580 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6581 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6584 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6585 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6588 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6591 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
6595 /*-----------------------------------------------------------------*/
6596 /* AccSRsh - signed right shift accumulator by known count */
6597 /*-----------------------------------------------------------------*/
6598 static void AccSRsh (int shCount)
6601 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6604 pic16_emitcode("mov","c,acc.7");
6605 pic16_emitcode("rrc","a");
6606 } else if(shCount == 2){
6607 pic16_emitcode("mov","c,acc.7");
6608 pic16_emitcode("rrc","a");
6609 pic16_emitcode("mov","c,acc.7");
6610 pic16_emitcode("rrc","a");
6612 tlbl = newiTempLabel(NULL);
6613 /* rotate right accumulator */
6614 AccRol(8 - shCount);
6615 /* and kill the higher order bits */
6616 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6617 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6618 pic16_emitcode("orl","a,#0x%02x",
6619 (unsigned char)~SRMask[shCount]);
6620 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6625 /*-----------------------------------------------------------------*/
6626 /* shiftR1Left2Result - shift right one byte from left to result */
6627 /*-----------------------------------------------------------------*/
6628 static void shiftR1Left2ResultSigned (operand *left, int offl,
6629 operand *result, int offr,
6634 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6636 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6640 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6642 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6644 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6645 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6651 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6653 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6655 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6656 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6658 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6659 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6665 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6667 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6668 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6671 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6672 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6673 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6675 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6676 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6678 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6682 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6683 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6684 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6685 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6686 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6690 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6692 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6693 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6695 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6696 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6697 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6698 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6699 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6704 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6705 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6706 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6707 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6708 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6709 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6711 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6712 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6713 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6714 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6715 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6721 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6722 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6723 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6724 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6726 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6727 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6728 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6736 /*-----------------------------------------------------------------*/
6737 /* shiftR1Left2Result - shift right one byte from left to result */
6738 /*-----------------------------------------------------------------*/
6739 static void shiftR1Left2Result (operand *left, int offl,
6740 operand *result, int offr,
6741 int shCount, int sign)
6745 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6747 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6749 /* Copy the msb into the carry if signed. */
6751 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6761 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6763 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6764 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6770 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6772 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6773 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6776 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6781 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6783 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6784 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6787 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6788 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6789 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6790 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6794 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6795 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6796 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6800 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6801 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6802 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6804 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6809 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6810 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6811 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6812 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6813 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6818 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6819 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6820 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6829 /*-----------------------------------------------------------------*/
6830 /* shiftL1Left2Result - shift left one byte from left to result */
6831 /*-----------------------------------------------------------------*/
6832 static void shiftL1Left2Result (operand *left, int offl,
6833 operand *result, int offr, int shCount)
6838 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6840 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6841 DEBUGpic16_emitcode ("; ***","same = %d",same);
6842 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6844 /* shift left accumulator */
6845 //AccLsh(shCount); // don't comment out just yet...
6846 // pic16_aopPut(AOP(result),"a",offr);
6850 /* Shift left 1 bit position */
6851 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6853 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6855 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6856 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6860 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6861 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6862 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6863 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6866 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6867 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6868 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6869 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6870 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6873 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6874 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6875 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6878 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6879 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6880 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6881 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6884 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6885 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6886 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6887 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6888 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6891 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6892 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6893 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6897 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6902 /*-----------------------------------------------------------------*/
6903 /* movLeft2Result - move byte from left to result */
6904 /*-----------------------------------------------------------------*/
6905 static void movLeft2Result (operand *left, int offl,
6906 operand *result, int offr)
6909 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6910 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6911 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6913 if (*l == '@' && (IS_AOP_PREG(result))) {
6914 pic16_emitcode("mov","a,%s",l);
6915 pic16_aopPut(AOP(result),"a",offr);
6917 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6918 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6923 /*-----------------------------------------------------------------*/
6924 /* shiftL2Left2Result - shift left two bytes from left to result */
6925 /*-----------------------------------------------------------------*/
6926 static void shiftL2Left2Result (operand *left, int offl,
6927 operand *result, int offr, int shCount)
6929 int same = pic16_sameRegs(AOP(result), AOP(left));
6932 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
6934 if (same && (offl != offr)) { // shift bytes
6937 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
6938 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
6940 } else { // just treat as different later on
6953 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6954 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6955 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6959 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6960 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6966 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6967 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6968 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6969 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6970 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6971 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6972 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6974 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6975 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6979 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6980 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6981 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6982 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6983 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6984 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6985 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6986 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6987 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6988 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6991 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6992 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6993 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6994 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6995 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7005 /* note, use a mov/add for the shift since the mov has a
7006 chance of getting optimized out */
7007 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7008 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7009 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7010 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7011 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7015 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7016 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7022 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7023 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7024 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7025 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7026 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7027 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7028 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7029 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7033 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7034 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7038 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7039 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7040 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7041 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7043 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7044 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7045 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7046 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7047 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7048 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7049 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7050 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7053 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7054 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7055 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7056 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7057 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7062 /*-----------------------------------------------------------------*/
7063 /* shiftR2Left2Result - shift right two bytes from left to result */
7064 /*-----------------------------------------------------------------*/
7065 static void shiftR2Left2Result (operand *left, int offl,
7066 operand *result, int offr,
7067 int shCount, int sign)
7069 int same = pic16_sameRegs(AOP(result), AOP(left));
7071 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7073 if (same && (offl != offr)) { // shift right bytes
7076 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7077 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7079 } else { // just treat as different later on
7091 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7096 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7097 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7099 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7100 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7101 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7102 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7107 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7110 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7111 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7118 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7119 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7120 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7122 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7123 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7124 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7125 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7127 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7128 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7129 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7131 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7132 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7133 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7134 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7135 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7139 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7140 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7144 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7145 pic16_emitpcode(POC_BTFSC,
7146 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7147 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7155 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7156 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7158 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7159 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7160 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7161 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7163 pic16_emitpcode(POC_BTFSC,
7164 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7165 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7167 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7168 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7169 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7170 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7172 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7173 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7174 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7175 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7176 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7177 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7178 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7179 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7181 pic16_emitpcode(POC_BTFSC,
7182 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7183 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7185 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7186 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7193 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7194 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7195 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7196 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7199 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7201 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7206 /*-----------------------------------------------------------------*/
7207 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7208 /*-----------------------------------------------------------------*/
7209 static void shiftLLeftOrResult (operand *left, int offl,
7210 operand *result, int offr, int shCount)
7212 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7214 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7215 /* shift left accumulator */
7217 /* or with result */
7218 /* back to result */
7219 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7222 /*-----------------------------------------------------------------*/
7223 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7224 /*-----------------------------------------------------------------*/
7225 static void shiftRLeftOrResult (operand *left, int offl,
7226 operand *result, int offr, int shCount)
7228 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7230 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7231 /* shift right accumulator */
7233 /* or with result */
7234 /* back to result */
7235 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7238 /*-----------------------------------------------------------------*/
7239 /* genlshOne - left shift a one byte quantity by known count */
7240 /*-----------------------------------------------------------------*/
7241 static void genlshOne (operand *result, operand *left, int shCount)
7243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7244 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7247 /*-----------------------------------------------------------------*/
7248 /* genlshTwo - left shift two bytes by known amount != 0 */
7249 /*-----------------------------------------------------------------*/
7250 static void genlshTwo (operand *result,operand *left, int shCount)
7254 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7255 size = pic16_getDataSize(result);
7257 /* if shCount >= 8 */
7263 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7265 movLeft2Result(left, LSB, result, MSB16);
7267 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7270 /* 1 <= shCount <= 7 */
7273 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7275 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7279 /*-----------------------------------------------------------------*/
7280 /* shiftLLong - shift left one long from left to result */
7281 /* offr = LSB or MSB16 */
7282 /*-----------------------------------------------------------------*/
7283 static void shiftLLong (operand *left, operand *result, int offr )
7285 int size = AOP_SIZE(result);
7286 int same = pic16_sameRegs(AOP(left),AOP(result));
7289 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7291 if (same && (offr == MSB16)) { //shift one byte
7292 for(i=size-1;i>=MSB16;i--) {
7293 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7294 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7297 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7300 if (size >= LSB+offr ){
7302 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7304 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7305 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7309 if(size >= MSB16+offr){
7311 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7313 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7314 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7318 if(size >= MSB24+offr){
7320 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7322 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7323 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7327 if(size > MSB32+offr){
7329 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7331 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7332 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7336 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7340 /*-----------------------------------------------------------------*/
7341 /* genlshFour - shift four byte by a known amount != 0 */
7342 /*-----------------------------------------------------------------*/
7343 static void genlshFour (operand *result, operand *left, int shCount)
7347 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7348 size = AOP_SIZE(result);
7350 /* if shifting more that 3 bytes */
7351 if (shCount >= 24 ) {
7354 /* lowest order of left goes to the highest
7355 order of the destination */
7356 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7358 movLeft2Result(left, LSB, result, MSB32);
7360 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7361 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7362 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7367 /* more than two bytes */
7368 else if ( shCount >= 16 ) {
7369 /* lower order two bytes goes to higher order two bytes */
7371 /* if some more remaining */
7373 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7375 movLeft2Result(left, MSB16, result, MSB32);
7376 movLeft2Result(left, LSB, result, MSB24);
7378 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7379 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7383 /* if more than 1 byte */
7384 else if ( shCount >= 8 ) {
7385 /* lower order three bytes goes to higher order three bytes */
7389 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7391 movLeft2Result(left, LSB, result, MSB16);
7393 else{ /* size = 4 */
7395 movLeft2Result(left, MSB24, result, MSB32);
7396 movLeft2Result(left, MSB16, result, MSB24);
7397 movLeft2Result(left, LSB, result, MSB16);
7398 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7400 else if(shCount == 1)
7401 shiftLLong(left, result, MSB16);
7403 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7404 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7405 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7406 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7411 /* 1 <= shCount <= 7 */
7412 else if(shCount <= 3)
7414 shiftLLong(left, result, LSB);
7415 while(--shCount >= 1)
7416 shiftLLong(result, result, LSB);
7418 /* 3 <= shCount <= 7, optimize */
7420 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7421 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7422 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7426 /*-----------------------------------------------------------------*/
7427 /* genLeftShiftLiteral - left shifting by known count */
7428 /*-----------------------------------------------------------------*/
7429 static void genLeftShiftLiteral (operand *left,
7434 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7437 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7438 pic16_freeAsmop(right,NULL,ic,TRUE);
7440 pic16_aopOp(left,ic,FALSE);
7441 pic16_aopOp(result,ic,FALSE);
7443 size = getSize(operandType(result));
7446 pic16_emitcode("; shift left ","result %d, left %d",size,
7450 /* I suppose that the left size >= result size */
7453 movLeft2Result(left, size, result, size);
7457 else if(shCount >= (size * 8))
7459 pic16_aopPut(AOP(result),zero,size);
7463 genlshOne (result,left,shCount);
7468 genlshTwo (result,left,shCount);
7472 genlshFour (result,left,shCount);
7476 pic16_freeAsmop(left,NULL,ic,TRUE);
7477 pic16_freeAsmop(result,NULL,ic,TRUE);
7480 /*-----------------------------------------------------------------*
7481 * genMultiAsm - repeat assembly instruction for size of register.
7482 * if endian == 1, then the high byte (i.e base address + size of
7483 * register) is used first else the low byte is used first;
7484 *-----------------------------------------------------------------*/
7485 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7490 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7503 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7508 /*-----------------------------------------------------------------*/
7509 /* genLeftShift - generates code for left shifting */
7510 /*-----------------------------------------------------------------*/
7511 static void genLeftShift (iCode *ic)
7513 operand *left,*right, *result;
7516 symbol *tlbl , *tlbl1;
7519 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7521 right = IC_RIGHT(ic);
7523 result = IC_RESULT(ic);
7525 pic16_aopOp(right,ic,FALSE);
7527 /* if the shift count is known then do it
7528 as efficiently as possible */
7529 if (AOP_TYPE(right) == AOP_LIT) {
7530 genLeftShiftLiteral (left,right,result,ic);
7534 /* shift count is unknown then we have to form
7535 a loop get the loop count in B : Note: we take
7536 only the lower order byte since shifting
7537 more that 32 bits make no sense anyway, ( the
7538 largest size of an object can be only 32 bits ) */
7541 pic16_aopOp(left,ic,FALSE);
7542 pic16_aopOp(result,ic,FALSE);
7544 /* now move the left to the result if they are not the
7546 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7547 AOP_SIZE(result) > 1) {
7549 size = AOP_SIZE(result);
7552 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7553 if (*l == '@' && (IS_AOP_PREG(result))) {
7555 pic16_emitcode("mov","a,%s",l);
7556 pic16_aopPut(AOP(result),"a",offset);
7558 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7559 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7560 //pic16_aopPut(AOP(result),l,offset);
7566 size = AOP_SIZE(result);
7568 /* if it is only one byte then */
7570 if(optimized_for_speed) {
7571 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7572 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7573 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7574 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7575 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7576 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7577 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7578 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7579 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7580 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7581 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7582 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7585 tlbl = newiTempLabel(NULL);
7586 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7587 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7588 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7591 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7592 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7593 pic16_emitpLabel(tlbl->key);
7594 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7595 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7597 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7602 if (pic16_sameRegs(AOP(left),AOP(result))) {
7604 tlbl = newiTempLabel(NULL);
7605 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7606 genMultiAsm(POC_RRCF, result, size,1);
7607 pic16_emitpLabel(tlbl->key);
7608 genMultiAsm(POC_RLCF, result, size,0);
7609 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7611 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7615 //tlbl = newiTempLabel(NULL);
7617 //tlbl1 = newiTempLabel(NULL);
7619 //reAdjustPreg(AOP(result));
7621 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7622 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7623 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7625 //pic16_emitcode("add","a,acc");
7626 //pic16_aopPut(AOP(result),"a",offset++);
7628 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7630 // pic16_emitcode("rlc","a");
7631 // pic16_aopPut(AOP(result),"a",offset++);
7633 //reAdjustPreg(AOP(result));
7635 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7636 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7639 tlbl = newiTempLabel(NULL);
7640 tlbl1= newiTempLabel(NULL);
7642 size = AOP_SIZE(result);
7645 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7647 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7649 /* offset should be 0, 1 or 3 */
7651 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
7653 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7655 pic16_emitpcode(POC_MOVWF, pctemp);
7658 pic16_emitpLabel(tlbl->key);
7661 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7663 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7665 pic16_emitpcode(POC_DECFSZ, pctemp);
7666 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7667 pic16_emitpLabel(tlbl1->key);
7669 pic16_popReleaseTempReg(pctemp);
7673 pic16_freeAsmop (right,NULL,ic,TRUE);
7674 pic16_freeAsmop(left,NULL,ic,TRUE);
7675 pic16_freeAsmop(result,NULL,ic,TRUE);
7678 /*-----------------------------------------------------------------*/
7679 /* genrshOne - right shift a one byte quantity by known count */
7680 /*-----------------------------------------------------------------*/
7681 static void genrshOne (operand *result, operand *left,
7682 int shCount, int sign)
7684 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7685 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7688 /*-----------------------------------------------------------------*/
7689 /* genrshTwo - right shift two bytes by known amount != 0 */
7690 /*-----------------------------------------------------------------*/
7691 static void genrshTwo (operand *result,operand *left,
7692 int shCount, int sign)
7694 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7695 /* if shCount >= 8 */
7699 shiftR1Left2Result(left, MSB16, result, LSB,
7702 movLeft2Result(left, MSB16, result, LSB);
7704 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7707 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7708 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7712 /* 1 <= shCount <= 7 */
7714 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7717 /*-----------------------------------------------------------------*/
7718 /* shiftRLong - shift right one long from left to result */
7719 /* offl = LSB or MSB16 */
7720 /*-----------------------------------------------------------------*/
7721 static void shiftRLong (operand *left, int offl,
7722 operand *result, int sign)
7724 int size = AOP_SIZE(result);
7725 int same = pic16_sameRegs(AOP(left),AOP(result));
7727 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7729 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
7731 if (same && (offl == MSB16)) { //shift one byte right
7732 for(i=MSB16;i<size;i++) {
7733 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
7734 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
7739 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
7745 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
7747 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
7748 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
7752 /* add sign of "a" */
7753 pic16_addSign(result, MSB32, sign);
7757 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
7759 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
7760 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
7764 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
7766 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
7767 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
7771 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
7774 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
7775 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
7780 /*-----------------------------------------------------------------*/
7781 /* genrshFour - shift four byte by a known amount != 0 */
7782 /*-----------------------------------------------------------------*/
7783 static void genrshFour (operand *result, operand *left,
7784 int shCount, int sign)
7786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7787 /* if shifting more that 3 bytes */
7788 if(shCount >= 24 ) {
7791 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7793 movLeft2Result(left, MSB32, result, LSB);
7795 pic16_addSign(result, MSB16, sign);
7797 else if(shCount >= 16){
7800 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7802 movLeft2Result(left, MSB24, result, LSB);
7803 movLeft2Result(left, MSB32, result, MSB16);
7805 pic16_addSign(result, MSB24, sign);
7807 else if(shCount >= 8){
7810 shiftRLong(left, MSB16, result, sign);
7811 else if(shCount == 0){
7812 movLeft2Result(left, MSB16, result, LSB);
7813 movLeft2Result(left, MSB24, result, MSB16);
7814 movLeft2Result(left, MSB32, result, MSB24);
7815 pic16_addSign(result, MSB32, sign);
7817 else{ //shcount >= 2
7818 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7819 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7820 /* the last shift is signed */
7821 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7822 pic16_addSign(result, MSB32, sign);
7825 else{ /* 1 <= shCount <= 7 */
7827 shiftRLong(left, LSB, result, sign);
7829 shiftRLong(result, LSB, result, sign);
7832 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7833 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7834 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7839 /*-----------------------------------------------------------------*/
7840 /* genRightShiftLiteral - right shifting by known count */
7841 /*-----------------------------------------------------------------*/
7842 static void genRightShiftLiteral (operand *left,
7848 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7851 pic16_freeAsmop(right,NULL,ic,TRUE);
7853 pic16_aopOp(left,ic,FALSE);
7854 pic16_aopOp(result,ic,FALSE);
7856 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
7859 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7863 lsize = pic16_getDataSize(left);
7864 res_size = pic16_getDataSize(result);
7865 /* test the LEFT size !!! */
7867 /* I suppose that the left size >= result size */
7870 movLeft2Result(left, lsize, result, res_size);
7873 else if(shCount >= (lsize * 8)){
7876 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7878 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7879 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7884 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7885 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7886 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7888 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7893 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7900 genrshOne (result,left,shCount,sign);
7904 genrshTwo (result,left,shCount,sign);
7908 genrshFour (result,left,shCount,sign);
7916 pic16_freeAsmop(left,NULL,ic,TRUE);
7917 pic16_freeAsmop(result,NULL,ic,TRUE);
7920 /*-----------------------------------------------------------------*/
7921 /* genSignedRightShift - right shift of signed number */
7922 /*-----------------------------------------------------------------*/
7923 static void genSignedRightShift (iCode *ic)
7925 operand *right, *left, *result;
7928 symbol *tlbl, *tlbl1 ;
7931 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7933 /* we do it the hard way put the shift count in b
7934 and loop thru preserving the sign */
7935 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7937 right = IC_RIGHT(ic);
7939 result = IC_RESULT(ic);
7941 pic16_aopOp(right,ic,FALSE);
7942 pic16_aopOp(left,ic,FALSE);
7943 pic16_aopOp(result,ic,FALSE);
7946 if ( AOP_TYPE(right) == AOP_LIT) {
7947 genRightShiftLiteral (left,right,result,ic,1);
7950 /* shift count is unknown then we have to form
7951 a loop get the loop count in B : Note: we take
7952 only the lower order byte since shifting
7953 more that 32 bits make no sense anyway, ( the
7954 largest size of an object can be only 32 bits ) */
7956 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7957 //pic16_emitcode("inc","b");
7958 //pic16_freeAsmop (right,NULL,ic,TRUE);
7959 //pic16_aopOp(left,ic,FALSE);
7960 //pic16_aopOp(result,ic,FALSE);
7962 /* now move the left to the result if they are not the
7964 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7965 AOP_SIZE(result) > 1) {
7967 size = AOP_SIZE(result);
7971 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7972 if (*l == '@' && IS_AOP_PREG(result)) {
7974 pic16_emitcode("mov","a,%s",l);
7975 pic16_aopPut(AOP(result),"a",offset);
7977 pic16_aopPut(AOP(result),l,offset);
7979 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7980 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7986 /* mov the highest order bit to OVR */
7987 tlbl = newiTempLabel(NULL);
7988 tlbl1= newiTempLabel(NULL);
7990 size = AOP_SIZE(result);
7993 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7995 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7997 /* offset should be 0, 1 or 3 */
7998 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8000 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8002 pic16_emitpcode(POC_MOVWF, pctemp);
8005 pic16_emitpLabel(tlbl->key);
8007 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8008 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8011 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8014 pic16_emitpcode(POC_DECFSZ, pctemp);
8015 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8016 pic16_emitpLabel(tlbl1->key);
8018 pic16_popReleaseTempReg(pctemp);
8020 size = AOP_SIZE(result);
8022 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8023 pic16_emitcode("rlc","a");
8024 pic16_emitcode("mov","ov,c");
8025 /* if it is only one byte then */
8027 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8029 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8030 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8031 pic16_emitcode("mov","c,ov");
8032 pic16_emitcode("rrc","a");
8033 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8034 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8035 pic16_aopPut(AOP(result),"a",0);
8039 reAdjustPreg(AOP(result));
8040 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8041 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8042 pic16_emitcode("mov","c,ov");
8044 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8046 pic16_emitcode("rrc","a");
8047 pic16_aopPut(AOP(result),"a",offset--);
8049 reAdjustPreg(AOP(result));
8050 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8051 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8056 pic16_freeAsmop(left,NULL,ic,TRUE);
8057 pic16_freeAsmop(result,NULL,ic,TRUE);
8058 pic16_freeAsmop(right,NULL,ic,TRUE);
8061 /*-----------------------------------------------------------------*/
8062 /* genRightShift - generate code for right shifting */
8063 /*-----------------------------------------------------------------*/
8064 static void genRightShift (iCode *ic)
8066 operand *right, *left, *result;
8070 symbol *tlbl, *tlbl1 ;
8072 /* if signed then we do it the hard way preserve the
8073 sign bit moving it inwards */
8074 letype = getSpec(operandType(IC_LEFT(ic)));
8075 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8077 if (!SPEC_USIGN(letype)) {
8078 genSignedRightShift (ic);
8082 /* signed & unsigned types are treated the same : i.e. the
8083 signed is NOT propagated inwards : quoting from the
8084 ANSI - standard : "for E1 >> E2, is equivalent to division
8085 by 2**E2 if unsigned or if it has a non-negative value,
8086 otherwise the result is implementation defined ", MY definition
8087 is that the sign does not get propagated */
8089 right = IC_RIGHT(ic);
8091 result = IC_RESULT(ic);
8093 pic16_aopOp(right,ic,FALSE);
8095 /* if the shift count is known then do it
8096 as efficiently as possible */
8097 if (AOP_TYPE(right) == AOP_LIT) {
8098 genRightShiftLiteral (left,right,result,ic, 0);
8102 /* shift count is unknown then we have to form
8103 a loop get the loop count in B : Note: we take
8104 only the lower order byte since shifting
8105 more that 32 bits make no sense anyway, ( the
8106 largest size of an object can be only 32 bits ) */
8108 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8109 pic16_emitcode("inc","b");
8110 pic16_aopOp(left,ic,FALSE);
8111 pic16_aopOp(result,ic,FALSE);
8113 /* now move the left to the result if they are not the
8115 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8116 AOP_SIZE(result) > 1) {
8118 size = AOP_SIZE(result);
8121 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8122 if (*l == '@' && IS_AOP_PREG(result)) {
8124 pic16_emitcode("mov","a,%s",l);
8125 pic16_aopPut(AOP(result),"a",offset);
8127 pic16_aopPut(AOP(result),l,offset);
8132 tlbl = newiTempLabel(NULL);
8133 tlbl1= newiTempLabel(NULL);
8134 size = AOP_SIZE(result);
8137 /* if it is only one byte then */
8140 tlbl = newiTempLabel(NULL);
8141 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8142 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8143 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8146 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8147 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8148 pic16_emitpLabel(tlbl->key);
8149 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8150 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8152 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8157 reAdjustPreg(AOP(result));
8158 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8159 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8162 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8164 pic16_emitcode("rrc","a");
8165 pic16_aopPut(AOP(result),"a",offset--);
8167 reAdjustPreg(AOP(result));
8169 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8170 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8173 pic16_freeAsmop(left,NULL,ic,TRUE);
8174 pic16_freeAsmop (right,NULL,ic,TRUE);
8175 pic16_freeAsmop(result,NULL,ic,TRUE);
8178 /*-----------------------------------------------------------------*/
8179 /* genUnpackBits - generates code for unpacking bits */
8180 /*-----------------------------------------------------------------*/
8181 static void genUnpackBits (operand *result, char *rname, int ptype)
8188 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8189 etype = getSpec(operandType(result));
8191 /* read the first byte */
8196 pic16_emitcode("mov","a,@%s",rname);
8200 pic16_emitcode("movx","a,@%s",rname);
8204 pic16_emitcode("movx","a,@dptr");
8208 pic16_emitcode("clr","a");
8209 pic16_emitcode("movc","a","@a+dptr");
8213 pic16_emitcode("lcall","__gptrget");
8217 /* if we have bitdisplacement then it fits */
8218 /* into this byte completely or if length is */
8219 /* less than a byte */
8220 if ((shCnt = SPEC_BSTR(etype)) ||
8221 (SPEC_BLEN(etype) <= 8)) {
8223 /* shift right acc */
8226 pic16_emitcode("anl","a,#0x%02x",
8227 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8228 pic16_aopPut(AOP(result),"a",offset);
8232 /* bit field did not fit in a byte */
8233 rlen = SPEC_BLEN(etype) - 8;
8234 pic16_aopPut(AOP(result),"a",offset++);
8241 pic16_emitcode("inc","%s",rname);
8242 pic16_emitcode("mov","a,@%s",rname);
8246 pic16_emitcode("inc","%s",rname);
8247 pic16_emitcode("movx","a,@%s",rname);
8251 pic16_emitcode("inc","dptr");
8252 pic16_emitcode("movx","a,@dptr");
8256 pic16_emitcode("clr","a");
8257 pic16_emitcode("inc","dptr");
8258 pic16_emitcode("movc","a","@a+dptr");
8262 pic16_emitcode("inc","dptr");
8263 pic16_emitcode("lcall","__gptrget");
8268 /* if we are done */
8272 pic16_aopPut(AOP(result),"a",offset++);
8277 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8278 pic16_aopPut(AOP(result),"a",offset);
8285 /*-----------------------------------------------------------------*/
8286 /* genDataPointerGet - generates code when ptr offset is known */
8287 /*-----------------------------------------------------------------*/
8288 static void genDataPointerGet (operand *left,
8292 int size , offset = 0;
8295 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8298 /* optimization - most of the time, left and result are the same
8299 * address, but different types. for the pic code, we could omit
8303 pic16_aopOp(result,ic,TRUE);
8305 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8307 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8309 size = AOP_SIZE(result);
8312 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8316 pic16_freeAsmop(left,NULL,ic,TRUE);
8317 pic16_freeAsmop(result,NULL,ic,TRUE);
8320 /*-----------------------------------------------------------------*/
8321 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8322 /*-----------------------------------------------------------------*/
8323 static void genNearPointerGet (operand *left,
8328 //regs *preg = NULL ;
8330 sym_link *rtype, *retype;
8331 sym_link *ltype = operandType(left);
8334 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8336 rtype = operandType(result);
8337 retype= getSpec(rtype);
8339 pic16_aopOp(left,ic,FALSE);
8341 /* if left is rematerialisable and
8342 result is not bit variable type and
8343 the left is pointer to data space i.e
8344 lower 128 bytes of space */
8345 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8346 !IS_BITVAR(retype) &&
8347 DCL_TYPE(ltype) == POINTER) {
8348 //genDataPointerGet (left,result,ic);
8352 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8354 /* if the value is already in a pointer register
8355 then don't need anything more */
8356 if (!AOP_INPREG(AOP(left))) {
8357 /* otherwise get a free pointer register */
8358 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8361 preg = getFreePtr(ic,&aop,FALSE);
8362 pic16_emitcode("mov","%s,%s",
8364 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8365 rname = preg->name ;
8369 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8371 pic16_aopOp (result,ic,FALSE);
8373 /* if bitfield then unpack the bits */
8374 if (IS_BITFIELD(retype))
8375 genUnpackBits (result,rname,POINTER);
8377 /* we have can just get the values */
8378 int size = AOP_SIZE(result);
8381 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8383 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8384 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8386 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8387 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8389 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8393 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8395 pic16_emitcode("mov","a,@%s",rname);
8396 pic16_aopPut(AOP(result),"a",offset);
8398 sprintf(buffer,"@%s",rname);
8399 pic16_aopPut(AOP(result),buffer,offset);
8403 pic16_emitcode("inc","%s",rname);
8408 /* now some housekeeping stuff */
8410 /* we had to allocate for this iCode */
8411 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8412 pic16_freeAsmop(NULL,aop,ic,TRUE);
8414 /* we did not allocate which means left
8415 already in a pointer register, then
8416 if size > 0 && this could be used again
8417 we have to point it back to where it
8419 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8420 if (AOP_SIZE(result) > 1 &&
8421 !OP_SYMBOL(left)->remat &&
8422 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8424 int size = AOP_SIZE(result) - 1;
8426 pic16_emitcode("dec","%s",rname);
8431 pic16_freeAsmop(left,NULL,ic,TRUE);
8432 pic16_freeAsmop(result,NULL,ic,TRUE);
8436 /*-----------------------------------------------------------------*/
8437 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8438 /*-----------------------------------------------------------------*/
8439 static void genPagedPointerGet (operand *left,
8446 sym_link *rtype, *retype;
8448 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8450 rtype = operandType(result);
8451 retype= getSpec(rtype);
8453 pic16_aopOp(left,ic,FALSE);
8455 /* if the value is already in a pointer register
8456 then don't need anything more */
8457 if (!AOP_INPREG(AOP(left))) {
8458 /* otherwise get a free pointer register */
8460 preg = getFreePtr(ic,&aop,FALSE);
8461 pic16_emitcode("mov","%s,%s",
8463 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8464 rname = preg->name ;
8466 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8468 pic16_freeAsmop(left,NULL,ic,TRUE);
8469 pic16_aopOp (result,ic,FALSE);
8471 /* if bitfield then unpack the bits */
8472 if (IS_BITFIELD(retype))
8473 genUnpackBits (result,rname,PPOINTER);
8475 /* we have can just get the values */
8476 int size = AOP_SIZE(result);
8481 pic16_emitcode("movx","a,@%s",rname);
8482 pic16_aopPut(AOP(result),"a",offset);
8487 pic16_emitcode("inc","%s",rname);
8491 /* now some housekeeping stuff */
8493 /* we had to allocate for this iCode */
8494 pic16_freeAsmop(NULL,aop,ic,TRUE);
8496 /* we did not allocate which means left
8497 already in a pointer register, then
8498 if size > 0 && this could be used again
8499 we have to point it back to where it
8501 if (AOP_SIZE(result) > 1 &&
8502 !OP_SYMBOL(left)->remat &&
8503 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8505 int size = AOP_SIZE(result) - 1;
8507 pic16_emitcode("dec","%s",rname);
8512 pic16_freeAsmop(result,NULL,ic,TRUE);
8517 /*-----------------------------------------------------------------*/
8518 /* genFarPointerGet - gget value from far space */
8519 /*-----------------------------------------------------------------*/
8520 static void genFarPointerGet (operand *left,
8521 operand *result, iCode *ic)
8524 sym_link *retype = getSpec(operandType(result));
8526 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8528 pic16_aopOp(left,ic,FALSE);
8530 /* if the operand is already in dptr
8531 then we do nothing else we move the value to dptr */
8532 if (AOP_TYPE(left) != AOP_STR) {
8533 /* if this is remateriazable */
8534 if (AOP_TYPE(left) == AOP_IMMD)
8535 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8536 else { /* we need to get it byte by byte */
8537 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8538 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8539 if (options.model == MODEL_FLAT24)
8541 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8545 /* so dptr know contains the address */
8546 pic16_freeAsmop(left,NULL,ic,TRUE);
8547 pic16_aopOp(result,ic,FALSE);
8549 /* if bit then unpack */
8550 if (IS_BITFIELD(retype))
8551 genUnpackBits(result,"dptr",FPOINTER);
8553 size = AOP_SIZE(result);
8557 pic16_emitcode("movx","a,@dptr");
8558 pic16_aopPut(AOP(result),"a",offset++);
8560 pic16_emitcode("inc","dptr");
8564 pic16_freeAsmop(result,NULL,ic,TRUE);
8567 /*-----------------------------------------------------------------*/
8568 /* genCodePointerGet - get value from code space */
8569 /*-----------------------------------------------------------------*/
8570 static void genCodePointerGet (operand *left,
8571 operand *result, iCode *ic)
8574 sym_link *retype = getSpec(operandType(result));
8576 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8578 pic16_aopOp(left,ic,FALSE);
8580 /* if the operand is already in dptr
8581 then we do nothing else we move the value to dptr */
8582 if (AOP_TYPE(left) != AOP_STR) {
8583 /* if this is remateriazable */
8584 if (AOP_TYPE(left) == AOP_IMMD)
8585 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8586 else { /* we need to get it byte by byte */
8587 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8588 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8589 if (options.model == MODEL_FLAT24)
8591 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8595 /* so dptr know contains the address */
8596 pic16_freeAsmop(left,NULL,ic,TRUE);
8597 pic16_aopOp(result,ic,FALSE);
8599 /* if bit then unpack */
8600 if (IS_BITFIELD(retype))
8601 genUnpackBits(result,"dptr",CPOINTER);
8603 size = AOP_SIZE(result);
8607 pic16_emitcode("clr","a");
8608 pic16_emitcode("movc","a,@a+dptr");
8609 pic16_aopPut(AOP(result),"a",offset++);
8611 pic16_emitcode("inc","dptr");
8615 pic16_freeAsmop(result,NULL,ic,TRUE);
8618 /*-----------------------------------------------------------------*/
8619 /* genGenPointerGet - gget value from generic pointer space */
8620 /*-----------------------------------------------------------------*/
8621 static void genGenPointerGet (operand *left,
8622 operand *result, iCode *ic)
8625 sym_link *retype = getSpec(operandType(result));
8627 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8628 pic16_aopOp(left,ic,FALSE);
8629 pic16_aopOp(result,ic,FALSE);
8632 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8634 /* if the operand is already in dptr
8635 then we do nothing else we move the value to dptr */
8636 // if (AOP_TYPE(left) != AOP_STR) {
8637 /* if this is remateriazable */
8638 if (AOP_TYPE(left) == AOP_IMMD) {
8639 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8640 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8642 else { /* we need to get it byte by byte */
8644 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8645 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8647 size = AOP_SIZE(result);
8651 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8652 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8654 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8659 /* so dptr know contains the address */
8661 /* if bit then unpack */
8662 if (IS_BITFIELD(retype))
8663 genUnpackBits(result,"BAD",GPOINTER);
8666 pic16_freeAsmop(left,NULL,ic,TRUE);
8667 pic16_freeAsmop(result,NULL,ic,TRUE);
8671 /*-----------------------------------------------------------------*/
8672 /* genConstPointerGet - get value from const generic pointer space */
8673 /*-----------------------------------------------------------------*/
8674 static void genConstPointerGet (operand *left,
8675 operand *result, iCode *ic)
8677 //sym_link *retype = getSpec(operandType(result));
8678 symbol *albl = newiTempLabel(NULL);
8679 symbol *blbl = newiTempLabel(NULL);
8682 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8683 pic16_aopOp(left,ic,FALSE);
8684 pic16_aopOp(result,ic,FALSE);
8687 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8689 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8691 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8692 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8693 pic16_emitpLabel(albl->key);
8695 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8697 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8698 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8699 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8700 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8701 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8703 pic16_emitpLabel(blbl->key);
8705 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8708 pic16_freeAsmop(left,NULL,ic,TRUE);
8709 pic16_freeAsmop(result,NULL,ic,TRUE);
8712 /*-----------------------------------------------------------------*/
8713 /* genPointerGet - generate code for pointer get */
8714 /*-----------------------------------------------------------------*/
8715 static void genPointerGet (iCode *ic)
8717 operand *left, *result ;
8718 sym_link *type, *etype;
8721 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8724 result = IC_RESULT(ic) ;
8726 /* depending on the type of pointer we need to
8727 move it to the correct pointer register */
8728 type = operandType(left);
8729 etype = getSpec(type);
8732 if (IS_PTR_CONST(type))
8734 if (IS_CODEPTR(type))
8736 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8738 /* if left is of type of pointer then it is simple */
8739 if (IS_PTR(type) && !IS_FUNC(type->next))
8740 p_type = DCL_TYPE(type);
8742 /* we have to go by the storage class */
8743 p_type = PTR_TYPE(SPEC_OCLS(etype));
8745 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8747 if (SPEC_OCLS(etype)->codesp ) {
8748 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8749 //p_type = CPOINTER ;
8752 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8753 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8754 /*p_type = FPOINTER ;*/
8756 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8757 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8758 /* p_type = PPOINTER; */
8760 if (SPEC_OCLS(etype) == idata )
8761 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8762 /* p_type = IPOINTER; */
8764 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8765 /* p_type = POINTER ; */
8768 /* now that we have the pointer type we assign
8769 the pointer values */
8774 genNearPointerGet (left,result,ic);
8778 genPagedPointerGet(left,result,ic);
8782 genFarPointerGet (left,result,ic);
8786 genConstPointerGet (left,result,ic);
8787 //pic16_emitcodePointerGet (left,result,ic);
8792 if (IS_PTR_CONST(type))
8793 genConstPointerGet (left,result,ic);
8796 genGenPointerGet (left,result,ic);
8802 /*-----------------------------------------------------------------*/
8803 /* genPackBits - generates code for packed bit storage */
8804 /*-----------------------------------------------------------------*/
8805 static void genPackBits (sym_link *etype ,
8807 char *rname, int p_type)
8815 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8816 blen = SPEC_BLEN(etype);
8817 bstr = SPEC_BSTR(etype);
8819 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8822 /* if the bit lenth is less than or */
8823 /* it exactly fits a byte then */
8824 if (SPEC_BLEN(etype) <= 8 ) {
8825 shCount = SPEC_BSTR(etype) ;
8827 /* shift left acc */
8830 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8835 pic16_emitcode ("mov","b,a");
8836 pic16_emitcode("mov","a,@%s",rname);
8840 pic16_emitcode ("mov","b,a");
8841 pic16_emitcode("movx","a,@dptr");
8845 pic16_emitcode ("push","b");
8846 pic16_emitcode ("push","acc");
8847 pic16_emitcode ("lcall","__gptrget");
8848 pic16_emitcode ("pop","b");
8852 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8853 ((unsigned char)(0xFF << (blen+bstr)) |
8854 (unsigned char)(0xFF >> (8-bstr)) ) );
8855 pic16_emitcode ("orl","a,b");
8856 if (p_type == GPOINTER)
8857 pic16_emitcode("pop","b");
8863 pic16_emitcode("mov","@%s,a",rname);
8867 pic16_emitcode("movx","@dptr,a");
8871 DEBUGpic16_emitcode(";lcall","__gptrput");
8876 if ( SPEC_BLEN(etype) <= 8 )
8879 pic16_emitcode("inc","%s",rname);
8880 rLen = SPEC_BLEN(etype) ;
8882 /* now generate for lengths greater than one byte */
8885 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8895 pic16_emitcode("mov","@%s,a",rname);
8897 pic16_emitcode("mov","@%s,%s",rname,l);
8902 pic16_emitcode("movx","@dptr,a");
8907 DEBUGpic16_emitcode(";lcall","__gptrput");
8910 pic16_emitcode ("inc","%s",rname);
8915 /* last last was not complete */
8917 /* save the byte & read byte */
8920 pic16_emitcode ("mov","b,a");
8921 pic16_emitcode("mov","a,@%s",rname);
8925 pic16_emitcode ("mov","b,a");
8926 pic16_emitcode("movx","a,@dptr");
8930 pic16_emitcode ("push","b");
8931 pic16_emitcode ("push","acc");
8932 pic16_emitcode ("lcall","__gptrget");
8933 pic16_emitcode ("pop","b");
8937 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8938 pic16_emitcode ("orl","a,b");
8941 if (p_type == GPOINTER)
8942 pic16_emitcode("pop","b");
8947 pic16_emitcode("mov","@%s,a",rname);
8951 pic16_emitcode("movx","@dptr,a");
8955 DEBUGpic16_emitcode(";lcall","__gptrput");
8959 /*-----------------------------------------------------------------*/
8960 /* genDataPointerSet - remat pointer to data space */
8961 /*-----------------------------------------------------------------*/
8962 static void genDataPointerSet(operand *right,
8966 int size, offset = 0 ;
8967 char *l, buffer[256];
8969 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8970 pic16_aopOp(right,ic,FALSE);
8972 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8973 size = AOP_SIZE(right);
8975 if ( AOP_TYPE(result) == AOP_PCODE) {
8976 fprintf(stderr,"genDataPointerSet %s, %d\n",
8977 AOP(result)->aopu.pcop->name,
8978 PCOI(AOP(result)->aopu.pcop)->offset);
8982 // tsd, was l+1 - the underline `_' prefix was being stripped
8985 sprintf(buffer,"(%s + %d)",l,offset);
8986 fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer);
8988 sprintf(buffer,"%s",l);
8990 if (AOP_TYPE(right) == AOP_LIT) {
8991 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8992 lit = lit >> (8*offset);
8994 pic16_emitcode("movlw","%d",lit);
8995 pic16_emitcode("movwf","%s",buffer);
8997 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8998 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
8999 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9002 pic16_emitcode("clrf","%s",buffer);
9003 //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer));
9004 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9007 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
9008 pic16_emitcode("movwf","%s",buffer);
9010 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9011 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
9012 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9019 pic16_freeAsmop(right,NULL,ic,TRUE);
9020 pic16_freeAsmop(result,NULL,ic,TRUE);
9023 /*-----------------------------------------------------------------*/
9024 /* genNearPointerSet - pic16_emitcode for near pointer put */
9025 /*-----------------------------------------------------------------*/
9026 static void genNearPointerSet (operand *right,
9033 sym_link *ptype = operandType(result);
9036 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9037 retype= getSpec(operandType(right));
9039 pic16_aopOp(result,ic,FALSE);
9042 /* if the result is rematerializable &
9043 in data space & not a bit variable */
9044 //if (AOP_TYPE(result) == AOP_IMMD &&
9045 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
9046 DCL_TYPE(ptype) == POINTER &&
9047 !IS_BITVAR(retype)) {
9048 genDataPointerSet (right,result,ic);
9049 pic16_freeAsmop(result,NULL,ic,TRUE);
9053 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9054 pic16_aopOp(right,ic,FALSE);
9055 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9057 /* if the value is already in a pointer register
9058 then don't need anything more */
9059 if (!AOP_INPREG(AOP(result))) {
9060 /* otherwise get a free pointer register */
9061 //aop = newAsmop(0);
9062 //preg = getFreePtr(ic,&aop,FALSE);
9063 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9064 //pic16_emitcode("mov","%s,%s",
9066 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
9067 //rname = preg->name ;
9068 //pic16_emitcode("movwf","fsr0");
9069 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
9070 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
9071 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9072 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9076 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9078 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9080 /* if bitfield then unpack the bits */
9081 if (IS_BITFIELD(retype)) {
9082 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9083 "The programmer is obviously confused");
9084 // genPackBits (retype,right,"BAD",POINTER);
9088 /* we have can just get the values */
9089 int size = AOP_SIZE(right);
9092 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9094 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9097 //pic16_emitcode("mov","@%s,a",rname);
9098 pic16_emitcode("movf","indf0,w ;1");
9101 if (AOP_TYPE(right) == AOP_LIT) {
9102 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9104 pic16_emitcode("movlw","%s",l);
9105 pic16_emitcode("movwf","indf0 ;2");
9107 pic16_emitcode("clrf","indf0");
9109 pic16_emitcode("movf","%s,w",l);
9110 pic16_emitcode("movwf","indf0 ;2");
9112 //pic16_emitcode("mov","@%s,%s",rname,l);
9115 pic16_emitcode("incf","fsr0,f ;3");
9116 //pic16_emitcode("inc","%s",rname);
9121 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9122 /* now some housekeeping stuff */
9124 /* we had to allocate for this iCode */
9125 pic16_freeAsmop(NULL,aop,ic,TRUE);
9127 /* we did not allocate which means left
9128 already in a pointer register, then
9129 if size > 0 && this could be used again
9130 we have to point it back to where it
9132 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9133 if (AOP_SIZE(right) > 1 &&
9134 !OP_SYMBOL(result)->remat &&
9135 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9137 int size = AOP_SIZE(right) - 1;
9139 pic16_emitcode("decf","fsr0,f");
9140 //pic16_emitcode("dec","%s",rname);
9144 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9147 pic16_freeAsmop(right,NULL,ic,TRUE);
9148 pic16_freeAsmop(result,NULL,ic,TRUE);
9151 /*-----------------------------------------------------------------*/
9152 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9153 /*-----------------------------------------------------------------*/
9154 static void genPagedPointerSet (operand *right,
9163 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9165 retype= getSpec(operandType(right));
9167 pic16_aopOp(result,ic,FALSE);
9169 /* if the value is already in a pointer register
9170 then don't need anything more */
9171 if (!AOP_INPREG(AOP(result))) {
9172 /* otherwise get a free pointer register */
9174 preg = getFreePtr(ic,&aop,FALSE);
9175 pic16_emitcode("mov","%s,%s",
9177 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9178 rname = preg->name ;
9180 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9182 pic16_freeAsmop(result,NULL,ic,TRUE);
9183 pic16_aopOp (right,ic,FALSE);
9185 /* if bitfield then unpack the bits */
9186 if (IS_BITFIELD(retype))
9187 genPackBits (retype,right,rname,PPOINTER);
9189 /* we have can just get the values */
9190 int size = AOP_SIZE(right);
9194 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9197 pic16_emitcode("movx","@%s,a",rname);
9200 pic16_emitcode("inc","%s",rname);
9206 /* now some housekeeping stuff */
9208 /* we had to allocate for this iCode */
9209 pic16_freeAsmop(NULL,aop,ic,TRUE);
9211 /* we did not allocate which means left
9212 already in a pointer register, then
9213 if size > 0 && this could be used again
9214 we have to point it back to where it
9216 if (AOP_SIZE(right) > 1 &&
9217 !OP_SYMBOL(result)->remat &&
9218 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9220 int size = AOP_SIZE(right) - 1;
9222 pic16_emitcode("dec","%s",rname);
9227 pic16_freeAsmop(right,NULL,ic,TRUE);
9232 /*-----------------------------------------------------------------*/
9233 /* genFarPointerSet - set value from far space */
9234 /*-----------------------------------------------------------------*/
9235 static void genFarPointerSet (operand *right,
9236 operand *result, iCode *ic)
9239 sym_link *retype = getSpec(operandType(right));
9241 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9242 pic16_aopOp(result,ic,FALSE);
9244 /* if the operand is already in dptr
9245 then we do nothing else we move the value to dptr */
9246 if (AOP_TYPE(result) != AOP_STR) {
9247 /* if this is remateriazable */
9248 if (AOP_TYPE(result) == AOP_IMMD)
9249 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9250 else { /* we need to get it byte by byte */
9251 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9252 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9253 if (options.model == MODEL_FLAT24)
9255 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9259 /* so dptr know contains the address */
9260 pic16_freeAsmop(result,NULL,ic,TRUE);
9261 pic16_aopOp(right,ic,FALSE);
9263 /* if bit then unpack */
9264 if (IS_BITFIELD(retype))
9265 genPackBits(retype,right,"dptr",FPOINTER);
9267 size = AOP_SIZE(right);
9271 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9273 pic16_emitcode("movx","@dptr,a");
9275 pic16_emitcode("inc","dptr");
9279 pic16_freeAsmop(right,NULL,ic,TRUE);
9282 /*-----------------------------------------------------------------*/
9283 /* genGenPointerSet - set value from generic pointer space */
9284 /*-----------------------------------------------------------------*/
9285 static void genGenPointerSet (operand *right,
9286 operand *result, iCode *ic)
9289 sym_link *retype = getSpec(operandType(right));
9291 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9293 pic16_aopOp(result,ic,FALSE);
9294 pic16_aopOp(right,ic,FALSE);
9295 size = AOP_SIZE(right);
9297 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9299 /* if the operand is already in dptr
9300 then we do nothing else we move the value to dptr */
9301 if (AOP_TYPE(result) != AOP_STR) {
9302 /* if this is remateriazable */
9303 if (AOP_TYPE(result) == AOP_IMMD) {
9304 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9305 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9307 else { /* we need to get it byte by byte */
9308 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9309 size = AOP_SIZE(right);
9312 /* hack hack! see if this the FSR. If so don't load W */
9313 if(AOP_TYPE(right) != AOP_ACC) {
9315 // pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(result), pic16_popCopyReg(&pic16_pc_fsr0), 0));
9317 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9318 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9320 if(AOP_SIZE(result) > 1) {
9321 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9322 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9323 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9328 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9330 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9331 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9335 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9336 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9339 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9346 if(aopIdx(AOP(result),0) != 4) {
9348 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9352 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9357 /* so dptr know contains the address */
9360 /* if bit then unpack */
9361 if (IS_BITFIELD(retype))
9362 genPackBits(retype,right,"dptr",GPOINTER);
9364 size = AOP_SIZE(right);
9367 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9371 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9372 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9374 if (AOP_TYPE(right) == AOP_LIT)
9375 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9377 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9379 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9386 pic16_freeAsmop(right,NULL,ic,TRUE);
9387 pic16_freeAsmop(result,NULL,ic,TRUE);
9390 /*-----------------------------------------------------------------*/
9391 /* genPointerSet - stores the value into a pointer location */
9392 /*-----------------------------------------------------------------*/
9393 static void genPointerSet (iCode *ic)
9395 operand *right, *result ;
9396 sym_link *type, *etype;
9399 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9401 right = IC_RIGHT(ic);
9402 result = IC_RESULT(ic) ;
9404 /* depending on the type of pointer we need to
9405 move it to the correct pointer register */
9406 type = operandType(result);
9407 etype = getSpec(type);
9408 /* if left is of type of pointer then it is simple */
9409 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9410 p_type = DCL_TYPE(type);
9413 /* we have to go by the storage class */
9414 p_type = PTR_TYPE(SPEC_OCLS(etype));
9416 /* if (SPEC_OCLS(etype)->codesp ) { */
9417 /* p_type = CPOINTER ; */
9420 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9421 /* p_type = FPOINTER ; */
9423 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9424 /* p_type = PPOINTER ; */
9426 /* if (SPEC_OCLS(etype) == idata ) */
9427 /* p_type = IPOINTER ; */
9429 /* p_type = POINTER ; */
9432 /* now that we have the pointer type we assign
9433 the pointer values */
9438 genNearPointerSet (right,result,ic);
9442 genPagedPointerSet (right,result,ic);
9446 genFarPointerSet (right,result,ic);
9450 genGenPointerSet (right,result,ic);
9454 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9455 "genPointerSet: illegal pointer type");
9459 /*-----------------------------------------------------------------*/
9460 /* genIfx - generate code for Ifx statement */
9461 /*-----------------------------------------------------------------*/
9462 static void genIfx (iCode *ic, iCode *popIc)
9464 operand *cond = IC_COND(ic);
9467 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9469 pic16_aopOp(cond,ic,FALSE);
9471 /* get the value into acc */
9472 if (AOP_TYPE(cond) != AOP_CRY)
9473 pic16_toBoolean(cond);
9476 /* the result is now in the accumulator */
9477 pic16_freeAsmop(cond,NULL,ic,TRUE);
9479 /* if there was something to be popped then do it */
9483 /* if the condition is a bit variable */
9484 if (isbit && IS_ITEMP(cond) &&
9486 genIfxJump(ic,SPIL_LOC(cond)->rname);
9487 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9490 if (isbit && !IS_ITEMP(cond))
9491 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9499 /*-----------------------------------------------------------------*/
9500 /* genAddrOf - generates code for address of */
9501 /*-----------------------------------------------------------------*/
9503 static void genAddrOf (iCode *ic)
9505 operand *right, *result, *left;
9508 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9511 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9513 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9514 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9515 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9517 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9519 size = AOP_SIZE(IC_RESULT(ic));
9524 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9525 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9530 pic16_freeAsmop(left,NULL,ic,FALSE);
9531 pic16_freeAsmop(result,NULL,ic,TRUE);
9535 #else /* new genAddrOf */
9537 static void genAddrOf (iCode *ic)
9539 operand *result, *left;
9541 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9542 pCodeOp *pcop0, *pcop1, *pcop2;
9544 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9546 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9547 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9549 sym = OP_SYMBOL( left );
9551 size = AOP_SIZE(IC_RESULT(ic));
9553 if(pic16_debug_verbose) {
9554 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9555 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9558 /* Assume that what we want the address of is in data space
9559 * since there is no stack on the PIC, yet! -- VR */
9561 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9564 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9567 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9571 pic16_emitpcode(POC_MOVLW, pcop0);
9572 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9573 pic16_emitpcode(POC_MOVLW, pcop1);
9574 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9575 pic16_emitpcode(POC_MOVLW, pcop2);
9576 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9579 pic16_emitpcode(POC_MOVLW, pcop0);
9580 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9581 pic16_emitpcode(POC_MOVLW, pcop1);
9582 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9584 pic16_emitpcode(POC_MOVLW, pcop0);
9585 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9588 pic16_freeAsmop(result,NULL,ic,TRUE);
9589 pic16_freeAsmop(left, NULL, ic, FALSE);
9592 #endif /* new genAddrOf */
9595 /*-----------------------------------------------------------------*/
9596 /* genFarFarAssign - assignment when both are in far space */
9597 /*-----------------------------------------------------------------*/
9598 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9600 int size = AOP_SIZE(right);
9603 /* first push the right side on to the stack */
9605 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9607 pic16_emitcode ("push","acc");
9610 pic16_freeAsmop(right,NULL,ic,FALSE);
9611 /* now assign DPTR to result */
9612 pic16_aopOp(result,ic,FALSE);
9613 size = AOP_SIZE(result);
9615 pic16_emitcode ("pop","acc");
9616 pic16_aopPut(AOP(result),"a",--offset);
9618 pic16_freeAsmop(result,NULL,ic,FALSE);
9623 /*-----------------------------------------------------------------*/
9624 /* genAssign - generate code for assignment */
9625 /*-----------------------------------------------------------------*/
9626 static void genAssign (iCode *ic)
9628 operand *result, *right;
9629 int size, offset,know_W;
9630 unsigned long lit = 0L;
9632 result = IC_RESULT(ic);
9633 right = IC_RIGHT(ic) ;
9635 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9637 /* if they are the same */
9638 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9641 pic16_aopOp(right,ic,FALSE);
9642 pic16_aopOp(result,ic,TRUE);
9644 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9646 /* if they are the same registers */
9647 if (pic16_sameRegs(AOP(right),AOP(result)))
9650 /* if the result is a bit */
9651 if (AOP_TYPE(result) == AOP_CRY) {
9652 /* if the right size is a literal then
9653 we know what the value is */
9654 if (AOP_TYPE(right) == AOP_LIT) {
9656 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9657 pic16_popGet(AOP(result),0));
9659 if (((int) operandLitValue(right)))
9660 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9661 AOP(result)->aopu.aop_dir,
9662 AOP(result)->aopu.aop_dir);
9664 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9665 AOP(result)->aopu.aop_dir,
9666 AOP(result)->aopu.aop_dir);
9670 /* the right is also a bit variable */
9671 if (AOP_TYPE(right) == AOP_CRY) {
9672 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9673 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9674 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9676 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9677 AOP(result)->aopu.aop_dir,
9678 AOP(result)->aopu.aop_dir);
9679 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9680 AOP(right)->aopu.aop_dir,
9681 AOP(right)->aopu.aop_dir);
9682 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9683 AOP(result)->aopu.aop_dir,
9684 AOP(result)->aopu.aop_dir);
9689 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9690 pic16_toBoolean(right);
9692 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9693 //pic16_aopPut(AOP(result),"a",0);
9697 /* bit variables done */
9699 size = AOP_SIZE(result);
9701 if(AOP_TYPE(right) == AOP_LIT)
9702 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9704 /* VR - What is this?! */
9705 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9706 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9707 if(aopIdx(AOP(result),0) == 4) {
9708 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9709 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9710 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9713 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9718 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9719 if(AOP_TYPE(right) == AOP_LIT) {
9721 if(know_W != (lit&0xff))
9722 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9724 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9726 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9730 } else if (AOP_TYPE(right) == AOP_CRY) {
9731 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9733 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9734 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9737 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9740 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9741 normally should work, but mind that the W register live range
9742 is not checked, so if the code generator assumes that the W
9743 is already loaded after such a pair, wrong code will be generated.
9745 Checking the live range is the next step.
9746 This is experimental code yet and has not been fully tested yet.
9747 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9748 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9750 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9752 /* This is the old code, which is assumed(?!) that works fine(!?) */
9754 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9755 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9764 pic16_freeAsmop (right,NULL,ic,FALSE);
9765 pic16_freeAsmop (result,NULL,ic,TRUE);
9768 /*-----------------------------------------------------------------*/
9769 /* genJumpTab - generates code for jump table */
9770 /*-----------------------------------------------------------------*/
9771 static void genJumpTab (iCode *ic)
9776 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9778 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9779 /* get the condition into accumulator */
9780 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9782 /* multiply by three */
9783 pic16_emitcode("add","a,acc");
9784 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9786 jtab = newiTempLabel(NULL);
9787 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9788 pic16_emitcode("jmp","@a+dptr");
9789 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9791 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9792 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9794 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9795 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9796 pic16_emitpLabel(jtab->key);
9798 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9800 /* now generate the jump labels */
9801 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9802 jtab = setNextItem(IC_JTLABELS(ic))) {
9803 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9804 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9810 /*-----------------------------------------------------------------*/
9811 /* genMixedOperation - gen code for operators between mixed types */
9812 /*-----------------------------------------------------------------*/
9814 TSD - Written for the PIC port - but this unfortunately is buggy.
9815 This routine is good in that it is able to efficiently promote
9816 types to different (larger) sizes. Unfortunately, the temporary
9817 variables that are optimized out by this routine are sometimes
9818 used in other places. So until I know how to really parse the
9819 iCode tree, I'm going to not be using this routine :(.
9821 static int genMixedOperation (iCode *ic)
9824 operand *result = IC_RESULT(ic);
9825 sym_link *ctype = operandType(IC_LEFT(ic));
9826 operand *right = IC_RIGHT(ic);
9832 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9834 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9840 nextright = IC_RIGHT(nextic);
9841 nextleft = IC_LEFT(nextic);
9842 nextresult = IC_RESULT(nextic);
9844 pic16_aopOp(right,ic,FALSE);
9845 pic16_aopOp(result,ic,FALSE);
9846 pic16_aopOp(nextright, nextic, FALSE);
9847 pic16_aopOp(nextleft, nextic, FALSE);
9848 pic16_aopOp(nextresult, nextic, FALSE);
9850 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9856 pic16_emitcode(";remove right +","");
9858 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9864 pic16_emitcode(";remove left +","");
9868 big = AOP_SIZE(nextleft);
9869 small = AOP_SIZE(nextright);
9871 switch(nextic->op) {
9874 pic16_emitcode(";optimize a +","");
9875 /* if unsigned or not an integral type */
9876 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9877 pic16_emitcode(";add a bit to something","");
9880 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9882 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9883 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9884 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9886 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9894 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9895 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9896 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9899 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9901 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9902 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9903 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9904 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9905 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9908 pic16_emitcode("rlf","known_zero,w");
9915 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9916 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9917 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9919 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9929 pic16_freeAsmop(right,NULL,ic,TRUE);
9930 pic16_freeAsmop(result,NULL,ic,TRUE);
9931 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9932 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9934 nextic->generated = 1;
9941 /*-----------------------------------------------------------------*/
9942 /* genCast - gen code for casting */
9943 /*-----------------------------------------------------------------*/
9944 static void genCast (iCode *ic)
9946 operand *result = IC_RESULT(ic);
9947 sym_link *ctype = operandType(IC_LEFT(ic));
9948 sym_link *rtype = operandType(IC_RIGHT(ic));
9949 operand *right = IC_RIGHT(ic);
9952 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9953 /* if they are equivalent then do nothing */
9954 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9957 pic16_aopOp(right,ic,FALSE) ;
9958 pic16_aopOp(result,ic,FALSE);
9960 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9962 /* if the result is a bit */
9963 if (AOP_TYPE(result) == AOP_CRY) {
9965 /* if the right size is a literal then
9966 * we know what the value is */
9967 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9969 if (AOP_TYPE(right) == AOP_LIT) {
9970 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9971 pic16_popGet(AOP(result),0));
9973 if (((int) operandLitValue(right)))
9974 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9975 AOP(result)->aopu.aop_dir,
9976 AOP(result)->aopu.aop_dir);
9978 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9979 AOP(result)->aopu.aop_dir,
9980 AOP(result)->aopu.aop_dir);
9984 /* the right is also a bit variable */
9985 if (AOP_TYPE(right) == AOP_CRY) {
9987 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9989 pic16_emitcode("clrc","");
9990 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9991 AOP(right)->aopu.aop_dir,
9992 AOP(right)->aopu.aop_dir);
9993 pic16_aopPut(AOP(result),"c",0);
9998 if (AOP_TYPE(right) == AOP_REG) {
9999 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10000 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10001 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10003 pic16_toBoolean(right);
10004 pic16_aopPut(AOP(result),"a",0);
10008 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10011 size = AOP_SIZE(result);
10013 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10015 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10016 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10017 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10020 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10025 /* if they are the same size : or less */
10026 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10028 /* if they are in the same place */
10029 if (pic16_sameRegs(AOP(right),AOP(result)))
10032 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10034 if (IS_PTR_CONST(rtype))
10036 if (IS_CODEPTR(rtype))
10038 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10041 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10043 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10045 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10048 if(AOP_TYPE(right) == AOP_IMMD) {
10049 pCodeOp *pcop0, *pcop1, *pcop2;
10050 symbol *sym = OP_SYMBOL( right );
10052 size = AOP_SIZE(result);
10054 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10056 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10058 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10061 pic16_emitpcode(POC_MOVLW, pcop0);
10062 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10063 pic16_emitpcode(POC_MOVLW, pcop1);
10064 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10065 pic16_emitpcode(POC_MOVLW, pcop2);
10066 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10069 pic16_emitpcode(POC_MOVLW, pcop0);
10070 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10071 pic16_emitpcode(POC_MOVLW, pcop1);
10072 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10074 pic16_emitpcode(POC_MOVLW, pcop0);
10075 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10079 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10080 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10081 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10082 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10083 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10084 if(AOP_SIZE(result) <2)
10085 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10087 /* if they in different places then copy */
10088 size = AOP_SIZE(result);
10091 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10092 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10099 /* if the result is of type pointer */
10100 if (IS_PTR(ctype)) {
10102 sym_link *type = operandType(right);
10103 sym_link *etype = getSpec(type);
10105 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10107 /* pointer to generic pointer */
10108 if (IS_GENPTR(ctype)) {
10112 p_type = DCL_TYPE(type);
10114 /* we have to go by the storage class */
10115 p_type = PTR_TYPE(SPEC_OCLS(etype));
10117 /* if (SPEC_OCLS(etype)->codesp ) */
10118 /* p_type = CPOINTER ; */
10120 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10121 /* p_type = FPOINTER ; */
10123 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10124 /* p_type = PPOINTER; */
10126 /* if (SPEC_OCLS(etype) == idata ) */
10127 /* p_type = IPOINTER ; */
10129 /* p_type = POINTER ; */
10132 /* the first two bytes are known */
10133 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10134 size = GPTRSIZE - 1;
10137 if(offset < AOP_SIZE(right)) {
10138 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10139 if ((AOP_TYPE(right) == AOP_PCODE) &&
10140 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10141 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10142 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10144 pic16_aopPut(AOP(result),
10145 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10149 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10152 /* the last byte depending on type */
10156 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10159 pic16_emitcode(";BUG!? ","%d",__LINE__);
10163 pic16_emitcode(";BUG!? ","%d",__LINE__);
10167 pic16_emitcode(";BUG!? ","%d",__LINE__);
10172 /* this should never happen */
10173 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10174 "got unknown pointer type");
10177 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10181 /* just copy the pointers */
10182 size = AOP_SIZE(result);
10185 pic16_aopPut(AOP(result),
10186 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10195 /* so we now know that the size of destination is greater
10196 than the size of the source.
10197 Now, if the next iCode is an operator then we might be
10198 able to optimize the operation without performing a cast.
10200 if(genMixedOperation(ic))
10203 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10205 /* we move to result for the size of source */
10206 size = AOP_SIZE(right);
10209 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10210 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10214 /* now depending on the sign of the destination */
10215 size = AOP_SIZE(result) - AOP_SIZE(right);
10216 /* if unsigned or not an integral type */
10217 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10219 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10221 /* we need to extend the sign :( */
10224 /* Save one instruction of casting char to int */
10225 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10226 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10227 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10229 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10232 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10234 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10236 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10239 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10244 pic16_freeAsmop(right,NULL,ic,TRUE);
10245 pic16_freeAsmop(result,NULL,ic,TRUE);
10249 /*-----------------------------------------------------------------*/
10250 /* genDjnz - generate decrement & jump if not zero instrucion */
10251 /*-----------------------------------------------------------------*/
10252 static int genDjnz (iCode *ic, iCode *ifx)
10254 symbol *lbl, *lbl1;
10255 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10260 /* if the if condition has a false label
10261 then we cannot save */
10265 /* if the minus is not of the form
10267 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10268 !IS_OP_LITERAL(IC_RIGHT(ic)))
10271 if (operandLitValue(IC_RIGHT(ic)) != 1)
10274 /* if the size of this greater than one then no
10276 if (getSize(operandType(IC_RESULT(ic))) > 1)
10279 /* otherwise we can save BIG */
10280 lbl = newiTempLabel(NULL);
10281 lbl1= newiTempLabel(NULL);
10283 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10285 if (IS_AOP_PREG(IC_RESULT(ic))) {
10286 pic16_emitcode("dec","%s",
10287 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10288 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10289 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10293 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10294 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10296 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10297 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10300 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10301 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10302 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10303 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10306 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10307 ifx->generated = 1;
10311 /*-----------------------------------------------------------------*/
10312 /* genReceive - generate code for a receive iCode */
10313 /*-----------------------------------------------------------------*/
10314 static void genReceive (iCode *ic)
10316 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10318 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10319 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10320 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10322 int size = getSize(operandType(IC_RESULT(ic)));
10323 int offset = pic16_fReturnSizePic - size;
10326 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10327 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10331 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10333 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10334 size = AOP_SIZE(IC_RESULT(ic));
10337 pic16_emitcode ("pop","acc");
10338 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10341 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10344 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10346 assignResultValue(IC_RESULT(ic));
10349 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10352 /*-----------------------------------------------------------------*/
10353 /* genDummyRead - generate code for dummy read of volatiles */
10354 /*-----------------------------------------------------------------*/
10356 genDummyRead (iCode * ic)
10358 pic16_emitcode ("; genDummyRead","");
10359 pic16_emitcode ("; not implemented","");
10364 /*-----------------------------------------------------------------*/
10365 /* genpic16Code - generate code for pic16 based controllers */
10366 /*-----------------------------------------------------------------*/
10368 * At this point, ralloc.c has gone through the iCode and attempted
10369 * to optimize in a way suitable for a PIC. Now we've got to generate
10370 * PIC instructions that correspond to the iCode.
10372 * Once the instructions are generated, we'll pass through both the
10373 * peep hole optimizer and the pCode optimizer.
10374 *-----------------------------------------------------------------*/
10376 void genpic16Code (iCode *lic)
10381 lineHead = lineCurr = NULL;
10383 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10384 pic16_addpBlock(pb);
10387 /* if debug information required */
10388 if (options.debug && currFunc) {
10390 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10392 if (IS_STATIC(currFunc->etype)) {
10393 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10394 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10396 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10397 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10406 for (ic = lic ; ic ; ic = ic->next ) {
10408 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10409 // DEBUGpic16_emitcode("; VR", "");
10410 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10411 if ( cln != ic->lineno ) {
10412 if ( options.debug ) {
10414 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10415 FileBaseName(ic->filename),ic->lineno,
10416 ic->level,ic->block);
10420 if(!options.noCcodeInAsm) {
10421 pic16_addpCode2pBlock(pb,
10422 pic16_newpCodeCSource(ic->lineno, ic->filename,
10423 printCLine(ic->filename, ic->lineno)));
10429 if(options.iCodeInAsm) {
10430 /* insert here code to print iCode as comment */
10431 pic16_emitcomment("; ic:%d: %s", ic->seq, printILine(ic));
10434 /* if the result is marked as
10435 spilt and rematerializable or code for
10436 this has already been generated then
10438 if (resultRemat(ic) || ic->generated )
10441 /* depending on the operation */
10460 /* IPOP happens only when trying to restore a
10461 spilt live range, if there is an ifx statement
10462 following this pop then the if statement might
10463 be using some of the registers being popped which
10464 would destroy the contents of the register so
10465 we need to check for this condition and handle it */
10467 ic->next->op == IFX &&
10468 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10469 genIfx (ic->next,ic);
10487 genEndFunction (ic);
10503 pic16_genPlus (ic) ;
10507 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10508 pic16_genMinus (ic);
10524 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10528 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10535 /* note these two are xlated by algebraic equivalence
10536 during parsing SDCC.y */
10537 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10538 "got '>=' or '<=' shouldn't have come here");
10542 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10554 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10558 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10562 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10586 genRightShift (ic);
10589 case GET_VALUE_AT_ADDRESS:
10594 if (POINTER_SET(ic))
10621 addSet(&_G.sendSet,ic);
10624 case DUMMY_READ_VOLATILE:
10634 /* now we are ready to call the
10635 peep hole optimizer */
10636 if (!options.nopeep) {
10637 peepHole (&lineHead);
10639 /* now do the actual printing */
10640 printLine (lineHead,codeOutFile);
10643 DFPRINTF((stderr,"printing pBlock\n\n"));
10644 pic16_printpBlock(stdout,pb);