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;
3892 /*-----------------------------------------------------------------*/
3894 /*-----------------------------------------------------------------*/
3895 static void genSkipz(iCode *ifx, int condition)
3906 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3908 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3911 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3913 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3916 /*-----------------------------------------------------------------*/
3918 /*-----------------------------------------------------------------*/
3919 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3925 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3927 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3930 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3931 rifx->generated = 1;
3935 /*-----------------------------------------------------------------*/
3936 /* genChkZeroes :- greater or less than comparison */
3937 /* For each byte in a literal that is zero, inclusive or the */
3938 /* the corresponding byte in the operand with W */
3939 /* returns true if any of the bytes are zero */
3940 /*-----------------------------------------------------------------*/
3941 static int genChkZeroes(operand *op, int lit, int size)
3948 i = (lit >> (size*8)) & 0xff;
3952 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3954 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3963 /*-----------------------------------------------------------------*/
3964 /* genCmp :- greater or less than comparison */
3965 /*-----------------------------------------------------------------*/
3966 static void genCmp (operand *left,operand *right,
3967 operand *result, iCode *ifx, int sign)
3969 int size; //, offset = 0 ;
3970 unsigned long lit = 0L,i = 0;
3971 resolvedIfx rFalseIfx;
3972 // resolvedIfx rTrueIfx;
3974 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3977 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3978 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3982 resolveIfx(&rFalseIfx,ifx);
3983 truelbl = newiTempLabel(NULL);
3984 size = max(AOP_SIZE(left),AOP_SIZE(right));
3986 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3990 /* if literal is on the right then swap with left */
3991 if ((AOP_TYPE(right) == AOP_LIT)) {
3992 operand *tmp = right ;
3993 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3994 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3997 lit = (lit - 1) & mask;
4000 rFalseIfx.condition ^= 1;
4003 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4004 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4008 //if(IC_TRUE(ifx) == NULL)
4009 /* if left & right are bit variables */
4010 if (AOP_TYPE(left) == AOP_CRY &&
4011 AOP_TYPE(right) == AOP_CRY ) {
4012 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4013 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4015 /* subtract right from left if at the
4016 end the carry flag is set then we know that
4017 left is greater than right */
4021 symbol *lbl = newiTempLabel(NULL);
4024 if(AOP_TYPE(right) == AOP_LIT) {
4026 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4028 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4035 genSkipCond(&rFalseIfx,left,size-1,7);
4037 /* no need to compare to 0...*/
4038 /* NOTE: this is a de-generate compare that most certainly
4039 * creates some dead code. */
4040 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4042 if(ifx) ifx->generated = 1;
4049 //i = (lit >> (size*8)) & 0xff;
4050 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4052 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4054 i = ((0-lit) & 0xff);
4057 /* lit is 0x7f, all signed chars are less than
4058 * this except for 0x7f itself */
4059 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4060 genSkipz2(&rFalseIfx,0);
4062 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4063 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4064 genSkipc(&rFalseIfx);
4069 genSkipz2(&rFalseIfx,1);
4071 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4072 genSkipc(&rFalseIfx);
4076 if(ifx) ifx->generated = 1;
4080 /* chars are out of the way. now do ints and longs */
4083 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4090 genSkipCond(&rFalseIfx,left,size,7);
4091 if(ifx) ifx->generated = 1;
4096 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4098 //rFalseIfx.condition ^= 1;
4099 //genSkipCond(&rFalseIfx,left,size,7);
4100 //rFalseIfx.condition ^= 1;
4102 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4103 if(rFalseIfx.condition)
4104 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4106 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4108 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4109 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4110 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4113 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4115 if(rFalseIfx.condition) {
4117 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4123 genSkipc(&rFalseIfx);
4124 pic16_emitpLabel(truelbl->key);
4125 if(ifx) ifx->generated = 1;
4132 if( (lit & 0xff) == 0) {
4133 /* lower byte is zero */
4134 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4135 i = ((lit >> 8) & 0xff) ^0x80;
4136 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4137 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4138 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4139 genSkipc(&rFalseIfx);
4142 if(ifx) ifx->generated = 1;
4147 /* Special cases for signed longs */
4148 if( (lit & 0xffffff) == 0) {
4149 /* lower byte is zero */
4150 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4151 i = ((lit >> 8*3) & 0xff) ^0x80;
4152 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4153 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4154 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4155 genSkipc(&rFalseIfx);
4158 if(ifx) ifx->generated = 1;
4166 if(lit & (0x80 << (size*8))) {
4167 /* lit is negative */
4168 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4170 //genSkipCond(&rFalseIfx,left,size,7);
4172 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4174 if(rFalseIfx.condition)
4175 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4177 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4181 /* lit is positive */
4182 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4183 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4184 if(rFalseIfx.condition)
4185 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4187 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4192 This works, but is only good for ints.
4193 It also requires a "known zero" register.
4194 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4195 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4196 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4197 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4198 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4199 genSkipc(&rFalseIfx);
4201 pic16_emitpLabel(truelbl->key);
4202 if(ifx) ifx->generated = 1;
4206 /* There are no more special cases, so perform a general compare */
4208 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4209 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4213 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4215 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4217 //rFalseIfx.condition ^= 1;
4218 genSkipc(&rFalseIfx);
4220 pic16_emitpLabel(truelbl->key);
4222 if(ifx) ifx->generated = 1;
4229 /* sign is out of the way. So now do an unsigned compare */
4230 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4233 /* General case - compare to an unsigned literal on the right.*/
4235 i = (lit >> (size*8)) & 0xff;
4236 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4237 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4239 i = (lit >> (size*8)) & 0xff;
4242 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4244 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4246 /* this byte of the lit is zero,
4247 *if it's not the last then OR in the variable */
4249 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4254 pic16_emitpLabel(lbl->key);
4255 //if(emitFinalCheck)
4256 genSkipc(&rFalseIfx);
4258 pic16_emitpLabel(truelbl->key);
4260 if(ifx) ifx->generated = 1;
4267 if(AOP_TYPE(left) == AOP_LIT) {
4268 //symbol *lbl = newiTempLabel(NULL);
4270 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4273 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4276 if((lit == 0) && (sign == 0)){
4279 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4281 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4283 genSkipz2(&rFalseIfx,0);
4284 if(ifx) ifx->generated = 1;
4291 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4292 /* degenerate compare can never be true */
4293 if(rFalseIfx.condition == 0)
4294 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4296 if(ifx) ifx->generated = 1;
4301 /* signed comparisons to a literal byte */
4303 int lp1 = (lit+1) & 0xff;
4305 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4308 rFalseIfx.condition ^= 1;
4309 genSkipCond(&rFalseIfx,right,0,7);
4312 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4313 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4314 genSkipz2(&rFalseIfx,1);
4317 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4318 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4319 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4320 rFalseIfx.condition ^= 1;
4321 genSkipc(&rFalseIfx);
4325 /* unsigned comparisons to a literal byte */
4327 switch(lit & 0xff ) {
4329 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4330 genSkipz2(&rFalseIfx,0);
4333 rFalseIfx.condition ^= 1;
4334 genSkipCond(&rFalseIfx,right,0,7);
4338 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4339 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4340 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4341 rFalseIfx.condition ^= 1;
4342 if (AOP_TYPE(result) == AOP_CRY)
4343 genSkipc(&rFalseIfx);
4345 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4346 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4352 if(ifx) ifx->generated = 1;
4358 /* Size is greater than 1 */
4366 /* this means lit = 0xffffffff, or -1 */
4369 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4370 rFalseIfx.condition ^= 1;
4371 genSkipCond(&rFalseIfx,right,size,7);
4372 if(ifx) ifx->generated = 1;
4379 if(rFalseIfx.condition) {
4380 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4381 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4384 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4386 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4390 if(rFalseIfx.condition) {
4391 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4392 pic16_emitpLabel(truelbl->key);
4394 rFalseIfx.condition ^= 1;
4395 genSkipCond(&rFalseIfx,right,s,7);
4398 if(ifx) ifx->generated = 1;
4402 if((size == 1) && (0 == (lp1&0xff))) {
4403 /* lower byte of signed word is zero */
4404 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4405 i = ((lp1 >> 8) & 0xff) ^0x80;
4406 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4407 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4408 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4409 rFalseIfx.condition ^= 1;
4410 genSkipc(&rFalseIfx);
4413 if(ifx) ifx->generated = 1;
4417 if(lit & (0x80 << (size*8))) {
4418 /* Lit is less than zero */
4419 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4420 //rFalseIfx.condition ^= 1;
4421 //genSkipCond(&rFalseIfx,left,size,7);
4422 //rFalseIfx.condition ^= 1;
4423 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4424 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4426 if(rFalseIfx.condition)
4427 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4429 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4433 /* Lit is greater than or equal to zero */
4434 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4435 //rFalseIfx.condition ^= 1;
4436 //genSkipCond(&rFalseIfx,right,size,7);
4437 //rFalseIfx.condition ^= 1;
4439 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4440 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4442 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4443 if(rFalseIfx.condition)
4444 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4446 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4451 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4452 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4456 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4458 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4460 rFalseIfx.condition ^= 1;
4461 //rFalseIfx.condition = 1;
4462 genSkipc(&rFalseIfx);
4464 pic16_emitpLabel(truelbl->key);
4466 if(ifx) ifx->generated = 1;
4471 /* compare word or long to an unsigned literal on the right.*/
4476 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4479 break; /* handled above */
4482 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4484 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4485 genSkipz2(&rFalseIfx,0);
4489 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4491 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4494 if(rFalseIfx.condition)
4495 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4497 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4500 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4501 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4503 rFalseIfx.condition ^= 1;
4504 genSkipc(&rFalseIfx);
4507 pic16_emitpLabel(truelbl->key);
4509 if(ifx) ifx->generated = 1;
4515 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4516 i = (lit >> (size*8)) & 0xff;
4518 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4519 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4522 i = (lit >> (size*8)) & 0xff;
4525 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4527 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4529 /* this byte of the lit is zero,
4530 *if it's not the last then OR in the variable */
4532 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4537 pic16_emitpLabel(lbl->key);
4539 rFalseIfx.condition ^= 1;
4540 genSkipc(&rFalseIfx);
4544 pic16_emitpLabel(truelbl->key);
4545 if(ifx) ifx->generated = 1;
4549 /* Compare two variables */
4551 DEBUGpic16_emitcode(";sign","%d",sign);
4555 /* Sigh. thus sucks... */
4557 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4558 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4559 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4560 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4561 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4562 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4564 /* Signed char comparison */
4565 /* Special thanks to Nikolai Golovchenko for this snippet */
4566 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4567 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4568 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4569 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4570 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4571 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4573 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4574 genSkipc(&rFalseIfx);
4576 if(ifx) ifx->generated = 1;
4582 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4583 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4587 /* The rest of the bytes of a multi-byte compare */
4591 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4594 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4595 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4600 pic16_emitpLabel(lbl->key);
4602 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4603 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4604 (AOP_TYPE(result) == AOP_REG)) {
4605 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4606 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4608 genSkipc(&rFalseIfx);
4610 //genSkipc(&rFalseIfx);
4611 if(ifx) ifx->generated = 1;
4618 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4619 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4620 pic16_outBitC(result);
4622 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4623 /* if the result is used in the next
4624 ifx conditional branch then generate
4625 code a little differently */
4627 genIfxJump (ifx,"c");
4629 pic16_outBitC(result);
4630 /* leave the result in acc */
4635 /*-----------------------------------------------------------------*/
4636 /* genCmpGt :- greater than comparison */
4637 /*-----------------------------------------------------------------*/
4638 static void genCmpGt (iCode *ic, iCode *ifx)
4640 operand *left, *right, *result;
4641 sym_link *letype , *retype;
4644 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4646 right= IC_RIGHT(ic);
4647 result = IC_RESULT(ic);
4649 letype = getSpec(operandType(left));
4650 retype =getSpec(operandType(right));
4651 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4652 /* assign the amsops */
4653 pic16_aopOp (left,ic,FALSE);
4654 pic16_aopOp (right,ic,FALSE);
4655 pic16_aopOp (result,ic,TRUE);
4657 genCmp(right, left, result, ifx, sign);
4659 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4660 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4661 pic16_freeAsmop(result,NULL,ic,TRUE);
4664 /*-----------------------------------------------------------------*/
4665 /* genCmpLt - less than comparisons */
4666 /*-----------------------------------------------------------------*/
4667 static void genCmpLt (iCode *ic, iCode *ifx)
4669 operand *left, *right, *result;
4670 sym_link *letype , *retype;
4673 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4675 right= IC_RIGHT(ic);
4676 result = IC_RESULT(ic);
4678 letype = getSpec(operandType(left));
4679 retype =getSpec(operandType(right));
4680 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4682 /* assign the amsops */
4683 pic16_aopOp (left,ic,FALSE);
4684 pic16_aopOp (right,ic,FALSE);
4685 pic16_aopOp (result,ic,TRUE);
4687 genCmp(left, right, result, ifx, sign);
4689 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4690 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4691 pic16_freeAsmop(result,NULL,ic,TRUE);
4694 /*-----------------------------------------------------------------*/
4695 /* genc16bit2lit - compare a 16 bit value to a literal */
4696 /*-----------------------------------------------------------------*/
4697 static void genc16bit2lit(operand *op, int lit, int offset)
4701 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4702 if( (lit&0xff) == 0)
4707 switch( BYTEofLONG(lit,i)) {
4709 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4712 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4715 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4718 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4719 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4724 switch( BYTEofLONG(lit,i)) {
4726 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4730 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4734 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4737 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4739 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4745 /*-----------------------------------------------------------------*/
4746 /* gencjneshort - compare and jump if not equal */
4747 /*-----------------------------------------------------------------*/
4748 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4750 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4752 int res_offset = 0; /* the result may be a different size then left or right */
4753 int res_size = AOP_SIZE(result);
4757 unsigned long lit = 0L;
4758 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4759 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4761 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4762 resolveIfx(&rIfx,ifx);
4763 lbl = newiTempLabel(NULL);
4766 /* if the left side is a literal or
4767 if the right is in a pointer register and left
4769 if ((AOP_TYPE(left) == AOP_LIT) ||
4770 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4775 if(AOP_TYPE(right) == AOP_LIT)
4776 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4778 /* if the right side is a literal then anything goes */
4779 if (AOP_TYPE(right) == AOP_LIT &&
4780 AOP_TYPE(left) != AOP_DIR ) {
4783 genc16bit2lit(left, lit, 0);
4785 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4790 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4791 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4793 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4797 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4799 if(res_offset < res_size-1)
4807 /* if the right side is in a register or in direct space or
4808 if the left is a pointer register & right is not */
4809 else if (AOP_TYPE(right) == AOP_REG ||
4810 AOP_TYPE(right) == AOP_DIR ||
4811 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4812 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4813 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4814 int lbl_key = lbl->key;
4817 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4818 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4820 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4821 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4822 __FUNCTION__,__LINE__);
4826 /* switch(size) { */
4828 /* genc16bit2lit(left, lit, 0); */
4830 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4835 if((AOP_TYPE(left) == AOP_DIR) &&
4836 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4838 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4839 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4841 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4843 switch (lit & 0xff) {
4845 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4848 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4849 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4850 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4854 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4855 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4856 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4857 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4861 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4862 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4867 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4870 if(AOP_TYPE(result) == AOP_CRY) {
4871 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4876 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4878 /* fix me. probably need to check result size too */
4879 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4884 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4885 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4892 if(res_offset < res_size-1)
4897 } else if(AOP_TYPE(right) == AOP_REG &&
4898 AOP_TYPE(left) != AOP_DIR){
4901 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4902 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4903 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4908 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4910 if(res_offset < res_size-1)
4915 /* right is a pointer reg need both a & b */
4917 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4919 pic16_emitcode("mov","b,%s",l);
4920 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4921 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4926 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4928 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4930 pic16_emitpLabel(lbl->key);
4932 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4939 /*-----------------------------------------------------------------*/
4940 /* gencjne - compare and jump if not equal */
4941 /*-----------------------------------------------------------------*/
4942 static void gencjne(operand *left, operand *right, iCode *ifx)
4944 symbol *tlbl = newiTempLabel(NULL);
4946 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4947 gencjneshort(left, right, lbl);
4949 pic16_emitcode("mov","a,%s",one);
4950 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4951 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4952 pic16_emitcode("clr","a");
4953 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4955 pic16_emitpLabel(lbl->key);
4956 pic16_emitpLabel(tlbl->key);
4961 /*-----------------------------------------------------------------*/
4962 /* genCmpEq - generates code for equal to */
4963 /*-----------------------------------------------------------------*/
4964 static void genCmpEq (iCode *ic, iCode *ifx)
4966 operand *left, *right, *result;
4967 unsigned long lit = 0L;
4969 symbol *falselbl = newiTempLabel(NULL);
4972 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4975 DEBUGpic16_emitcode ("; ifx is non-null","");
4977 DEBUGpic16_emitcode ("; ifx is null","");
4979 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4980 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4981 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4983 size = max(AOP_SIZE(left),AOP_SIZE(right));
4985 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4987 /* if literal, literal on the right or
4988 if the right is in a pointer register and left
4990 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4991 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4992 operand *tmp = right ;
4998 if(ifx && !AOP_SIZE(result)){
5000 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5001 /* if they are both bit variables */
5002 if (AOP_TYPE(left) == AOP_CRY &&
5003 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5004 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5005 if(AOP_TYPE(right) == AOP_LIT){
5006 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5008 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5009 pic16_emitcode("cpl","c");
5010 } else if(lit == 1L) {
5011 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5013 pic16_emitcode("clr","c");
5015 /* AOP_TYPE(right) == AOP_CRY */
5017 symbol *lbl = newiTempLabel(NULL);
5018 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5019 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5020 pic16_emitcode("cpl","c");
5021 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5023 /* if true label then we jump if condition
5025 tlbl = newiTempLabel(NULL);
5026 if ( IC_TRUE(ifx) ) {
5027 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5028 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5030 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5031 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5033 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5036 /* left and right are both bit variables, result is carry */
5039 resolveIfx(&rIfx,ifx);
5041 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5042 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5043 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5044 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5049 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5051 /* They're not both bit variables. Is the right a literal? */
5052 if(AOP_TYPE(right) == AOP_LIT) {
5053 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5058 switch(lit & 0xff) {
5060 if ( IC_TRUE(ifx) ) {
5061 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5063 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5065 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5066 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5070 if ( IC_TRUE(ifx) ) {
5071 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5073 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5075 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5076 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5080 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5082 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5087 /* end of size == 1 */
5091 genc16bit2lit(left,lit,offset);
5094 /* end of size == 2 */
5099 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5100 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5101 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5102 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5105 /* search for patterns that can be optimized */
5107 genc16bit2lit(left,lit,0);
5111 emitSKPZ; // if hi word unequal
5113 emitSKPNZ; // if hi word equal
5115 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5116 genc16bit2lit(left,lit,2);
5119 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5120 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5124 pic16_emitpLabel(falselbl->key);
5133 } else if(AOP_TYPE(right) == AOP_CRY ) {
5134 /* we know the left is not a bit, but that the right is */
5135 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5136 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5137 pic16_popGet(AOP(right),offset));
5138 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5140 /* if the two are equal, then W will be 0 and the Z bit is set
5141 * we could test Z now, or go ahead and check the high order bytes if
5142 * the variable we're comparing is larger than a byte. */
5145 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5147 if ( IC_TRUE(ifx) ) {
5149 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5150 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5153 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5154 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5158 /* They're both variables that are larger than bits */
5161 tlbl = newiTempLabel(NULL);
5164 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5165 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5167 if ( IC_TRUE(ifx) ) {
5171 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5173 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5174 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5178 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5181 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5182 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5187 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5189 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5190 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5194 if(s>1 && IC_TRUE(ifx)) {
5195 pic16_emitpLabel(tlbl->key);
5196 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5200 /* mark the icode as generated */
5205 /* if they are both bit variables */
5206 if (AOP_TYPE(left) == AOP_CRY &&
5207 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5208 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5209 if(AOP_TYPE(right) == AOP_LIT){
5210 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5212 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5213 pic16_emitcode("cpl","c");
5214 } else if(lit == 1L) {
5215 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5217 pic16_emitcode("clr","c");
5219 /* AOP_TYPE(right) == AOP_CRY */
5221 symbol *lbl = newiTempLabel(NULL);
5222 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5223 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5224 pic16_emitcode("cpl","c");
5225 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5228 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5229 pic16_outBitC(result);
5233 genIfxJump (ifx,"c");
5236 /* if the result is used in an arithmetic operation
5237 then put the result in place */
5238 pic16_outBitC(result);
5241 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5242 gencjne(left,right,result,ifx);
5245 gencjne(left,right,newiTempLabel(NULL));
5247 if(IC_TRUE(ifx)->key)
5248 gencjne(left,right,IC_TRUE(ifx)->key);
5250 gencjne(left,right,IC_FALSE(ifx)->key);
5254 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5255 pic16_aopPut(AOP(result),"a",0);
5260 genIfxJump (ifx,"a");
5264 /* if the result is used in an arithmetic operation
5265 then put the result in place */
5267 if (AOP_TYPE(result) != AOP_CRY)
5268 pic16_outAcc(result);
5270 /* leave the result in acc */
5274 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5275 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5276 pic16_freeAsmop(result,NULL,ic,TRUE);
5279 /*-----------------------------------------------------------------*/
5280 /* ifxForOp - returns the icode containing the ifx for operand */
5281 /*-----------------------------------------------------------------*/
5282 static iCode *ifxForOp ( operand *op, iCode *ic )
5284 /* if true symbol then needs to be assigned */
5285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5286 if (IS_TRUE_SYMOP(op))
5289 /* if this has register type condition and
5290 the next instruction is ifx with the same operand
5291 and live to of the operand is upto the ifx only then */
5293 ic->next->op == IFX &&
5294 IC_COND(ic->next)->key == op->key &&
5295 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5299 ic->next->op == IFX &&
5300 IC_COND(ic->next)->key == op->key) {
5301 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5305 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5307 ic->next->op == IFX)
5308 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5311 ic->next->op == IFX &&
5312 IC_COND(ic->next)->key == op->key) {
5313 DEBUGpic16_emitcode ("; "," key is okay");
5314 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5315 OP_SYMBOL(op)->liveTo,
5322 /*-----------------------------------------------------------------*/
5323 /* genAndOp - for && operation */
5324 /*-----------------------------------------------------------------*/
5325 static void genAndOp (iCode *ic)
5327 operand *left,*right, *result;
5330 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5331 /* note here that && operations that are in an
5332 if statement are taken away by backPatchLabels
5333 only those used in arthmetic operations remain */
5334 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5335 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5336 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5338 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5340 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5341 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5342 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5344 /* if both are bit variables */
5345 /* if (AOP_TYPE(left) == AOP_CRY && */
5346 /* AOP_TYPE(right) == AOP_CRY ) { */
5347 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5348 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5349 /* pic16_outBitC(result); */
5351 /* tlbl = newiTempLabel(NULL); */
5352 /* pic16_toBoolean(left); */
5353 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5354 /* pic16_toBoolean(right); */
5355 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5356 /* pic16_outBitAcc(result); */
5359 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5360 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5361 pic16_freeAsmop(result,NULL,ic,TRUE);
5365 /*-----------------------------------------------------------------*/
5366 /* genOrOp - for || operation */
5367 /*-----------------------------------------------------------------*/
5370 modified this code, but it doesn't appear to ever get called
5373 static void genOrOp (iCode *ic)
5375 operand *left,*right, *result;
5378 /* note here that || operations that are in an
5379 if statement are taken away by backPatchLabels
5380 only those used in arthmetic operations remain */
5381 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5382 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5383 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5384 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5386 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5388 /* if both are bit variables */
5389 if (AOP_TYPE(left) == AOP_CRY &&
5390 AOP_TYPE(right) == AOP_CRY ) {
5391 pic16_emitcode("clrc","");
5392 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5393 AOP(left)->aopu.aop_dir,
5394 AOP(left)->aopu.aop_dir);
5395 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5396 AOP(right)->aopu.aop_dir,
5397 AOP(right)->aopu.aop_dir);
5398 pic16_emitcode("setc","");
5401 tlbl = newiTempLabel(NULL);
5402 pic16_toBoolean(left);
5404 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5405 pic16_toBoolean(right);
5406 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5408 pic16_outBitAcc(result);
5411 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5412 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5413 pic16_freeAsmop(result,NULL,ic,TRUE);
5416 /*-----------------------------------------------------------------*/
5417 /* isLiteralBit - test if lit == 2^n */
5418 /*-----------------------------------------------------------------*/
5419 static int isLiteralBit(unsigned long lit)
5421 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5422 0x100L,0x200L,0x400L,0x800L,
5423 0x1000L,0x2000L,0x4000L,0x8000L,
5424 0x10000L,0x20000L,0x40000L,0x80000L,
5425 0x100000L,0x200000L,0x400000L,0x800000L,
5426 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5427 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5430 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5431 for(idx = 0; idx < 32; idx++)
5437 /*-----------------------------------------------------------------*/
5438 /* continueIfTrue - */
5439 /*-----------------------------------------------------------------*/
5440 static void continueIfTrue (iCode *ic)
5442 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5444 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5448 /*-----------------------------------------------------------------*/
5450 /*-----------------------------------------------------------------*/
5451 static void jumpIfTrue (iCode *ic)
5453 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5455 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5459 /*-----------------------------------------------------------------*/
5460 /* jmpTrueOrFalse - */
5461 /*-----------------------------------------------------------------*/
5462 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5464 // ugly but optimized by peephole
5465 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5467 symbol *nlbl = newiTempLabel(NULL);
5468 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5469 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5470 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5471 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5474 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5475 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5480 /*-----------------------------------------------------------------*/
5481 /* genAnd - code for and */
5482 /*-----------------------------------------------------------------*/
5483 static void genAnd (iCode *ic, iCode *ifx)
5485 operand *left, *right, *result;
5487 unsigned long lit = 0L;
5492 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5493 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5494 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5495 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5497 resolveIfx(&rIfx,ifx);
5499 /* if left is a literal & right is not then exchange them */
5500 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5501 AOP_NEEDSACC(left)) {
5502 operand *tmp = right ;
5507 /* if result = right then exchange them */
5508 if(pic16_sameRegs(AOP(result),AOP(right))){
5509 operand *tmp = right ;
5514 /* if right is bit then exchange them */
5515 if (AOP_TYPE(right) == AOP_CRY &&
5516 AOP_TYPE(left) != AOP_CRY){
5517 operand *tmp = right ;
5521 if(AOP_TYPE(right) == AOP_LIT)
5522 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5524 size = AOP_SIZE(result);
5526 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5529 // result = bit & yy;
5530 if (AOP_TYPE(left) == AOP_CRY){
5531 // c = bit & literal;
5532 if(AOP_TYPE(right) == AOP_LIT){
5534 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5537 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5540 if(size && (AOP_TYPE(result) == AOP_CRY)){
5541 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5544 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5548 pic16_emitcode("clr","c");
5551 if (AOP_TYPE(right) == AOP_CRY){
5553 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5554 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5557 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5559 pic16_emitcode("rrc","a");
5560 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5566 pic16_outBitC(result);
5568 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5569 genIfxJump(ifx, "c");
5573 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5574 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5575 if((AOP_TYPE(right) == AOP_LIT) &&
5576 (AOP_TYPE(result) == AOP_CRY) &&
5577 (AOP_TYPE(left) != AOP_CRY)){
5578 int posbit = isLiteralBit(lit);
5582 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5585 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5591 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5592 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5594 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5595 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5598 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5599 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5600 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5607 symbol *tlbl = newiTempLabel(NULL);
5608 int sizel = AOP_SIZE(left);
5610 pic16_emitcode("setb","c");
5612 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5613 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5615 if((posbit = isLiteralBit(bytelit)) != 0)
5616 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5618 if(bytelit != 0x0FFL)
5619 pic16_emitcode("anl","a,%s",
5620 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5621 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5626 // bit = left & literal
5628 pic16_emitcode("clr","c");
5629 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5631 // if(left & literal)
5634 jmpTrueOrFalse(ifx, tlbl);
5638 pic16_outBitC(result);
5642 /* if left is same as result */
5643 if(pic16_sameRegs(AOP(result),AOP(left))){
5645 for(;size--; offset++,lit>>=8) {
5646 if(AOP_TYPE(right) == AOP_LIT){
5647 switch(lit & 0xff) {
5649 /* and'ing with 0 has clears the result */
5650 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5651 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5654 /* and'ing with 0xff is a nop when the result and left are the same */
5659 int p = my_powof2( (~lit) & 0xff );
5661 /* only one bit is set in the literal, so use a bcf instruction */
5662 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5663 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5666 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5667 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5668 if(know_W != (lit&0xff))
5669 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5671 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5676 if (AOP_TYPE(left) == AOP_ACC) {
5677 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5679 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5680 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5687 // left & result in different registers
5688 if(AOP_TYPE(result) == AOP_CRY){
5690 // if(size), result in bit
5691 // if(!size && ifx), conditional oper: if(left & right)
5692 symbol *tlbl = newiTempLabel(NULL);
5693 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5695 pic16_emitcode("setb","c");
5697 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5698 pic16_emitcode("anl","a,%s",
5699 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5700 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5705 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5706 pic16_outBitC(result);
5708 jmpTrueOrFalse(ifx, tlbl);
5710 for(;(size--);offset++) {
5712 // result = left & right
5713 if(AOP_TYPE(right) == AOP_LIT){
5714 int t = (lit >> (offset*8)) & 0x0FFL;
5717 pic16_emitcode("clrf","%s",
5718 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5719 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5722 pic16_emitcode("movf","%s,w",
5723 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5724 pic16_emitcode("movwf","%s",
5725 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5726 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5727 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5730 pic16_emitcode("movlw","0x%x",t);
5731 pic16_emitcode("andwf","%s,w",
5732 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5733 pic16_emitcode("movwf","%s",
5734 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5736 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5737 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5738 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5743 if (AOP_TYPE(left) == AOP_ACC) {
5744 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5745 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5747 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5748 pic16_emitcode("andwf","%s,w",
5749 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5750 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5751 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5753 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5754 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5760 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5761 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5762 pic16_freeAsmop(result,NULL,ic,TRUE);
5765 /*-----------------------------------------------------------------*/
5766 /* genOr - code for or */
5767 /*-----------------------------------------------------------------*/
5768 static void genOr (iCode *ic, iCode *ifx)
5770 operand *left, *right, *result;
5772 unsigned long lit = 0L;
5774 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5776 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5777 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5778 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5780 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5782 /* if left is a literal & right is not then exchange them */
5783 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5784 AOP_NEEDSACC(left)) {
5785 operand *tmp = right ;
5790 /* if result = right then exchange them */
5791 if(pic16_sameRegs(AOP(result),AOP(right))){
5792 operand *tmp = right ;
5797 /* if right is bit then exchange them */
5798 if (AOP_TYPE(right) == AOP_CRY &&
5799 AOP_TYPE(left) != AOP_CRY){
5800 operand *tmp = right ;
5805 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5807 if(AOP_TYPE(right) == AOP_LIT)
5808 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5810 size = AOP_SIZE(result);
5814 if (AOP_TYPE(left) == AOP_CRY){
5815 if(AOP_TYPE(right) == AOP_LIT){
5816 // c = bit & literal;
5818 // lit != 0 => result = 1
5819 if(AOP_TYPE(result) == AOP_CRY){
5821 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5822 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5823 // AOP(result)->aopu.aop_dir,
5824 // AOP(result)->aopu.aop_dir);
5826 continueIfTrue(ifx);
5830 // lit == 0 => result = left
5831 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5833 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5836 if (AOP_TYPE(right) == AOP_CRY){
5837 if(pic16_sameRegs(AOP(result),AOP(left))){
5839 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5840 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5841 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5843 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5844 AOP(result)->aopu.aop_dir,
5845 AOP(result)->aopu.aop_dir);
5846 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5847 AOP(right)->aopu.aop_dir,
5848 AOP(right)->aopu.aop_dir);
5849 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5850 AOP(result)->aopu.aop_dir,
5851 AOP(result)->aopu.aop_dir);
5853 if( AOP_TYPE(result) == AOP_ACC) {
5854 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5855 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5856 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5857 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5861 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5862 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5863 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5864 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5866 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5867 AOP(result)->aopu.aop_dir,
5868 AOP(result)->aopu.aop_dir);
5869 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5870 AOP(right)->aopu.aop_dir,
5871 AOP(right)->aopu.aop_dir);
5872 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5873 AOP(left)->aopu.aop_dir,
5874 AOP(left)->aopu.aop_dir);
5875 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5876 AOP(result)->aopu.aop_dir,
5877 AOP(result)->aopu.aop_dir);
5882 symbol *tlbl = newiTempLabel(NULL);
5883 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5886 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5887 if( AOP_TYPE(right) == AOP_ACC) {
5888 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5890 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5891 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5896 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5897 pic16_emitcode(";XXX setb","c");
5898 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5899 AOP(left)->aopu.aop_dir,tlbl->key+100);
5900 pic16_toBoolean(right);
5901 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5902 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5903 jmpTrueOrFalse(ifx, tlbl);
5907 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5914 pic16_outBitC(result);
5916 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5917 genIfxJump(ifx, "c");
5921 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5922 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5923 if((AOP_TYPE(right) == AOP_LIT) &&
5924 (AOP_TYPE(result) == AOP_CRY) &&
5925 (AOP_TYPE(left) != AOP_CRY)){
5927 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5930 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5932 continueIfTrue(ifx);
5935 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5936 // lit = 0, result = boolean(left)
5938 pic16_emitcode(";XXX setb","c");
5939 pic16_toBoolean(right);
5941 symbol *tlbl = newiTempLabel(NULL);
5942 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5944 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5946 genIfxJump (ifx,"a");
5950 pic16_outBitC(result);
5954 /* if left is same as result */
5955 if(pic16_sameRegs(AOP(result),AOP(left))){
5957 for(;size--; offset++,lit>>=8) {
5958 if(AOP_TYPE(right) == AOP_LIT){
5959 if((lit & 0xff) == 0)
5960 /* or'ing with 0 has no effect */
5963 int p = my_powof2(lit & 0xff);
5965 /* only one bit is set in the literal, so use a bsf instruction */
5966 pic16_emitpcode(POC_BSF,
5967 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5969 if(know_W != (lit & 0xff))
5970 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5971 know_W = lit & 0xff;
5972 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5977 if (AOP_TYPE(left) == AOP_ACC) {
5978 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5979 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5981 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5982 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5984 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5985 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5991 // left & result in different registers
5992 if(AOP_TYPE(result) == AOP_CRY){
5994 // if(size), result in bit
5995 // if(!size && ifx), conditional oper: if(left | right)
5996 symbol *tlbl = newiTempLabel(NULL);
5997 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5998 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6002 pic16_emitcode(";XXX setb","c");
6004 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6005 pic16_emitcode(";XXX orl","a,%s",
6006 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6007 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6012 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6013 pic16_outBitC(result);
6015 jmpTrueOrFalse(ifx, tlbl);
6016 } else for(;(size--);offset++){
6018 // result = left & right
6019 if(AOP_TYPE(right) == AOP_LIT){
6020 int t = (lit >> (offset*8)) & 0x0FFL;
6023 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6024 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6026 pic16_emitcode("movf","%s,w",
6027 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6028 pic16_emitcode("movwf","%s",
6029 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6032 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6033 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6034 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6036 pic16_emitcode("movlw","0x%x",t);
6037 pic16_emitcode("iorwf","%s,w",
6038 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6039 pic16_emitcode("movwf","%s",
6040 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6046 // faster than result <- left, anl result,right
6047 // and better if result is SFR
6048 if (AOP_TYPE(left) == AOP_ACC) {
6049 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6050 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6052 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6053 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6055 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6056 pic16_emitcode("iorwf","%s,w",
6057 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6059 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6060 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6065 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6066 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6067 pic16_freeAsmop(result,NULL,ic,TRUE);
6070 /*-----------------------------------------------------------------*/
6071 /* genXor - code for xclusive or */
6072 /*-----------------------------------------------------------------*/
6073 static void genXor (iCode *ic, iCode *ifx)
6075 operand *left, *right, *result;
6077 unsigned long lit = 0L;
6079 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6081 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6082 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6083 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6085 /* if left is a literal & right is not ||
6086 if left needs acc & right does not */
6087 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6088 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6089 operand *tmp = right ;
6094 /* if result = right then exchange them */
6095 if(pic16_sameRegs(AOP(result),AOP(right))){
6096 operand *tmp = right ;
6101 /* if right is bit then exchange them */
6102 if (AOP_TYPE(right) == AOP_CRY &&
6103 AOP_TYPE(left) != AOP_CRY){
6104 operand *tmp = right ;
6108 if(AOP_TYPE(right) == AOP_LIT)
6109 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6111 size = AOP_SIZE(result);
6115 if (AOP_TYPE(left) == AOP_CRY){
6116 if(AOP_TYPE(right) == AOP_LIT){
6117 // c = bit & literal;
6119 // lit>>1 != 0 => result = 1
6120 if(AOP_TYPE(result) == AOP_CRY){
6122 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6123 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6125 continueIfTrue(ifx);
6128 pic16_emitcode("setb","c");
6132 // lit == 0, result = left
6133 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6135 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6137 // lit == 1, result = not(left)
6138 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6139 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6140 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6141 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6144 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6145 pic16_emitcode("cpl","c");
6152 symbol *tlbl = newiTempLabel(NULL);
6153 if (AOP_TYPE(right) == AOP_CRY){
6155 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6158 int sizer = AOP_SIZE(right);
6160 // if val>>1 != 0, result = 1
6161 pic16_emitcode("setb","c");
6163 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6165 // test the msb of the lsb
6166 pic16_emitcode("anl","a,#0xfe");
6167 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6171 pic16_emitcode("rrc","a");
6173 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6174 pic16_emitcode("cpl","c");
6175 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6180 pic16_outBitC(result);
6182 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6183 genIfxJump(ifx, "c");
6187 if(pic16_sameRegs(AOP(result),AOP(left))){
6188 /* if left is same as result */
6189 for(;size--; offset++) {
6190 if(AOP_TYPE(right) == AOP_LIT){
6191 int t = (lit >> (offset*8)) & 0x0FFL;
6195 if (IS_AOP_PREG(left)) {
6196 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6197 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6198 pic16_aopPut(AOP(result),"a",offset);
6200 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6201 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6202 pic16_emitcode("xrl","%s,%s",
6203 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6204 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6207 if (AOP_TYPE(left) == AOP_ACC)
6208 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6210 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6211 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6213 if (IS_AOP_PREG(left)) {
6214 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6215 pic16_aopPut(AOP(result),"a",offset);
6217 pic16_emitcode("xrl","%s,a",
6218 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6224 // left & result in different registers
6225 if(AOP_TYPE(result) == AOP_CRY){
6227 // if(size), result in bit
6228 // if(!size && ifx), conditional oper: if(left ^ right)
6229 symbol *tlbl = newiTempLabel(NULL);
6230 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6232 pic16_emitcode("setb","c");
6234 if((AOP_TYPE(right) == AOP_LIT) &&
6235 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6236 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6238 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6239 pic16_emitcode("xrl","a,%s",
6240 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6242 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6247 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6248 pic16_outBitC(result);
6250 jmpTrueOrFalse(ifx, tlbl);
6251 } else for(;(size--);offset++){
6253 // result = left & right
6254 if(AOP_TYPE(right) == AOP_LIT){
6255 int t = (lit >> (offset*8)) & 0x0FFL;
6258 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6259 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6260 pic16_emitcode("movf","%s,w",
6261 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6262 pic16_emitcode("movwf","%s",
6263 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6266 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6267 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6268 pic16_emitcode("comf","%s,w",
6269 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6270 pic16_emitcode("movwf","%s",
6271 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6274 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6275 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6276 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6277 pic16_emitcode("movlw","0x%x",t);
6278 pic16_emitcode("xorwf","%s,w",
6279 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6280 pic16_emitcode("movwf","%s",
6281 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6287 // faster than result <- left, anl result,right
6288 // and better if result is SFR
6289 if (AOP_TYPE(left) == AOP_ACC) {
6290 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6291 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6293 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6294 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6295 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6296 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6298 if ( AOP_TYPE(result) != AOP_ACC){
6299 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6300 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6306 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6307 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6308 pic16_freeAsmop(result,NULL,ic,TRUE);
6311 /*-----------------------------------------------------------------*/
6312 /* genInline - write the inline code out */
6313 /*-----------------------------------------------------------------*/
6314 static void genInline (iCode *ic)
6316 char *buffer, *bp, *bp1;
6318 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6320 _G.inLine += (!options.asmpeep);
6322 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6323 strcpy(buffer,IC_INLINE(ic));
6325 /* emit each line as a code */
6331 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6332 // inline directly, no process
6339 pic16_emitcode(bp1,"");
6345 if ((bp1 != bp) && *bp1)
6346 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6350 _G.inLine -= (!options.asmpeep);
6353 /*-----------------------------------------------------------------*/
6354 /* genRRC - rotate right with carry */
6355 /*-----------------------------------------------------------------*/
6356 static void genRRC (iCode *ic)
6358 operand *left , *result ;
6359 int size, offset = 0, same;
6361 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6363 /* rotate right with carry */
6365 result=IC_RESULT(ic);
6366 pic16_aopOp (left,ic,FALSE);
6367 pic16_aopOp (result,ic,FALSE);
6369 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6371 same = pic16_sameRegs(AOP(result),AOP(left));
6373 size = AOP_SIZE(result);
6375 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6377 /* get the lsb and put it into the carry */
6378 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6385 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6387 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6388 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6394 pic16_freeAsmop(left,NULL,ic,TRUE);
6395 pic16_freeAsmop(result,NULL,ic,TRUE);
6398 /*-----------------------------------------------------------------*/
6399 /* genRLC - generate code for rotate left with carry */
6400 /*-----------------------------------------------------------------*/
6401 static void genRLC (iCode *ic)
6403 operand *left , *result ;
6404 int size, offset = 0;
6407 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6408 /* rotate right with carry */
6410 result=IC_RESULT(ic);
6411 pic16_aopOp (left,ic,FALSE);
6412 pic16_aopOp (result,ic,FALSE);
6414 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6416 same = pic16_sameRegs(AOP(result),AOP(left));
6418 /* move it to the result */
6419 size = AOP_SIZE(result);
6421 /* get the msb and put it into the carry */
6422 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6429 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6431 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6432 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6439 pic16_freeAsmop(left,NULL,ic,TRUE);
6440 pic16_freeAsmop(result,NULL,ic,TRUE);
6443 /*-----------------------------------------------------------------*/
6444 /* genGetHbit - generates code get highest order bit */
6445 /*-----------------------------------------------------------------*/
6446 static void genGetHbit (iCode *ic)
6448 operand *left, *result;
6450 result=IC_RESULT(ic);
6451 pic16_aopOp (left,ic,FALSE);
6452 pic16_aopOp (result,ic,FALSE);
6454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6455 /* get the highest order byte into a */
6456 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6457 if(AOP_TYPE(result) == AOP_CRY){
6458 pic16_emitcode("rlc","a");
6459 pic16_outBitC(result);
6462 pic16_emitcode("rl","a");
6463 pic16_emitcode("anl","a,#0x01");
6464 pic16_outAcc(result);
6468 pic16_freeAsmop(left,NULL,ic,TRUE);
6469 pic16_freeAsmop(result,NULL,ic,TRUE);
6472 /*-----------------------------------------------------------------*/
6473 /* AccRol - rotate left accumulator by known count */
6474 /*-----------------------------------------------------------------*/
6475 static void AccRol (int shCount)
6477 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6478 shCount &= 0x0007; // shCount : 0..7
6483 pic16_emitcode("rl","a");
6486 pic16_emitcode("rl","a");
6487 pic16_emitcode("rl","a");
6490 pic16_emitcode("swap","a");
6491 pic16_emitcode("rr","a");
6494 pic16_emitcode("swap","a");
6497 pic16_emitcode("swap","a");
6498 pic16_emitcode("rl","a");
6501 pic16_emitcode("rr","a");
6502 pic16_emitcode("rr","a");
6505 pic16_emitcode("rr","a");
6510 /*-----------------------------------------------------------------*/
6511 /* AccLsh - left shift accumulator by known count */
6512 /*-----------------------------------------------------------------*/
6513 static void AccLsh (int shCount)
6515 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6521 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6524 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6525 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6528 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6529 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6532 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6535 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6536 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6539 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6540 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6543 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6546 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
6550 /*-----------------------------------------------------------------*/
6551 /* AccRsh - right shift accumulator by known count */
6552 /*-----------------------------------------------------------------*/
6553 static void AccRsh (int shCount)
6555 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6561 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6564 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6565 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6568 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6569 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6572 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6575 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
6576 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6579 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6580 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6583 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
6586 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
6590 /*-----------------------------------------------------------------*/
6591 /* AccSRsh - signed right shift accumulator by known count */
6592 /*-----------------------------------------------------------------*/
6593 static void AccSRsh (int shCount)
6596 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6599 pic16_emitcode("mov","c,acc.7");
6600 pic16_emitcode("rrc","a");
6601 } else if(shCount == 2){
6602 pic16_emitcode("mov","c,acc.7");
6603 pic16_emitcode("rrc","a");
6604 pic16_emitcode("mov","c,acc.7");
6605 pic16_emitcode("rrc","a");
6607 tlbl = newiTempLabel(NULL);
6608 /* rotate right accumulator */
6609 AccRol(8 - shCount);
6610 /* and kill the higher order bits */
6611 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6612 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6613 pic16_emitcode("orl","a,#0x%02x",
6614 (unsigned char)~SRMask[shCount]);
6615 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6620 /*-----------------------------------------------------------------*/
6621 /* shiftR1Left2Result - shift right one byte from left to result */
6622 /*-----------------------------------------------------------------*/
6623 static void shiftR1Left2ResultSigned (operand *left, int offl,
6624 operand *result, int offr,
6629 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6631 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6635 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6637 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6639 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6640 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6646 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6648 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6650 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6651 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6653 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6654 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6660 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6662 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6663 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6666 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6667 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6668 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6670 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6671 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6673 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6677 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6678 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6679 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6680 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6681 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6685 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6687 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6688 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6690 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6691 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6692 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6693 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6694 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6699 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6700 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6701 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6702 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6703 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6704 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6706 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6707 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6708 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6709 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6710 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6716 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6717 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6718 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6719 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6721 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6722 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6723 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6731 /*-----------------------------------------------------------------*/
6732 /* shiftR1Left2Result - shift right one byte from left to result */
6733 /*-----------------------------------------------------------------*/
6734 static void shiftR1Left2Result (operand *left, int offl,
6735 operand *result, int offr,
6736 int shCount, int sign)
6740 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6742 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6744 /* Copy the msb into the carry if signed. */
6746 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6756 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6758 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6759 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6765 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6767 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6768 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6771 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6776 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6778 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6779 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6782 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6783 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6784 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6785 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6789 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6790 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6791 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6795 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6796 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6797 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6799 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6804 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6805 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6806 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6807 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6808 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6813 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6814 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6815 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6824 /*-----------------------------------------------------------------*/
6825 /* shiftL1Left2Result - shift left one byte from left to result */
6826 /*-----------------------------------------------------------------*/
6827 static void shiftL1Left2Result (operand *left, int offl,
6828 operand *result, int offr, int shCount)
6833 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6835 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6836 DEBUGpic16_emitcode ("; ***","same = %d",same);
6837 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6839 /* shift left accumulator */
6840 //AccLsh(shCount); // don't comment out just yet...
6841 // pic16_aopPut(AOP(result),"a",offr);
6845 /* Shift left 1 bit position */
6846 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6848 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6850 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6851 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6855 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6856 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6857 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6858 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6861 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6862 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6863 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6864 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6865 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6868 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6869 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6870 pic16_emitpcode(POC_MOVWF,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));
6876 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6879 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6880 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6881 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6882 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6883 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6886 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6887 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6888 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6892 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6897 /*-----------------------------------------------------------------*/
6898 /* movLeft2Result - move byte from left to result */
6899 /*-----------------------------------------------------------------*/
6900 static void movLeft2Result (operand *left, int offl,
6901 operand *result, int offr)
6904 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6905 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6906 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6908 if (*l == '@' && (IS_AOP_PREG(result))) {
6909 pic16_emitcode("mov","a,%s",l);
6910 pic16_aopPut(AOP(result),"a",offr);
6912 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6913 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6918 /*-----------------------------------------------------------------*/
6919 /* shiftL2Left2Result - shift left two bytes from left to result */
6920 /*-----------------------------------------------------------------*/
6921 static void shiftL2Left2Result (operand *left, int offl,
6922 operand *result, int offr, int shCount)
6924 int same = pic16_sameRegs(AOP(result), AOP(left));
6927 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
6929 if (same && (offl != offr)) { // shift bytes
6932 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
6933 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
6935 } else { // just treat as different later on
6948 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6949 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6950 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6954 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6955 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6961 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6962 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6963 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6964 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6965 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6966 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6967 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6969 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6970 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6974 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6975 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6976 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6977 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6978 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6979 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6980 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6981 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6982 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6983 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6986 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6987 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6988 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6989 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6990 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7000 /* note, use a mov/add for the shift since the mov has a
7001 chance of getting optimized out */
7002 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7003 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7004 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7005 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7006 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7010 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7011 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7017 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7018 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7019 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7020 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7021 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7022 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7023 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7024 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7028 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7029 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7033 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7034 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7035 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7036 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7038 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7039 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7040 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7041 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7042 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7043 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7044 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7045 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7048 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7049 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7050 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7051 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7052 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7057 /*-----------------------------------------------------------------*/
7058 /* shiftR2Left2Result - shift right two bytes from left to result */
7059 /*-----------------------------------------------------------------*/
7060 static void shiftR2Left2Result (operand *left, int offl,
7061 operand *result, int offr,
7062 int shCount, int sign)
7064 int same = pic16_sameRegs(AOP(result), AOP(left));
7066 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7068 if (same && (offl != offr)) { // shift right bytes
7071 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7072 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7074 } else { // just treat as different later on
7086 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7091 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7092 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7094 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7095 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7096 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7097 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7102 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7105 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7106 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7113 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7114 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7115 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7117 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7118 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7119 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7120 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7122 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7123 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7124 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7126 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7127 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7128 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7129 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7130 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7134 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7135 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7139 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7140 pic16_emitpcode(POC_BTFSC,
7141 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7142 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7150 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7151 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7153 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7154 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7155 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7156 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7158 pic16_emitpcode(POC_BTFSC,
7159 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7160 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7162 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7163 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7164 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7165 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7167 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7168 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7169 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7170 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7171 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7172 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7173 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7174 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7176 pic16_emitpcode(POC_BTFSC,
7177 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7178 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7180 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7181 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7188 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7189 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7190 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7191 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7194 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7196 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7201 /*-----------------------------------------------------------------*/
7202 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7203 /*-----------------------------------------------------------------*/
7204 static void shiftLLeftOrResult (operand *left, int offl,
7205 operand *result, int offr, int shCount)
7207 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7209 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7210 /* shift left accumulator */
7212 /* or with result */
7213 /* back to result */
7214 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7217 /*-----------------------------------------------------------------*/
7218 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7219 /*-----------------------------------------------------------------*/
7220 static void shiftRLeftOrResult (operand *left, int offl,
7221 operand *result, int offr, int shCount)
7223 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7225 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7226 /* shift right accumulator */
7228 /* or with result */
7229 /* back to result */
7230 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7233 /*-----------------------------------------------------------------*/
7234 /* genlshOne - left shift a one byte quantity by known count */
7235 /*-----------------------------------------------------------------*/
7236 static void genlshOne (operand *result, operand *left, int shCount)
7238 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7239 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7242 /*-----------------------------------------------------------------*/
7243 /* genlshTwo - left shift two bytes by known amount != 0 */
7244 /*-----------------------------------------------------------------*/
7245 static void genlshTwo (operand *result,operand *left, int shCount)
7249 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7250 size = pic16_getDataSize(result);
7252 /* if shCount >= 8 */
7258 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7260 movLeft2Result(left, LSB, result, MSB16);
7262 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7265 /* 1 <= shCount <= 7 */
7268 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7270 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7274 /*-----------------------------------------------------------------*/
7275 /* shiftLLong - shift left one long from left to result */
7276 /* offr = LSB or MSB16 */
7277 /*-----------------------------------------------------------------*/
7278 static void shiftLLong (operand *left, operand *result, int offr )
7280 int size = AOP_SIZE(result);
7281 int same = pic16_sameRegs(AOP(left),AOP(result));
7284 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7286 if (same && (offr == MSB16)) { //shift one byte
7287 for(i=size-1;i>=MSB16;i--) {
7288 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7289 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7292 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7295 if (size >= LSB+offr ){
7297 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7299 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7300 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7304 if(size >= MSB16+offr){
7306 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7308 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7309 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7313 if(size >= MSB24+offr){
7315 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7317 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7318 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7322 if(size > MSB32+offr){
7324 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7326 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7327 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7331 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7335 /*-----------------------------------------------------------------*/
7336 /* genlshFour - shift four byte by a known amount != 0 */
7337 /*-----------------------------------------------------------------*/
7338 static void genlshFour (operand *result, operand *left, int shCount)
7342 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7343 size = AOP_SIZE(result);
7345 /* if shifting more that 3 bytes */
7346 if (shCount >= 24 ) {
7349 /* lowest order of left goes to the highest
7350 order of the destination */
7351 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7353 movLeft2Result(left, LSB, result, MSB32);
7355 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7356 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7357 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7362 /* more than two bytes */
7363 else if ( shCount >= 16 ) {
7364 /* lower order two bytes goes to higher order two bytes */
7366 /* if some more remaining */
7368 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7370 movLeft2Result(left, MSB16, result, MSB32);
7371 movLeft2Result(left, LSB, result, MSB24);
7373 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7374 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7378 /* if more than 1 byte */
7379 else if ( shCount >= 8 ) {
7380 /* lower order three bytes goes to higher order three bytes */
7384 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7386 movLeft2Result(left, LSB, result, MSB16);
7388 else{ /* size = 4 */
7390 movLeft2Result(left, MSB24, result, MSB32);
7391 movLeft2Result(left, MSB16, result, MSB24);
7392 movLeft2Result(left, LSB, result, MSB16);
7393 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7395 else if(shCount == 1)
7396 shiftLLong(left, result, MSB16);
7398 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7399 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7400 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7401 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7406 /* 1 <= shCount <= 7 */
7407 else if(shCount <= 3)
7409 shiftLLong(left, result, LSB);
7410 while(--shCount >= 1)
7411 shiftLLong(result, result, LSB);
7413 /* 3 <= shCount <= 7, optimize */
7415 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7416 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7417 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7421 /*-----------------------------------------------------------------*/
7422 /* genLeftShiftLiteral - left shifting by known count */
7423 /*-----------------------------------------------------------------*/
7424 static void genLeftShiftLiteral (operand *left,
7429 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7432 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7433 pic16_freeAsmop(right,NULL,ic,TRUE);
7435 pic16_aopOp(left,ic,FALSE);
7436 pic16_aopOp(result,ic,FALSE);
7438 size = getSize(operandType(result));
7441 pic16_emitcode("; shift left ","result %d, left %d",size,
7445 /* I suppose that the left size >= result size */
7448 movLeft2Result(left, size, result, size);
7452 else if(shCount >= (size * 8))
7454 pic16_aopPut(AOP(result),zero,size);
7458 genlshOne (result,left,shCount);
7463 genlshTwo (result,left,shCount);
7467 genlshFour (result,left,shCount);
7471 pic16_freeAsmop(left,NULL,ic,TRUE);
7472 pic16_freeAsmop(result,NULL,ic,TRUE);
7475 /*-----------------------------------------------------------------*
7476 * genMultiAsm - repeat assembly instruction for size of register.
7477 * if endian == 1, then the high byte (i.e base address + size of
7478 * register) is used first else the low byte is used first;
7479 *-----------------------------------------------------------------*/
7480 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7485 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7498 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7503 /*-----------------------------------------------------------------*/
7504 /* genLeftShift - generates code for left shifting */
7505 /*-----------------------------------------------------------------*/
7506 static void genLeftShift (iCode *ic)
7508 operand *left,*right, *result;
7511 symbol *tlbl , *tlbl1;
7514 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7516 right = IC_RIGHT(ic);
7518 result = IC_RESULT(ic);
7520 pic16_aopOp(right,ic,FALSE);
7522 /* if the shift count is known then do it
7523 as efficiently as possible */
7524 if (AOP_TYPE(right) == AOP_LIT) {
7525 genLeftShiftLiteral (left,right,result,ic);
7529 /* shift count is unknown then we have to form
7530 a loop get the loop count in B : Note: we take
7531 only the lower order byte since shifting
7532 more that 32 bits make no sense anyway, ( the
7533 largest size of an object can be only 32 bits ) */
7536 pic16_aopOp(left,ic,FALSE);
7537 pic16_aopOp(result,ic,FALSE);
7539 /* now move the left to the result if they are not the
7541 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7542 AOP_SIZE(result) > 1) {
7544 size = AOP_SIZE(result);
7547 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7548 if (*l == '@' && (IS_AOP_PREG(result))) {
7550 pic16_emitcode("mov","a,%s",l);
7551 pic16_aopPut(AOP(result),"a",offset);
7553 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7554 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7555 //pic16_aopPut(AOP(result),l,offset);
7561 size = AOP_SIZE(result);
7563 /* if it is only one byte then */
7565 if(optimized_for_speed) {
7566 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7567 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7568 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7569 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7570 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7571 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7572 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7573 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7574 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7575 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7576 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7577 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7580 tlbl = newiTempLabel(NULL);
7581 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7582 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7583 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7586 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7587 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7588 pic16_emitpLabel(tlbl->key);
7589 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7590 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7592 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7597 if (pic16_sameRegs(AOP(left),AOP(result))) {
7599 tlbl = newiTempLabel(NULL);
7600 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7601 genMultiAsm(POC_RRCF, result, size,1);
7602 pic16_emitpLabel(tlbl->key);
7603 genMultiAsm(POC_RLCF, result, size,0);
7604 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7606 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7610 //tlbl = newiTempLabel(NULL);
7612 //tlbl1 = newiTempLabel(NULL);
7614 //reAdjustPreg(AOP(result));
7616 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7617 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7618 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7620 //pic16_emitcode("add","a,acc");
7621 //pic16_aopPut(AOP(result),"a",offset++);
7623 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7625 // pic16_emitcode("rlc","a");
7626 // pic16_aopPut(AOP(result),"a",offset++);
7628 //reAdjustPreg(AOP(result));
7630 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7631 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7634 tlbl = newiTempLabel(NULL);
7635 tlbl1= newiTempLabel(NULL);
7637 size = AOP_SIZE(result);
7640 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7642 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7644 /* offset should be 0, 1 or 3 */
7646 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
7648 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7650 pic16_emitpcode(POC_MOVWF, pctemp);
7653 pic16_emitpLabel(tlbl->key);
7656 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7658 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7660 pic16_emitpcode(POC_DECFSZ, pctemp);
7661 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7662 pic16_emitpLabel(tlbl1->key);
7664 pic16_popReleaseTempReg(pctemp);
7668 pic16_freeAsmop (right,NULL,ic,TRUE);
7669 pic16_freeAsmop(left,NULL,ic,TRUE);
7670 pic16_freeAsmop(result,NULL,ic,TRUE);
7673 /*-----------------------------------------------------------------*/
7674 /* genrshOne - right shift a one byte quantity by known count */
7675 /*-----------------------------------------------------------------*/
7676 static void genrshOne (operand *result, operand *left,
7677 int shCount, int sign)
7679 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7680 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7683 /*-----------------------------------------------------------------*/
7684 /* genrshTwo - right shift two bytes by known amount != 0 */
7685 /*-----------------------------------------------------------------*/
7686 static void genrshTwo (operand *result,operand *left,
7687 int shCount, int sign)
7689 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7690 /* if shCount >= 8 */
7694 shiftR1Left2Result(left, MSB16, result, LSB,
7697 movLeft2Result(left, MSB16, result, LSB);
7699 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7702 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7703 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7707 /* 1 <= shCount <= 7 */
7709 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7712 /*-----------------------------------------------------------------*/
7713 /* shiftRLong - shift right one long from left to result */
7714 /* offl = LSB or MSB16 */
7715 /*-----------------------------------------------------------------*/
7716 static void shiftRLong (operand *left, int offl,
7717 operand *result, int sign)
7719 int size = AOP_SIZE(result);
7720 int same = pic16_sameRegs(AOP(left),AOP(result));
7722 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7724 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
7726 if (same && (offl == MSB16)) { //shift one byte right
7727 for(i=MSB16;i<size;i++) {
7728 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
7729 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
7734 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
7740 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
7742 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
7743 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
7747 /* add sign of "a" */
7748 pic16_addSign(result, MSB32, sign);
7752 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
7754 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
7755 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
7759 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
7761 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
7762 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
7766 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
7769 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
7770 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
7775 /*-----------------------------------------------------------------*/
7776 /* genrshFour - shift four byte by a known amount != 0 */
7777 /*-----------------------------------------------------------------*/
7778 static void genrshFour (operand *result, operand *left,
7779 int shCount, int sign)
7781 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7782 /* if shifting more that 3 bytes */
7783 if(shCount >= 24 ) {
7786 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7788 movLeft2Result(left, MSB32, result, LSB);
7790 pic16_addSign(result, MSB16, sign);
7792 else if(shCount >= 16){
7795 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7797 movLeft2Result(left, MSB24, result, LSB);
7798 movLeft2Result(left, MSB32, result, MSB16);
7800 pic16_addSign(result, MSB24, sign);
7802 else if(shCount >= 8){
7805 shiftRLong(left, MSB16, result, sign);
7806 else if(shCount == 0){
7807 movLeft2Result(left, MSB16, result, LSB);
7808 movLeft2Result(left, MSB24, result, MSB16);
7809 movLeft2Result(left, MSB32, result, MSB24);
7810 pic16_addSign(result, MSB32, sign);
7812 else{ //shcount >= 2
7813 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7814 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7815 /* the last shift is signed */
7816 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7817 pic16_addSign(result, MSB32, sign);
7820 else{ /* 1 <= shCount <= 7 */
7822 shiftRLong(left, LSB, result, sign);
7824 shiftRLong(result, LSB, result, sign);
7827 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7828 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7829 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7834 /*-----------------------------------------------------------------*/
7835 /* genRightShiftLiteral - right shifting by known count */
7836 /*-----------------------------------------------------------------*/
7837 static void genRightShiftLiteral (operand *left,
7843 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7846 pic16_freeAsmop(right,NULL,ic,TRUE);
7848 pic16_aopOp(left,ic,FALSE);
7849 pic16_aopOp(result,ic,FALSE);
7851 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
7854 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7858 lsize = pic16_getDataSize(left);
7859 res_size = pic16_getDataSize(result);
7860 /* test the LEFT size !!! */
7862 /* I suppose that the left size >= result size */
7865 movLeft2Result(left, lsize, result, res_size);
7868 else if(shCount >= (lsize * 8)){
7871 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7873 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7874 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7879 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7880 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7881 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7883 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7888 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7895 genrshOne (result,left,shCount,sign);
7899 genrshTwo (result,left,shCount,sign);
7903 genrshFour (result,left,shCount,sign);
7911 pic16_freeAsmop(left,NULL,ic,TRUE);
7912 pic16_freeAsmop(result,NULL,ic,TRUE);
7915 /*-----------------------------------------------------------------*/
7916 /* genSignedRightShift - right shift of signed number */
7917 /*-----------------------------------------------------------------*/
7918 static void genSignedRightShift (iCode *ic)
7920 operand *right, *left, *result;
7923 symbol *tlbl, *tlbl1 ;
7926 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7928 /* we do it the hard way put the shift count in b
7929 and loop thru preserving the sign */
7930 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7932 right = IC_RIGHT(ic);
7934 result = IC_RESULT(ic);
7936 pic16_aopOp(right,ic,FALSE);
7937 pic16_aopOp(left,ic,FALSE);
7938 pic16_aopOp(result,ic,FALSE);
7941 if ( AOP_TYPE(right) == AOP_LIT) {
7942 genRightShiftLiteral (left,right,result,ic,1);
7945 /* shift count is unknown then we have to form
7946 a loop get the loop count in B : Note: we take
7947 only the lower order byte since shifting
7948 more that 32 bits make no sense anyway, ( the
7949 largest size of an object can be only 32 bits ) */
7951 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7952 //pic16_emitcode("inc","b");
7953 //pic16_freeAsmop (right,NULL,ic,TRUE);
7954 //pic16_aopOp(left,ic,FALSE);
7955 //pic16_aopOp(result,ic,FALSE);
7957 /* now move the left to the result if they are not the
7959 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7960 AOP_SIZE(result) > 1) {
7962 size = AOP_SIZE(result);
7966 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7967 if (*l == '@' && IS_AOP_PREG(result)) {
7969 pic16_emitcode("mov","a,%s",l);
7970 pic16_aopPut(AOP(result),"a",offset);
7972 pic16_aopPut(AOP(result),l,offset);
7974 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7975 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7981 /* mov the highest order bit to OVR */
7982 tlbl = newiTempLabel(NULL);
7983 tlbl1= newiTempLabel(NULL);
7985 size = AOP_SIZE(result);
7988 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7990 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7992 /* offset should be 0, 1 or 3 */
7993 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7995 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7997 pic16_emitpcode(POC_MOVWF, pctemp);
8000 pic16_emitpLabel(tlbl->key);
8002 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8003 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8006 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8009 pic16_emitpcode(POC_DECFSZ, pctemp);
8010 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8011 pic16_emitpLabel(tlbl1->key);
8013 pic16_popReleaseTempReg(pctemp);
8015 size = AOP_SIZE(result);
8017 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8018 pic16_emitcode("rlc","a");
8019 pic16_emitcode("mov","ov,c");
8020 /* if it is only one byte then */
8022 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8024 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8025 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8026 pic16_emitcode("mov","c,ov");
8027 pic16_emitcode("rrc","a");
8028 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8029 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8030 pic16_aopPut(AOP(result),"a",0);
8034 reAdjustPreg(AOP(result));
8035 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8036 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8037 pic16_emitcode("mov","c,ov");
8039 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8041 pic16_emitcode("rrc","a");
8042 pic16_aopPut(AOP(result),"a",offset--);
8044 reAdjustPreg(AOP(result));
8045 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8046 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8051 pic16_freeAsmop(left,NULL,ic,TRUE);
8052 pic16_freeAsmop(result,NULL,ic,TRUE);
8053 pic16_freeAsmop(right,NULL,ic,TRUE);
8056 /*-----------------------------------------------------------------*/
8057 /* genRightShift - generate code for right shifting */
8058 /*-----------------------------------------------------------------*/
8059 static void genRightShift (iCode *ic)
8061 operand *right, *left, *result;
8065 symbol *tlbl, *tlbl1 ;
8067 /* if signed then we do it the hard way preserve the
8068 sign bit moving it inwards */
8069 letype = getSpec(operandType(IC_LEFT(ic)));
8070 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8072 if (!SPEC_USIGN(letype)) {
8073 genSignedRightShift (ic);
8077 /* signed & unsigned types are treated the same : i.e. the
8078 signed is NOT propagated inwards : quoting from the
8079 ANSI - standard : "for E1 >> E2, is equivalent to division
8080 by 2**E2 if unsigned or if it has a non-negative value,
8081 otherwise the result is implementation defined ", MY definition
8082 is that the sign does not get propagated */
8084 right = IC_RIGHT(ic);
8086 result = IC_RESULT(ic);
8088 pic16_aopOp(right,ic,FALSE);
8090 /* if the shift count is known then do it
8091 as efficiently as possible */
8092 if (AOP_TYPE(right) == AOP_LIT) {
8093 genRightShiftLiteral (left,right,result,ic, 0);
8097 /* shift count is unknown then we have to form
8098 a loop get the loop count in B : Note: we take
8099 only the lower order byte since shifting
8100 more that 32 bits make no sense anyway, ( the
8101 largest size of an object can be only 32 bits ) */
8103 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8104 pic16_emitcode("inc","b");
8105 pic16_aopOp(left,ic,FALSE);
8106 pic16_aopOp(result,ic,FALSE);
8108 /* now move the left to the result if they are not the
8110 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8111 AOP_SIZE(result) > 1) {
8113 size = AOP_SIZE(result);
8116 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8117 if (*l == '@' && IS_AOP_PREG(result)) {
8119 pic16_emitcode("mov","a,%s",l);
8120 pic16_aopPut(AOP(result),"a",offset);
8122 pic16_aopPut(AOP(result),l,offset);
8127 tlbl = newiTempLabel(NULL);
8128 tlbl1= newiTempLabel(NULL);
8129 size = AOP_SIZE(result);
8132 /* if it is only one byte then */
8135 tlbl = newiTempLabel(NULL);
8136 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8137 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8138 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8141 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8142 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8143 pic16_emitpLabel(tlbl->key);
8144 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8145 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8147 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8152 reAdjustPreg(AOP(result));
8153 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8154 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8157 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8159 pic16_emitcode("rrc","a");
8160 pic16_aopPut(AOP(result),"a",offset--);
8162 reAdjustPreg(AOP(result));
8164 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8165 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8168 pic16_freeAsmop(left,NULL,ic,TRUE);
8169 pic16_freeAsmop (right,NULL,ic,TRUE);
8170 pic16_freeAsmop(result,NULL,ic,TRUE);
8173 /*-----------------------------------------------------------------*/
8174 /* genUnpackBits - generates code for unpacking bits */
8175 /*-----------------------------------------------------------------*/
8176 static void genUnpackBits (operand *result, char *rname, int ptype)
8183 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8184 etype = getSpec(operandType(result));
8186 /* read the first byte */
8191 pic16_emitcode("mov","a,@%s",rname);
8195 pic16_emitcode("movx","a,@%s",rname);
8199 pic16_emitcode("movx","a,@dptr");
8203 pic16_emitcode("clr","a");
8204 pic16_emitcode("movc","a","@a+dptr");
8208 pic16_emitcode("lcall","__gptrget");
8212 /* if we have bitdisplacement then it fits */
8213 /* into this byte completely or if length is */
8214 /* less than a byte */
8215 if ((shCnt = SPEC_BSTR(etype)) ||
8216 (SPEC_BLEN(etype) <= 8)) {
8218 /* shift right acc */
8221 pic16_emitcode("anl","a,#0x%02x",
8222 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8223 pic16_aopPut(AOP(result),"a",offset);
8227 /* bit field did not fit in a byte */
8228 rlen = SPEC_BLEN(etype) - 8;
8229 pic16_aopPut(AOP(result),"a",offset++);
8236 pic16_emitcode("inc","%s",rname);
8237 pic16_emitcode("mov","a,@%s",rname);
8241 pic16_emitcode("inc","%s",rname);
8242 pic16_emitcode("movx","a,@%s",rname);
8246 pic16_emitcode("inc","dptr");
8247 pic16_emitcode("movx","a,@dptr");
8251 pic16_emitcode("clr","a");
8252 pic16_emitcode("inc","dptr");
8253 pic16_emitcode("movc","a","@a+dptr");
8257 pic16_emitcode("inc","dptr");
8258 pic16_emitcode("lcall","__gptrget");
8263 /* if we are done */
8267 pic16_aopPut(AOP(result),"a",offset++);
8272 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8273 pic16_aopPut(AOP(result),"a",offset);
8280 /*-----------------------------------------------------------------*/
8281 /* genDataPointerGet - generates code when ptr offset is known */
8282 /*-----------------------------------------------------------------*/
8283 static void genDataPointerGet (operand *left,
8287 int size , offset = 0;
8290 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8293 /* optimization - most of the time, left and result are the same
8294 * address, but different types. for the pic code, we could omit
8298 pic16_aopOp(result,ic,TRUE);
8300 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8302 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8304 size = AOP_SIZE(result);
8307 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8311 pic16_freeAsmop(left,NULL,ic,TRUE);
8312 pic16_freeAsmop(result,NULL,ic,TRUE);
8315 /*-----------------------------------------------------------------*/
8316 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8317 /*-----------------------------------------------------------------*/
8318 static void genNearPointerGet (operand *left,
8323 //regs *preg = NULL ;
8325 sym_link *rtype, *retype;
8326 sym_link *ltype = operandType(left);
8329 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8331 rtype = operandType(result);
8332 retype= getSpec(rtype);
8334 pic16_aopOp(left,ic,FALSE);
8336 /* if left is rematerialisable and
8337 result is not bit variable type and
8338 the left is pointer to data space i.e
8339 lower 128 bytes of space */
8340 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8341 !IS_BITVAR(retype) &&
8342 DCL_TYPE(ltype) == POINTER) {
8343 //genDataPointerGet (left,result,ic);
8347 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8349 /* if the value is already in a pointer register
8350 then don't need anything more */
8351 if (!AOP_INPREG(AOP(left))) {
8352 /* otherwise get a free pointer register */
8353 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8356 preg = getFreePtr(ic,&aop,FALSE);
8357 pic16_emitcode("mov","%s,%s",
8359 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8360 rname = preg->name ;
8364 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8366 pic16_aopOp (result,ic,FALSE);
8368 /* if bitfield then unpack the bits */
8369 if (IS_BITVAR(retype))
8370 genUnpackBits (result,rname,POINTER);
8372 /* we have can just get the values */
8373 int size = AOP_SIZE(result);
8376 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8378 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8379 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8381 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8382 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8384 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8388 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8390 pic16_emitcode("mov","a,@%s",rname);
8391 pic16_aopPut(AOP(result),"a",offset);
8393 sprintf(buffer,"@%s",rname);
8394 pic16_aopPut(AOP(result),buffer,offset);
8398 pic16_emitcode("inc","%s",rname);
8403 /* now some housekeeping stuff */
8405 /* we had to allocate for this iCode */
8406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8407 pic16_freeAsmop(NULL,aop,ic,TRUE);
8409 /* we did not allocate which means left
8410 already in a pointer register, then
8411 if size > 0 && this could be used again
8412 we have to point it back to where it
8414 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8415 if (AOP_SIZE(result) > 1 &&
8416 !OP_SYMBOL(left)->remat &&
8417 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8419 int size = AOP_SIZE(result) - 1;
8421 pic16_emitcode("dec","%s",rname);
8426 pic16_freeAsmop(left,NULL,ic,TRUE);
8427 pic16_freeAsmop(result,NULL,ic,TRUE);
8431 /*-----------------------------------------------------------------*/
8432 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8433 /*-----------------------------------------------------------------*/
8434 static void genPagedPointerGet (operand *left,
8441 sym_link *rtype, *retype;
8443 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8445 rtype = operandType(result);
8446 retype= getSpec(rtype);
8448 pic16_aopOp(left,ic,FALSE);
8450 /* if the value is already in a pointer register
8451 then don't need anything more */
8452 if (!AOP_INPREG(AOP(left))) {
8453 /* otherwise get a free pointer register */
8455 preg = getFreePtr(ic,&aop,FALSE);
8456 pic16_emitcode("mov","%s,%s",
8458 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8459 rname = preg->name ;
8461 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8463 pic16_freeAsmop(left,NULL,ic,TRUE);
8464 pic16_aopOp (result,ic,FALSE);
8466 /* if bitfield then unpack the bits */
8467 if (IS_BITVAR(retype))
8468 genUnpackBits (result,rname,PPOINTER);
8470 /* we have can just get the values */
8471 int size = AOP_SIZE(result);
8476 pic16_emitcode("movx","a,@%s",rname);
8477 pic16_aopPut(AOP(result),"a",offset);
8482 pic16_emitcode("inc","%s",rname);
8486 /* now some housekeeping stuff */
8488 /* we had to allocate for this iCode */
8489 pic16_freeAsmop(NULL,aop,ic,TRUE);
8491 /* we did not allocate which means left
8492 already in a pointer register, then
8493 if size > 0 && this could be used again
8494 we have to point it back to where it
8496 if (AOP_SIZE(result) > 1 &&
8497 !OP_SYMBOL(left)->remat &&
8498 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8500 int size = AOP_SIZE(result) - 1;
8502 pic16_emitcode("dec","%s",rname);
8507 pic16_freeAsmop(result,NULL,ic,TRUE);
8512 /*-----------------------------------------------------------------*/
8513 /* genFarPointerGet - gget value from far space */
8514 /*-----------------------------------------------------------------*/
8515 static void genFarPointerGet (operand *left,
8516 operand *result, iCode *ic)
8519 sym_link *retype = getSpec(operandType(result));
8521 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8523 pic16_aopOp(left,ic,FALSE);
8525 /* if the operand is already in dptr
8526 then we do nothing else we move the value to dptr */
8527 if (AOP_TYPE(left) != AOP_STR) {
8528 /* if this is remateriazable */
8529 if (AOP_TYPE(left) == AOP_IMMD)
8530 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8531 else { /* we need to get it byte by byte */
8532 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8533 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8534 if (options.model == MODEL_FLAT24)
8536 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8540 /* so dptr know contains the address */
8541 pic16_freeAsmop(left,NULL,ic,TRUE);
8542 pic16_aopOp(result,ic,FALSE);
8544 /* if bit then unpack */
8545 if (IS_BITVAR(retype))
8546 genUnpackBits(result,"dptr",FPOINTER);
8548 size = AOP_SIZE(result);
8552 pic16_emitcode("movx","a,@dptr");
8553 pic16_aopPut(AOP(result),"a",offset++);
8555 pic16_emitcode("inc","dptr");
8559 pic16_freeAsmop(result,NULL,ic,TRUE);
8562 /*-----------------------------------------------------------------*/
8563 /* genCodePointerGet - get value from code space */
8564 /*-----------------------------------------------------------------*/
8565 static void genCodePointerGet (operand *left,
8566 operand *result, iCode *ic)
8569 sym_link *retype = getSpec(operandType(result));
8571 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8573 pic16_aopOp(left,ic,FALSE);
8575 /* if the operand is already in dptr
8576 then we do nothing else we move the value to dptr */
8577 if (AOP_TYPE(left) != AOP_STR) {
8578 /* if this is remateriazable */
8579 if (AOP_TYPE(left) == AOP_IMMD)
8580 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8581 else { /* we need to get it byte by byte */
8582 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8583 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8584 if (options.model == MODEL_FLAT24)
8586 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8590 /* so dptr know contains the address */
8591 pic16_freeAsmop(left,NULL,ic,TRUE);
8592 pic16_aopOp(result,ic,FALSE);
8594 /* if bit then unpack */
8595 if (IS_BITVAR(retype))
8596 genUnpackBits(result,"dptr",CPOINTER);
8598 size = AOP_SIZE(result);
8602 pic16_emitcode("clr","a");
8603 pic16_emitcode("movc","a,@a+dptr");
8604 pic16_aopPut(AOP(result),"a",offset++);
8606 pic16_emitcode("inc","dptr");
8610 pic16_freeAsmop(result,NULL,ic,TRUE);
8613 /*-----------------------------------------------------------------*/
8614 /* genGenPointerGet - gget value from generic pointer space */
8615 /*-----------------------------------------------------------------*/
8616 static void genGenPointerGet (operand *left,
8617 operand *result, iCode *ic)
8620 sym_link *retype = getSpec(operandType(result));
8622 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8623 pic16_aopOp(left,ic,FALSE);
8624 pic16_aopOp(result,ic,FALSE);
8627 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8629 /* if the operand is already in dptr
8630 then we do nothing else we move the value to dptr */
8631 // if (AOP_TYPE(left) != AOP_STR) {
8632 /* if this is remateriazable */
8633 if (AOP_TYPE(left) == AOP_IMMD) {
8634 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8635 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8637 else { /* we need to get it byte by byte */
8639 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8640 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8642 size = AOP_SIZE(result);
8646 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8647 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8649 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8654 /* so dptr know contains the address */
8656 /* if bit then unpack */
8657 if (IS_BITVAR(retype))
8658 genUnpackBits(result,"BAD",GPOINTER);
8661 pic16_freeAsmop(left,NULL,ic,TRUE);
8662 pic16_freeAsmop(result,NULL,ic,TRUE);
8666 /*-----------------------------------------------------------------*/
8667 /* genConstPointerGet - get value from const generic pointer space */
8668 /*-----------------------------------------------------------------*/
8669 static void genConstPointerGet (operand *left,
8670 operand *result, iCode *ic)
8672 //sym_link *retype = getSpec(operandType(result));
8673 symbol *albl = newiTempLabel(NULL);
8674 symbol *blbl = newiTempLabel(NULL);
8677 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8678 pic16_aopOp(left,ic,FALSE);
8679 pic16_aopOp(result,ic,FALSE);
8682 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8684 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8686 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8687 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8688 pic16_emitpLabel(albl->key);
8690 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8692 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8693 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8694 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8695 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8696 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8698 pic16_emitpLabel(blbl->key);
8700 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8703 pic16_freeAsmop(left,NULL,ic,TRUE);
8704 pic16_freeAsmop(result,NULL,ic,TRUE);
8707 /*-----------------------------------------------------------------*/
8708 /* genPointerGet - generate code for pointer get */
8709 /*-----------------------------------------------------------------*/
8710 static void genPointerGet (iCode *ic)
8712 operand *left, *result ;
8713 sym_link *type, *etype;
8716 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8719 result = IC_RESULT(ic) ;
8721 /* depending on the type of pointer we need to
8722 move it to the correct pointer register */
8723 type = operandType(left);
8724 etype = getSpec(type);
8727 if (IS_PTR_CONST(type))
8729 if (IS_CODEPTR(type))
8731 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8733 /* if left is of type of pointer then it is simple */
8734 if (IS_PTR(type) && !IS_FUNC(type->next))
8735 p_type = DCL_TYPE(type);
8737 /* we have to go by the storage class */
8738 p_type = PTR_TYPE(SPEC_OCLS(etype));
8740 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8742 if (SPEC_OCLS(etype)->codesp ) {
8743 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8744 //p_type = CPOINTER ;
8747 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8748 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8749 /*p_type = FPOINTER ;*/
8751 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8752 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8753 /* p_type = PPOINTER; */
8755 if (SPEC_OCLS(etype) == idata )
8756 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8757 /* p_type = IPOINTER; */
8759 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8760 /* p_type = POINTER ; */
8763 /* now that we have the pointer type we assign
8764 the pointer values */
8769 genNearPointerGet (left,result,ic);
8773 genPagedPointerGet(left,result,ic);
8777 genFarPointerGet (left,result,ic);
8781 genConstPointerGet (left,result,ic);
8782 //pic16_emitcodePointerGet (left,result,ic);
8787 if (IS_PTR_CONST(type))
8788 genConstPointerGet (left,result,ic);
8791 genGenPointerGet (left,result,ic);
8797 /*-----------------------------------------------------------------*/
8798 /* genPackBits - generates code for packed bit storage */
8799 /*-----------------------------------------------------------------*/
8800 static void genPackBits (sym_link *etype ,
8802 char *rname, int p_type)
8810 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8811 blen = SPEC_BLEN(etype);
8812 bstr = SPEC_BSTR(etype);
8814 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8817 /* if the bit lenth is less than or */
8818 /* it exactly fits a byte then */
8819 if (SPEC_BLEN(etype) <= 8 ) {
8820 shCount = SPEC_BSTR(etype) ;
8822 /* shift left acc */
8825 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8830 pic16_emitcode ("mov","b,a");
8831 pic16_emitcode("mov","a,@%s",rname);
8835 pic16_emitcode ("mov","b,a");
8836 pic16_emitcode("movx","a,@dptr");
8840 pic16_emitcode ("push","b");
8841 pic16_emitcode ("push","acc");
8842 pic16_emitcode ("lcall","__gptrget");
8843 pic16_emitcode ("pop","b");
8847 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8848 ((unsigned char)(0xFF << (blen+bstr)) |
8849 (unsigned char)(0xFF >> (8-bstr)) ) );
8850 pic16_emitcode ("orl","a,b");
8851 if (p_type == GPOINTER)
8852 pic16_emitcode("pop","b");
8858 pic16_emitcode("mov","@%s,a",rname);
8862 pic16_emitcode("movx","@dptr,a");
8866 DEBUGpic16_emitcode(";lcall","__gptrput");
8871 if ( SPEC_BLEN(etype) <= 8 )
8874 pic16_emitcode("inc","%s",rname);
8875 rLen = SPEC_BLEN(etype) ;
8877 /* now generate for lengths greater than one byte */
8880 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8890 pic16_emitcode("mov","@%s,a",rname);
8892 pic16_emitcode("mov","@%s,%s",rname,l);
8897 pic16_emitcode("movx","@dptr,a");
8902 DEBUGpic16_emitcode(";lcall","__gptrput");
8905 pic16_emitcode ("inc","%s",rname);
8910 /* last last was not complete */
8912 /* save the byte & read byte */
8915 pic16_emitcode ("mov","b,a");
8916 pic16_emitcode("mov","a,@%s",rname);
8920 pic16_emitcode ("mov","b,a");
8921 pic16_emitcode("movx","a,@dptr");
8925 pic16_emitcode ("push","b");
8926 pic16_emitcode ("push","acc");
8927 pic16_emitcode ("lcall","__gptrget");
8928 pic16_emitcode ("pop","b");
8932 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8933 pic16_emitcode ("orl","a,b");
8936 if (p_type == GPOINTER)
8937 pic16_emitcode("pop","b");
8942 pic16_emitcode("mov","@%s,a",rname);
8946 pic16_emitcode("movx","@dptr,a");
8950 DEBUGpic16_emitcode(";lcall","__gptrput");
8954 /*-----------------------------------------------------------------*/
8955 /* genDataPointerSet - remat pointer to data space */
8956 /*-----------------------------------------------------------------*/
8957 static void genDataPointerSet(operand *right,
8961 int size, offset = 0 ;
8962 char *l, buffer[256];
8964 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8965 pic16_aopOp(right,ic,FALSE);
8967 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8968 size = AOP_SIZE(right);
8970 if ( AOP_TYPE(result) == AOP_PCODE) {
8971 fprintf(stderr,"genDataPointerSet %s, %d\n",
8972 AOP(result)->aopu.pcop->name,
8973 PCOI(AOP(result)->aopu.pcop)->offset);
8977 // tsd, was l+1 - the underline `_' prefix was being stripped
8980 sprintf(buffer,"(%s + %d)",l,offset);
8981 fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer);
8983 sprintf(buffer,"%s",l);
8985 if (AOP_TYPE(right) == AOP_LIT) {
8986 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8987 lit = lit >> (8*offset);
8989 pic16_emitcode("movlw","%d",lit);
8990 pic16_emitcode("movwf","%s",buffer);
8992 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8993 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
8994 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8997 pic16_emitcode("clrf","%s",buffer);
8998 //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer));
8999 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9002 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
9003 pic16_emitcode("movwf","%s",buffer);
9005 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9006 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
9007 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9014 pic16_freeAsmop(right,NULL,ic,TRUE);
9015 pic16_freeAsmop(result,NULL,ic,TRUE);
9018 /*-----------------------------------------------------------------*/
9019 /* genNearPointerSet - pic16_emitcode for near pointer put */
9020 /*-----------------------------------------------------------------*/
9021 static void genNearPointerSet (operand *right,
9028 sym_link *ptype = operandType(result);
9031 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9032 retype= getSpec(operandType(right));
9034 pic16_aopOp(result,ic,FALSE);
9037 /* if the result is rematerializable &
9038 in data space & not a bit variable */
9039 //if (AOP_TYPE(result) == AOP_IMMD &&
9040 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
9041 DCL_TYPE(ptype) == POINTER &&
9042 !IS_BITVAR(retype)) {
9043 genDataPointerSet (right,result,ic);
9044 pic16_freeAsmop(result,NULL,ic,TRUE);
9048 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9049 pic16_aopOp(right,ic,FALSE);
9050 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9052 /* if the value is already in a pointer register
9053 then don't need anything more */
9054 if (!AOP_INPREG(AOP(result))) {
9055 /* otherwise get a free pointer register */
9056 //aop = newAsmop(0);
9057 //preg = getFreePtr(ic,&aop,FALSE);
9058 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9059 //pic16_emitcode("mov","%s,%s",
9061 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
9062 //rname = preg->name ;
9063 //pic16_emitcode("movwf","fsr0");
9064 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
9065 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
9066 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
9067 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9071 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9073 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9075 /* if bitfield then unpack the bits */
9076 if (IS_BITVAR(retype)) {
9077 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9078 "The programmer is obviously confused");
9079 // genPackBits (retype,right,"BAD",POINTER);
9083 /* we have can just get the values */
9084 int size = AOP_SIZE(right);
9087 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9089 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9092 //pic16_emitcode("mov","@%s,a",rname);
9093 pic16_emitcode("movf","indf0,w ;1");
9096 if (AOP_TYPE(right) == AOP_LIT) {
9097 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9099 pic16_emitcode("movlw","%s",l);
9100 pic16_emitcode("movwf","indf0 ;2");
9102 pic16_emitcode("clrf","indf0");
9104 pic16_emitcode("movf","%s,w",l);
9105 pic16_emitcode("movwf","indf0 ;2");
9107 //pic16_emitcode("mov","@%s,%s",rname,l);
9110 pic16_emitcode("incf","fsr0,f ;3");
9111 //pic16_emitcode("inc","%s",rname);
9116 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9117 /* now some housekeeping stuff */
9119 /* we had to allocate for this iCode */
9120 pic16_freeAsmop(NULL,aop,ic,TRUE);
9122 /* we did not allocate which means left
9123 already in a pointer register, then
9124 if size > 0 && this could be used again
9125 we have to point it back to where it
9127 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9128 if (AOP_SIZE(right) > 1 &&
9129 !OP_SYMBOL(result)->remat &&
9130 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9132 int size = AOP_SIZE(right) - 1;
9134 pic16_emitcode("decf","fsr0,f");
9135 //pic16_emitcode("dec","%s",rname);
9139 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9142 pic16_freeAsmop(right,NULL,ic,TRUE);
9143 pic16_freeAsmop(result,NULL,ic,TRUE);
9146 /*-----------------------------------------------------------------*/
9147 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9148 /*-----------------------------------------------------------------*/
9149 static void genPagedPointerSet (operand *right,
9158 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9160 retype= getSpec(operandType(right));
9162 pic16_aopOp(result,ic,FALSE);
9164 /* if the value is already in a pointer register
9165 then don't need anything more */
9166 if (!AOP_INPREG(AOP(result))) {
9167 /* otherwise get a free pointer register */
9169 preg = getFreePtr(ic,&aop,FALSE);
9170 pic16_emitcode("mov","%s,%s",
9172 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9173 rname = preg->name ;
9175 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9177 pic16_freeAsmop(result,NULL,ic,TRUE);
9178 pic16_aopOp (right,ic,FALSE);
9180 /* if bitfield then unpack the bits */
9181 if (IS_BITVAR(retype))
9182 genPackBits (retype,right,rname,PPOINTER);
9184 /* we have can just get the values */
9185 int size = AOP_SIZE(right);
9189 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9192 pic16_emitcode("movx","@%s,a",rname);
9195 pic16_emitcode("inc","%s",rname);
9201 /* now some housekeeping stuff */
9203 /* we had to allocate for this iCode */
9204 pic16_freeAsmop(NULL,aop,ic,TRUE);
9206 /* we did not allocate which means left
9207 already in a pointer register, then
9208 if size > 0 && this could be used again
9209 we have to point it back to where it
9211 if (AOP_SIZE(right) > 1 &&
9212 !OP_SYMBOL(result)->remat &&
9213 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9215 int size = AOP_SIZE(right) - 1;
9217 pic16_emitcode("dec","%s",rname);
9222 pic16_freeAsmop(right,NULL,ic,TRUE);
9227 /*-----------------------------------------------------------------*/
9228 /* genFarPointerSet - set value from far space */
9229 /*-----------------------------------------------------------------*/
9230 static void genFarPointerSet (operand *right,
9231 operand *result, iCode *ic)
9234 sym_link *retype = getSpec(operandType(right));
9236 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9237 pic16_aopOp(result,ic,FALSE);
9239 /* if the operand is already in dptr
9240 then we do nothing else we move the value to dptr */
9241 if (AOP_TYPE(result) != AOP_STR) {
9242 /* if this is remateriazable */
9243 if (AOP_TYPE(result) == AOP_IMMD)
9244 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9245 else { /* we need to get it byte by byte */
9246 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9247 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9248 if (options.model == MODEL_FLAT24)
9250 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9254 /* so dptr know contains the address */
9255 pic16_freeAsmop(result,NULL,ic,TRUE);
9256 pic16_aopOp(right,ic,FALSE);
9258 /* if bit then unpack */
9259 if (IS_BITVAR(retype))
9260 genPackBits(retype,right,"dptr",FPOINTER);
9262 size = AOP_SIZE(right);
9266 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9268 pic16_emitcode("movx","@dptr,a");
9270 pic16_emitcode("inc","dptr");
9274 pic16_freeAsmop(right,NULL,ic,TRUE);
9277 /*-----------------------------------------------------------------*/
9278 /* genGenPointerSet - set value from generic pointer space */
9279 /*-----------------------------------------------------------------*/
9280 static void genGenPointerSet (operand *right,
9281 operand *result, iCode *ic)
9284 sym_link *retype = getSpec(operandType(right));
9286 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9288 pic16_aopOp(result,ic,FALSE);
9289 pic16_aopOp(right,ic,FALSE);
9290 size = AOP_SIZE(right);
9292 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9294 /* if the operand is already in dptr
9295 then we do nothing else we move the value to dptr */
9296 if (AOP_TYPE(result) != AOP_STR) {
9297 /* if this is remateriazable */
9298 if (AOP_TYPE(result) == AOP_IMMD) {
9299 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9300 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9302 else { /* we need to get it byte by byte */
9303 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9304 size = AOP_SIZE(right);
9307 /* hack hack! see if this the FSR. If so don't load W */
9308 if(AOP_TYPE(right) != AOP_ACC) {
9310 // pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(result), pic16_popCopyReg(&pic16_pc_fsr0), 0));
9312 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9313 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9315 if(AOP_SIZE(result) > 1) {
9316 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9317 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9318 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9323 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9325 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9326 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9330 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9331 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9334 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9341 if(aopIdx(AOP(result),0) != 4) {
9343 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9347 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9352 /* so dptr know contains the address */
9355 /* if bit then unpack */
9356 if (IS_BITVAR(retype))
9357 genPackBits(retype,right,"dptr",GPOINTER);
9359 size = AOP_SIZE(right);
9362 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9366 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9367 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9369 if (AOP_TYPE(right) == AOP_LIT)
9370 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9372 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9374 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9381 pic16_freeAsmop(right,NULL,ic,TRUE);
9382 pic16_freeAsmop(result,NULL,ic,TRUE);
9385 /*-----------------------------------------------------------------*/
9386 /* genPointerSet - stores the value into a pointer location */
9387 /*-----------------------------------------------------------------*/
9388 static void genPointerSet (iCode *ic)
9390 operand *right, *result ;
9391 sym_link *type, *etype;
9394 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9396 right = IC_RIGHT(ic);
9397 result = IC_RESULT(ic) ;
9399 /* depending on the type of pointer we need to
9400 move it to the correct pointer register */
9401 type = operandType(result);
9402 etype = getSpec(type);
9403 /* if left is of type of pointer then it is simple */
9404 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9405 p_type = DCL_TYPE(type);
9408 /* we have to go by the storage class */
9409 p_type = PTR_TYPE(SPEC_OCLS(etype));
9411 /* if (SPEC_OCLS(etype)->codesp ) { */
9412 /* p_type = CPOINTER ; */
9415 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9416 /* p_type = FPOINTER ; */
9418 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9419 /* p_type = PPOINTER ; */
9421 /* if (SPEC_OCLS(etype) == idata ) */
9422 /* p_type = IPOINTER ; */
9424 /* p_type = POINTER ; */
9427 /* now that we have the pointer type we assign
9428 the pointer values */
9433 genNearPointerSet (right,result,ic);
9437 genPagedPointerSet (right,result,ic);
9441 genFarPointerSet (right,result,ic);
9445 genGenPointerSet (right,result,ic);
9449 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9450 "genPointerSet: illegal pointer type");
9454 /*-----------------------------------------------------------------*/
9455 /* genIfx - generate code for Ifx statement */
9456 /*-----------------------------------------------------------------*/
9457 static void genIfx (iCode *ic, iCode *popIc)
9459 operand *cond = IC_COND(ic);
9462 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9464 pic16_aopOp(cond,ic,FALSE);
9466 /* get the value into acc */
9467 if (AOP_TYPE(cond) != AOP_CRY)
9468 pic16_toBoolean(cond);
9471 /* the result is now in the accumulator */
9472 pic16_freeAsmop(cond,NULL,ic,TRUE);
9474 /* if there was something to be popped then do it */
9478 /* if the condition is a bit variable */
9479 if (isbit && IS_ITEMP(cond) &&
9481 genIfxJump(ic,SPIL_LOC(cond)->rname);
9482 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9485 if (isbit && !IS_ITEMP(cond))
9486 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9494 /*-----------------------------------------------------------------*/
9495 /* genAddrOf - generates code for address of */
9496 /*-----------------------------------------------------------------*/
9498 static void genAddrOf (iCode *ic)
9500 operand *right, *result, *left;
9503 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9506 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9508 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9509 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9510 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9512 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9514 size = AOP_SIZE(IC_RESULT(ic));
9519 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9520 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9525 pic16_freeAsmop(left,NULL,ic,FALSE);
9526 pic16_freeAsmop(result,NULL,ic,TRUE);
9530 #else /* new genAddrOf */
9532 static void genAddrOf (iCode *ic)
9534 operand *result, *left;
9536 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9537 pCodeOp *pcop0, *pcop1, *pcop2;
9539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9541 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9542 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9544 sym = OP_SYMBOL( left );
9546 size = AOP_SIZE(IC_RESULT(ic));
9548 if(pic16_debug_verbose) {
9549 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9550 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9553 /* Assume that what we want the address of is in data space
9554 * since there is no stack on the PIC, yet! -- VR */
9556 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9559 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9562 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9566 pic16_emitpcode(POC_MOVLW, pcop0);
9567 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9568 pic16_emitpcode(POC_MOVLW, pcop1);
9569 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9570 pic16_emitpcode(POC_MOVLW, pcop2);
9571 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9574 pic16_emitpcode(POC_MOVLW, pcop0);
9575 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9576 pic16_emitpcode(POC_MOVLW, pcop1);
9577 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9579 pic16_emitpcode(POC_MOVLW, pcop0);
9580 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9583 pic16_freeAsmop(result,NULL,ic,TRUE);
9584 pic16_freeAsmop(left, NULL, ic, FALSE);
9587 #endif /* new genAddrOf */
9590 /*-----------------------------------------------------------------*/
9591 /* genFarFarAssign - assignment when both are in far space */
9592 /*-----------------------------------------------------------------*/
9593 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9595 int size = AOP_SIZE(right);
9598 /* first push the right side on to the stack */
9600 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9602 pic16_emitcode ("push","acc");
9605 pic16_freeAsmop(right,NULL,ic,FALSE);
9606 /* now assign DPTR to result */
9607 pic16_aopOp(result,ic,FALSE);
9608 size = AOP_SIZE(result);
9610 pic16_emitcode ("pop","acc");
9611 pic16_aopPut(AOP(result),"a",--offset);
9613 pic16_freeAsmop(result,NULL,ic,FALSE);
9618 /*-----------------------------------------------------------------*/
9619 /* genAssign - generate code for assignment */
9620 /*-----------------------------------------------------------------*/
9621 static void genAssign (iCode *ic)
9623 operand *result, *right;
9624 int size, offset,know_W;
9625 unsigned long lit = 0L;
9627 result = IC_RESULT(ic);
9628 right = IC_RIGHT(ic) ;
9630 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9632 /* if they are the same */
9633 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9636 pic16_aopOp(right,ic,FALSE);
9637 pic16_aopOp(result,ic,TRUE);
9639 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9641 /* if they are the same registers */
9642 if (pic16_sameRegs(AOP(right),AOP(result)))
9645 /* if the result is a bit */
9646 if (AOP_TYPE(result) == AOP_CRY) {
9647 /* if the right size is a literal then
9648 we know what the value is */
9649 if (AOP_TYPE(right) == AOP_LIT) {
9651 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9652 pic16_popGet(AOP(result),0));
9654 if (((int) operandLitValue(right)))
9655 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9656 AOP(result)->aopu.aop_dir,
9657 AOP(result)->aopu.aop_dir);
9659 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9660 AOP(result)->aopu.aop_dir,
9661 AOP(result)->aopu.aop_dir);
9665 /* the right is also a bit variable */
9666 if (AOP_TYPE(right) == AOP_CRY) {
9667 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9668 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9669 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9671 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9672 AOP(result)->aopu.aop_dir,
9673 AOP(result)->aopu.aop_dir);
9674 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9675 AOP(right)->aopu.aop_dir,
9676 AOP(right)->aopu.aop_dir);
9677 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9678 AOP(result)->aopu.aop_dir,
9679 AOP(result)->aopu.aop_dir);
9684 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9685 pic16_toBoolean(right);
9687 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9688 //pic16_aopPut(AOP(result),"a",0);
9692 /* bit variables done */
9694 size = AOP_SIZE(result);
9696 if(AOP_TYPE(right) == AOP_LIT)
9697 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9699 /* VR - What is this?! */
9700 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9701 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9702 if(aopIdx(AOP(result),0) == 4) {
9703 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9704 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9705 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9708 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9713 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9714 if(AOP_TYPE(right) == AOP_LIT) {
9716 if(know_W != (lit&0xff))
9717 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9719 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9721 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9725 } else if (AOP_TYPE(right) == AOP_CRY) {
9726 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9728 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9729 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9732 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9735 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9736 normally should work, but mind that the W register live range
9737 is not checked, so if the code generator assumes that the W
9738 is already loaded after such a pair, wrong code will be generated.
9740 Checking the live range is the next step.
9741 This is experimental code yet and has not been fully tested yet.
9742 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9743 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9745 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9747 /* This is the old code, which is assumed(?!) that works fine(!?) */
9749 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9750 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9759 pic16_freeAsmop (right,NULL,ic,FALSE);
9760 pic16_freeAsmop (result,NULL,ic,TRUE);
9763 /*-----------------------------------------------------------------*/
9764 /* genJumpTab - generates code for jump table */
9765 /*-----------------------------------------------------------------*/
9766 static void genJumpTab (iCode *ic)
9771 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9773 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9774 /* get the condition into accumulator */
9775 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9777 /* multiply by three */
9778 pic16_emitcode("add","a,acc");
9779 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9781 jtab = newiTempLabel(NULL);
9782 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9783 pic16_emitcode("jmp","@a+dptr");
9784 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9786 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9787 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9789 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9790 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9791 pic16_emitpLabel(jtab->key);
9793 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9795 /* now generate the jump labels */
9796 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9797 jtab = setNextItem(IC_JTLABELS(ic))) {
9798 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9799 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9805 /*-----------------------------------------------------------------*/
9806 /* genMixedOperation - gen code for operators between mixed types */
9807 /*-----------------------------------------------------------------*/
9809 TSD - Written for the PIC port - but this unfortunately is buggy.
9810 This routine is good in that it is able to efficiently promote
9811 types to different (larger) sizes. Unfortunately, the temporary
9812 variables that are optimized out by this routine are sometimes
9813 used in other places. So until I know how to really parse the
9814 iCode tree, I'm going to not be using this routine :(.
9816 static int genMixedOperation (iCode *ic)
9819 operand *result = IC_RESULT(ic);
9820 sym_link *ctype = operandType(IC_LEFT(ic));
9821 operand *right = IC_RIGHT(ic);
9827 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9829 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9835 nextright = IC_RIGHT(nextic);
9836 nextleft = IC_LEFT(nextic);
9837 nextresult = IC_RESULT(nextic);
9839 pic16_aopOp(right,ic,FALSE);
9840 pic16_aopOp(result,ic,FALSE);
9841 pic16_aopOp(nextright, nextic, FALSE);
9842 pic16_aopOp(nextleft, nextic, FALSE);
9843 pic16_aopOp(nextresult, nextic, FALSE);
9845 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9851 pic16_emitcode(";remove right +","");
9853 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9859 pic16_emitcode(";remove left +","");
9863 big = AOP_SIZE(nextleft);
9864 small = AOP_SIZE(nextright);
9866 switch(nextic->op) {
9869 pic16_emitcode(";optimize a +","");
9870 /* if unsigned or not an integral type */
9871 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9872 pic16_emitcode(";add a bit to something","");
9875 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9877 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9878 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9879 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9881 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9889 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9890 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9891 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9894 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9896 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9897 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9898 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9899 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9900 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9903 pic16_emitcode("rlf","known_zero,w");
9910 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9911 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9912 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9914 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9924 pic16_freeAsmop(right,NULL,ic,TRUE);
9925 pic16_freeAsmop(result,NULL,ic,TRUE);
9926 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9927 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9929 nextic->generated = 1;
9936 /*-----------------------------------------------------------------*/
9937 /* genCast - gen code for casting */
9938 /*-----------------------------------------------------------------*/
9939 static void genCast (iCode *ic)
9941 operand *result = IC_RESULT(ic);
9942 sym_link *ctype = operandType(IC_LEFT(ic));
9943 sym_link *rtype = operandType(IC_RIGHT(ic));
9944 operand *right = IC_RIGHT(ic);
9947 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9948 /* if they are equivalent then do nothing */
9949 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9952 pic16_aopOp(right,ic,FALSE) ;
9953 pic16_aopOp(result,ic,FALSE);
9955 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9957 /* if the result is a bit */
9958 if (AOP_TYPE(result) == AOP_CRY) {
9960 /* if the right size is a literal then
9961 * we know what the value is */
9962 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9964 if (AOP_TYPE(right) == AOP_LIT) {
9965 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9966 pic16_popGet(AOP(result),0));
9968 if (((int) operandLitValue(right)))
9969 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9970 AOP(result)->aopu.aop_dir,
9971 AOP(result)->aopu.aop_dir);
9973 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9974 AOP(result)->aopu.aop_dir,
9975 AOP(result)->aopu.aop_dir);
9979 /* the right is also a bit variable */
9980 if (AOP_TYPE(right) == AOP_CRY) {
9982 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9984 pic16_emitcode("clrc","");
9985 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9986 AOP(right)->aopu.aop_dir,
9987 AOP(right)->aopu.aop_dir);
9988 pic16_aopPut(AOP(result),"c",0);
9993 if (AOP_TYPE(right) == AOP_REG) {
9994 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9995 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9996 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9998 pic16_toBoolean(right);
9999 pic16_aopPut(AOP(result),"a",0);
10003 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10006 size = AOP_SIZE(result);
10008 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10010 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10011 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10012 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10015 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10020 /* if they are the same size : or less */
10021 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10023 /* if they are in the same place */
10024 if (pic16_sameRegs(AOP(right),AOP(result)))
10027 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10029 if (IS_PTR_CONST(rtype))
10031 if (IS_CODEPTR(rtype))
10033 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10036 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10038 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10040 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10043 if(AOP_TYPE(right) == AOP_IMMD) {
10044 pCodeOp *pcop0, *pcop1, *pcop2;
10045 symbol *sym = OP_SYMBOL( right );
10047 size = AOP_SIZE(result);
10049 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10051 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10053 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10056 pic16_emitpcode(POC_MOVLW, pcop0);
10057 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10058 pic16_emitpcode(POC_MOVLW, pcop1);
10059 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10060 pic16_emitpcode(POC_MOVLW, pcop2);
10061 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10064 pic16_emitpcode(POC_MOVLW, pcop0);
10065 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10066 pic16_emitpcode(POC_MOVLW, pcop1);
10067 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10069 pic16_emitpcode(POC_MOVLW, pcop0);
10070 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10074 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10075 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10076 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10077 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10078 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10079 if(AOP_SIZE(result) <2)
10080 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10082 /* if they in different places then copy */
10083 size = AOP_SIZE(result);
10086 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10087 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10094 /* if the result is of type pointer */
10095 if (IS_PTR(ctype)) {
10097 sym_link *type = operandType(right);
10098 sym_link *etype = getSpec(type);
10100 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10102 /* pointer to generic pointer */
10103 if (IS_GENPTR(ctype)) {
10107 p_type = DCL_TYPE(type);
10109 /* we have to go by the storage class */
10110 p_type = PTR_TYPE(SPEC_OCLS(etype));
10112 /* if (SPEC_OCLS(etype)->codesp ) */
10113 /* p_type = CPOINTER ; */
10115 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10116 /* p_type = FPOINTER ; */
10118 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10119 /* p_type = PPOINTER; */
10121 /* if (SPEC_OCLS(etype) == idata ) */
10122 /* p_type = IPOINTER ; */
10124 /* p_type = POINTER ; */
10127 /* the first two bytes are known */
10128 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10129 size = GPTRSIZE - 1;
10132 if(offset < AOP_SIZE(right)) {
10133 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10134 if ((AOP_TYPE(right) == AOP_PCODE) &&
10135 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10136 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10137 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10139 pic16_aopPut(AOP(result),
10140 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10144 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10147 /* the last byte depending on type */
10151 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10154 pic16_emitcode(";BUG!? ","%d",__LINE__);
10158 pic16_emitcode(";BUG!? ","%d",__LINE__);
10162 pic16_emitcode(";BUG!? ","%d",__LINE__);
10167 /* this should never happen */
10168 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10169 "got unknown pointer type");
10172 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10176 /* just copy the pointers */
10177 size = AOP_SIZE(result);
10180 pic16_aopPut(AOP(result),
10181 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10190 /* so we now know that the size of destination is greater
10191 than the size of the source.
10192 Now, if the next iCode is an operator then we might be
10193 able to optimize the operation without performing a cast.
10195 if(genMixedOperation(ic))
10198 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10200 /* we move to result for the size of source */
10201 size = AOP_SIZE(right);
10204 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10205 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10209 /* now depending on the sign of the destination */
10210 size = AOP_SIZE(result) - AOP_SIZE(right);
10211 /* if unsigned or not an integral type */
10212 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10214 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10216 /* we need to extend the sign :( */
10219 /* Save one instruction of casting char to int */
10220 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10221 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10222 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10224 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10227 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10229 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10231 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10234 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10239 pic16_freeAsmop(right,NULL,ic,TRUE);
10240 pic16_freeAsmop(result,NULL,ic,TRUE);
10244 /*-----------------------------------------------------------------*/
10245 /* genDjnz - generate decrement & jump if not zero instrucion */
10246 /*-----------------------------------------------------------------*/
10247 static int genDjnz (iCode *ic, iCode *ifx)
10249 symbol *lbl, *lbl1;
10250 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10255 /* if the if condition has a false label
10256 then we cannot save */
10260 /* if the minus is not of the form
10262 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10263 !IS_OP_LITERAL(IC_RIGHT(ic)))
10266 if (operandLitValue(IC_RIGHT(ic)) != 1)
10269 /* if the size of this greater than one then no
10271 if (getSize(operandType(IC_RESULT(ic))) > 1)
10274 /* otherwise we can save BIG */
10275 lbl = newiTempLabel(NULL);
10276 lbl1= newiTempLabel(NULL);
10278 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10280 if (IS_AOP_PREG(IC_RESULT(ic))) {
10281 pic16_emitcode("dec","%s",
10282 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10283 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10284 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10288 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10289 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10291 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10292 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10295 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10296 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10297 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10298 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10301 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10302 ifx->generated = 1;
10306 /*-----------------------------------------------------------------*/
10307 /* genReceive - generate code for a receive iCode */
10308 /*-----------------------------------------------------------------*/
10309 static void genReceive (iCode *ic)
10311 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10313 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10314 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10315 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10317 int size = getSize(operandType(IC_RESULT(ic)));
10318 int offset = pic16_fReturnSizePic - size;
10321 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10322 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10326 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10328 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10329 size = AOP_SIZE(IC_RESULT(ic));
10332 pic16_emitcode ("pop","acc");
10333 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10336 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10339 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10341 assignResultValue(IC_RESULT(ic));
10344 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10347 /*-----------------------------------------------------------------*/
10348 /* genDummyRead - generate code for dummy read of volatiles */
10349 /*-----------------------------------------------------------------*/
10351 genDummyRead (iCode * ic)
10353 pic16_emitcode ("; genDummyRead","");
10354 pic16_emitcode ("; not implemented","");
10359 /*-----------------------------------------------------------------*/
10360 /* genpic16Code - generate code for pic16 based controllers */
10361 /*-----------------------------------------------------------------*/
10363 * At this point, ralloc.c has gone through the iCode and attempted
10364 * to optimize in a way suitable for a PIC. Now we've got to generate
10365 * PIC instructions that correspond to the iCode.
10367 * Once the instructions are generated, we'll pass through both the
10368 * peep hole optimizer and the pCode optimizer.
10369 *-----------------------------------------------------------------*/
10371 void genpic16Code (iCode *lic)
10376 lineHead = lineCurr = NULL;
10378 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10379 pic16_addpBlock(pb);
10382 /* if debug information required */
10383 if (options.debug && currFunc) {
10385 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10387 if (IS_STATIC(currFunc->etype)) {
10388 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10389 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10391 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10392 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10401 for (ic = lic ; ic ; ic = ic->next ) {
10403 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10404 // DEBUGpic16_emitcode("; VR", "");
10405 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10406 if ( cln != ic->lineno ) {
10407 if ( options.debug ) {
10409 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10410 FileBaseName(ic->filename),ic->lineno,
10411 ic->level,ic->block);
10415 if(!options.noCcodeInAsm) {
10416 pic16_addpCode2pBlock(pb,
10417 pic16_newpCodeCSource(ic->lineno, ic->filename,
10418 printCLine(ic->filename, ic->lineno)));
10424 if(options.iCodeInAsm) {
10425 /* insert here code to print iCode as comment */
10426 pic16_emitcomment("; ic:%d: %s", ic->seq, printILine(ic));
10429 /* if the result is marked as
10430 spilt and rematerializable or code for
10431 this has already been generated then
10433 if (resultRemat(ic) || ic->generated )
10436 /* depending on the operation */
10455 /* IPOP happens only when trying to restore a
10456 spilt live range, if there is an ifx statement
10457 following this pop then the if statement might
10458 be using some of the registers being popped which
10459 would destroy the contents of the register so
10460 we need to check for this condition and handle it */
10462 ic->next->op == IFX &&
10463 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10464 genIfx (ic->next,ic);
10482 genEndFunction (ic);
10498 pic16_genPlus (ic) ;
10502 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10503 pic16_genMinus (ic);
10519 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10523 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10530 /* note these two are xlated by algebraic equivalence
10531 during parsing SDCC.y */
10532 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10533 "got '>=' or '<=' shouldn't have come here");
10537 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10549 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10553 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10557 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10581 genRightShift (ic);
10584 case GET_VALUE_AT_ADDRESS:
10589 if (POINTER_SET(ic))
10616 addSet(&_G.sendSet,ic);
10619 case DUMMY_READ_VOLATILE:
10629 /* now we are ready to call the
10630 peep hole optimizer */
10631 if (!options.nopeep) {
10632 peepHole (&lineHead);
10634 /* now do the actual printing */
10635 printLine (lineHead,codeOutFile);
10638 DFPRINTF((stderr,"printing pBlock\n\n"));
10639 pic16_printpBlock(stdout,pb);