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)
3815 if ( IC_TRUE(ifx) ) {
3816 switch(status_bit) {
3831 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3832 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3836 switch(status_bit) {
3850 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3851 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3857 /*-----------------------------------------------------------------*/
3859 /*-----------------------------------------------------------------*/
3860 static void genSkipc(resolvedIfx *rifx)
3870 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3871 rifx->generated = 1;
3874 /*-----------------------------------------------------------------*/
3876 /*-----------------------------------------------------------------*/
3877 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3882 if( (rifx->condition ^ invert_condition) & 1)
3887 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3888 rifx->generated = 1;
3891 /*-----------------------------------------------------------------*/
3893 /*-----------------------------------------------------------------*/
3894 static void genSkipz(iCode *ifx, int condition)
3905 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3907 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3910 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3912 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3915 /*-----------------------------------------------------------------*/
3917 /*-----------------------------------------------------------------*/
3918 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3924 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3926 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3929 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3930 rifx->generated = 1;
3934 /*-----------------------------------------------------------------*/
3935 /* genChkZeroes :- greater or less than comparison */
3936 /* For each byte in a literal that is zero, inclusive or the */
3937 /* the corresponding byte in the operand with W */
3938 /* returns true if any of the bytes are zero */
3939 /*-----------------------------------------------------------------*/
3940 static int genChkZeroes(operand *op, int lit, int size)
3947 i = (lit >> (size*8)) & 0xff;
3951 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3953 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3962 /*-----------------------------------------------------------------*/
3963 /* genCmp :- greater or less than comparison */
3964 /*-----------------------------------------------------------------*/
3965 static void genCmp (operand *left,operand *right,
3966 operand *result, iCode *ifx, int sign)
3968 int size; //, offset = 0 ;
3969 unsigned long lit = 0L,i = 0;
3970 resolvedIfx rFalseIfx;
3971 // resolvedIfx rTrueIfx;
3973 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3976 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3977 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3981 resolveIfx(&rFalseIfx,ifx);
3982 truelbl = newiTempLabel(NULL);
3983 size = max(AOP_SIZE(left),AOP_SIZE(right));
3985 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3989 /* if literal is on the right then swap with left */
3990 if ((AOP_TYPE(right) == AOP_LIT)) {
3991 operand *tmp = right ;
3992 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3993 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3996 lit = (lit - 1) & mask;
3999 rFalseIfx.condition ^= 1;
4002 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4003 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4007 //if(IC_TRUE(ifx) == NULL)
4008 /* if left & right are bit variables */
4009 if (AOP_TYPE(left) == AOP_CRY &&
4010 AOP_TYPE(right) == AOP_CRY ) {
4011 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4012 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4014 /* subtract right from left if at the
4015 end the carry flag is set then we know that
4016 left is greater than right */
4020 symbol *lbl = newiTempLabel(NULL);
4023 if(AOP_TYPE(right) == AOP_LIT) {
4025 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4027 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4034 genSkipCond(&rFalseIfx,left,size-1,7);
4036 /* no need to compare to 0...*/
4037 /* NOTE: this is a de-generate compare that most certainly
4038 * creates some dead code. */
4039 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4041 if(ifx) ifx->generated = 1;
4048 //i = (lit >> (size*8)) & 0xff;
4049 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4051 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4053 i = ((0-lit) & 0xff);
4056 /* lit is 0x7f, all signed chars are less than
4057 * this except for 0x7f itself */
4058 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4059 genSkipz2(&rFalseIfx,0);
4061 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4062 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4063 genSkipc(&rFalseIfx);
4068 genSkipz2(&rFalseIfx,1);
4070 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4071 genSkipc(&rFalseIfx);
4075 if(ifx) ifx->generated = 1;
4079 /* chars are out of the way. now do ints and longs */
4082 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4089 genSkipCond(&rFalseIfx,left,size,7);
4090 if(ifx) ifx->generated = 1;
4095 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4097 //rFalseIfx.condition ^= 1;
4098 //genSkipCond(&rFalseIfx,left,size,7);
4099 //rFalseIfx.condition ^= 1;
4101 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4102 if(rFalseIfx.condition)
4103 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4105 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4107 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4108 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4109 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4112 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4114 if(rFalseIfx.condition) {
4116 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4122 genSkipc(&rFalseIfx);
4123 pic16_emitpLabel(truelbl->key);
4124 if(ifx) ifx->generated = 1;
4131 if( (lit & 0xff) == 0) {
4132 /* lower byte is zero */
4133 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4134 i = ((lit >> 8) & 0xff) ^0x80;
4135 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4136 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4137 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4138 genSkipc(&rFalseIfx);
4141 if(ifx) ifx->generated = 1;
4146 /* Special cases for signed longs */
4147 if( (lit & 0xffffff) == 0) {
4148 /* lower byte is zero */
4149 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4150 i = ((lit >> 8*3) & 0xff) ^0x80;
4151 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4152 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4153 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4154 genSkipc(&rFalseIfx);
4157 if(ifx) ifx->generated = 1;
4165 if(lit & (0x80 << (size*8))) {
4166 /* lit is negative */
4167 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4169 //genSkipCond(&rFalseIfx,left,size,7);
4171 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4173 if(rFalseIfx.condition)
4174 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4176 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4180 /* lit is positive */
4181 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4182 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4183 if(rFalseIfx.condition)
4184 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4186 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4191 This works, but is only good for ints.
4192 It also requires a "known zero" register.
4193 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4194 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4195 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4196 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4197 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4198 genSkipc(&rFalseIfx);
4200 pic16_emitpLabel(truelbl->key);
4201 if(ifx) ifx->generated = 1;
4205 /* There are no more special cases, so perform a general compare */
4207 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4208 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4212 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4214 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4216 //rFalseIfx.condition ^= 1;
4217 genSkipc(&rFalseIfx);
4219 pic16_emitpLabel(truelbl->key);
4221 if(ifx) ifx->generated = 1;
4228 /* sign is out of the way. So now do an unsigned compare */
4229 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4232 /* General case - compare to an unsigned literal on the right.*/
4234 i = (lit >> (size*8)) & 0xff;
4235 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4236 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4238 i = (lit >> (size*8)) & 0xff;
4241 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4243 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4245 /* this byte of the lit is zero,
4246 *if it's not the last then OR in the variable */
4248 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4253 pic16_emitpLabel(lbl->key);
4254 //if(emitFinalCheck)
4255 genSkipc(&rFalseIfx);
4257 pic16_emitpLabel(truelbl->key);
4259 if(ifx) ifx->generated = 1;
4266 if(AOP_TYPE(left) == AOP_LIT) {
4267 //symbol *lbl = newiTempLabel(NULL);
4269 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4272 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4275 if((lit == 0) && (sign == 0)){
4278 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4280 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4282 genSkipz2(&rFalseIfx,0);
4283 if(ifx) ifx->generated = 1;
4290 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4291 /* degenerate compare can never be true */
4292 if(rFalseIfx.condition == 0)
4293 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4295 if(ifx) ifx->generated = 1;
4300 /* signed comparisons to a literal byte */
4302 int lp1 = (lit+1) & 0xff;
4304 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4307 rFalseIfx.condition ^= 1;
4308 genSkipCond(&rFalseIfx,right,0,7);
4311 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4312 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4313 genSkipz2(&rFalseIfx,1);
4316 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4317 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4318 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4319 rFalseIfx.condition ^= 1;
4320 genSkipc(&rFalseIfx);
4324 /* unsigned comparisons to a literal byte */
4326 switch(lit & 0xff ) {
4328 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4329 genSkipz2(&rFalseIfx,0);
4332 rFalseIfx.condition ^= 1;
4333 genSkipCond(&rFalseIfx,right,0,7);
4337 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4338 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4339 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4340 rFalseIfx.condition ^= 1;
4341 if (AOP_TYPE(result) == AOP_CRY)
4342 genSkipc(&rFalseIfx);
4344 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4345 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4351 if(ifx) ifx->generated = 1;
4357 /* Size is greater than 1 */
4365 /* this means lit = 0xffffffff, or -1 */
4368 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4369 rFalseIfx.condition ^= 1;
4370 genSkipCond(&rFalseIfx,right,size,7);
4371 if(ifx) ifx->generated = 1;
4378 if(rFalseIfx.condition) {
4379 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4380 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4383 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4385 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4389 if(rFalseIfx.condition) {
4390 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4391 pic16_emitpLabel(truelbl->key);
4393 rFalseIfx.condition ^= 1;
4394 genSkipCond(&rFalseIfx,right,s,7);
4397 if(ifx) ifx->generated = 1;
4401 if((size == 1) && (0 == (lp1&0xff))) {
4402 /* lower byte of signed word is zero */
4403 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4404 i = ((lp1 >> 8) & 0xff) ^0x80;
4405 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4406 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4407 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4408 rFalseIfx.condition ^= 1;
4409 genSkipc(&rFalseIfx);
4412 if(ifx) ifx->generated = 1;
4416 if(lit & (0x80 << (size*8))) {
4417 /* Lit is less than zero */
4418 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4419 //rFalseIfx.condition ^= 1;
4420 //genSkipCond(&rFalseIfx,left,size,7);
4421 //rFalseIfx.condition ^= 1;
4422 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4423 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4425 if(rFalseIfx.condition)
4426 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4428 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4432 /* Lit is greater than or equal to zero */
4433 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4434 //rFalseIfx.condition ^= 1;
4435 //genSkipCond(&rFalseIfx,right,size,7);
4436 //rFalseIfx.condition ^= 1;
4438 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4439 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4441 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4442 if(rFalseIfx.condition)
4443 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4445 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4450 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4451 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4455 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4457 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4459 rFalseIfx.condition ^= 1;
4460 //rFalseIfx.condition = 1;
4461 genSkipc(&rFalseIfx);
4463 pic16_emitpLabel(truelbl->key);
4465 if(ifx) ifx->generated = 1;
4470 /* compare word or long to an unsigned literal on the right.*/
4475 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4478 break; /* handled above */
4481 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4483 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4484 genSkipz2(&rFalseIfx,0);
4488 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4490 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4493 if(rFalseIfx.condition)
4494 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4496 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4499 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4500 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4502 rFalseIfx.condition ^= 1;
4503 genSkipc(&rFalseIfx);
4506 pic16_emitpLabel(truelbl->key);
4508 if(ifx) ifx->generated = 1;
4514 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4515 i = (lit >> (size*8)) & 0xff;
4517 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4518 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4521 i = (lit >> (size*8)) & 0xff;
4524 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4526 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4528 /* this byte of the lit is zero,
4529 *if it's not the last then OR in the variable */
4531 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4536 pic16_emitpLabel(lbl->key);
4538 rFalseIfx.condition ^= 1;
4539 genSkipc(&rFalseIfx);
4543 pic16_emitpLabel(truelbl->key);
4544 if(ifx) ifx->generated = 1;
4548 /* Compare two variables */
4550 DEBUGpic16_emitcode(";sign","%d",sign);
4554 /* Sigh. thus sucks... */
4556 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4557 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4558 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4559 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4560 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4561 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4563 /* Signed char comparison */
4564 /* Special thanks to Nikolai Golovchenko for this snippet */
4565 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4566 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4567 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4568 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4569 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4570 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4572 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4573 genSkipc(&rFalseIfx);
4575 if(ifx) ifx->generated = 1;
4581 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4582 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4586 /* The rest of the bytes of a multi-byte compare */
4590 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4593 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4594 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4599 pic16_emitpLabel(lbl->key);
4601 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4602 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4603 (AOP_TYPE(result) == AOP_REG)) {
4604 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4605 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4607 genSkipc(&rFalseIfx);
4609 //genSkipc(&rFalseIfx);
4610 if(ifx) ifx->generated = 1;
4617 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4618 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4619 pic16_outBitC(result);
4621 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4622 /* if the result is used in the next
4623 ifx conditional branch then generate
4624 code a little differently */
4626 genIfxJump (ifx,"c");
4628 pic16_outBitC(result);
4629 /* leave the result in acc */
4634 /*-----------------------------------------------------------------*/
4635 /* genCmpGt :- greater than comparison */
4636 /*-----------------------------------------------------------------*/
4637 static void genCmpGt (iCode *ic, iCode *ifx)
4639 operand *left, *right, *result;
4640 sym_link *letype , *retype;
4643 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4645 right= IC_RIGHT(ic);
4646 result = IC_RESULT(ic);
4648 letype = getSpec(operandType(left));
4649 retype =getSpec(operandType(right));
4650 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4651 /* assign the amsops */
4652 pic16_aopOp (left,ic,FALSE);
4653 pic16_aopOp (right,ic,FALSE);
4654 pic16_aopOp (result,ic,TRUE);
4656 genCmp(right, left, result, ifx, sign);
4658 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4659 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4660 pic16_freeAsmop(result,NULL,ic,TRUE);
4663 /*-----------------------------------------------------------------*/
4664 /* genCmpLt - less than comparisons */
4665 /*-----------------------------------------------------------------*/
4666 static void genCmpLt (iCode *ic, iCode *ifx)
4668 operand *left, *right, *result;
4669 sym_link *letype , *retype;
4672 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4674 right= IC_RIGHT(ic);
4675 result = IC_RESULT(ic);
4677 letype = getSpec(operandType(left));
4678 retype =getSpec(operandType(right));
4679 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4681 /* assign the amsops */
4682 pic16_aopOp (left,ic,FALSE);
4683 pic16_aopOp (right,ic,FALSE);
4684 pic16_aopOp (result,ic,TRUE);
4686 genCmp(left, right, result, ifx, sign);
4688 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4689 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4690 pic16_freeAsmop(result,NULL,ic,TRUE);
4693 /*-----------------------------------------------------------------*/
4694 /* genc16bit2lit - compare a 16 bit value to a literal */
4695 /*-----------------------------------------------------------------*/
4696 static void genc16bit2lit(operand *op, int lit, int offset)
4700 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4701 if( (lit&0xff) == 0)
4706 switch( BYTEofLONG(lit,i)) {
4708 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4711 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4714 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4717 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4718 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4723 switch( BYTEofLONG(lit,i)) {
4725 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4729 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4733 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4736 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4738 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4744 /*-----------------------------------------------------------------*/
4745 /* gencjneshort - compare and jump if not equal */
4746 /*-----------------------------------------------------------------*/
4747 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4749 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4751 int res_offset = 0; /* the result may be a different size then left or right */
4752 int res_size = AOP_SIZE(result);
4756 unsigned long lit = 0L;
4757 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4758 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4760 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4761 resolveIfx(&rIfx,ifx);
4762 lbl = newiTempLabel(NULL);
4765 /* if the left side is a literal or
4766 if the right is in a pointer register and left
4768 if ((AOP_TYPE(left) == AOP_LIT) ||
4769 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4774 if(AOP_TYPE(right) == AOP_LIT)
4775 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4777 /* if the right side is a literal then anything goes */
4778 if (AOP_TYPE(right) == AOP_LIT &&
4779 AOP_TYPE(left) != AOP_DIR ) {
4782 genc16bit2lit(left, lit, 0);
4784 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4789 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4790 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4792 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4796 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4798 if(res_offset < res_size-1)
4806 /* if the right side is in a register or in direct space or
4807 if the left is a pointer register & right is not */
4808 else if (AOP_TYPE(right) == AOP_REG ||
4809 AOP_TYPE(right) == AOP_DIR ||
4810 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4811 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4812 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4813 int lbl_key = lbl->key;
4816 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4817 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4819 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4820 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4821 __FUNCTION__,__LINE__);
4825 /* switch(size) { */
4827 /* genc16bit2lit(left, lit, 0); */
4829 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4834 if((AOP_TYPE(left) == AOP_DIR) &&
4835 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4837 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4838 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4840 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4842 switch (lit & 0xff) {
4844 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4847 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4848 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4849 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4853 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4854 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4855 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4856 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4860 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4861 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4866 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4869 if(AOP_TYPE(result) == AOP_CRY) {
4870 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4875 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4877 /* fix me. probably need to check result size too */
4878 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4883 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4884 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4891 if(res_offset < res_size-1)
4896 } else if(AOP_TYPE(right) == AOP_REG &&
4897 AOP_TYPE(left) != AOP_DIR){
4900 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4901 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4902 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4907 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4909 if(res_offset < res_size-1)
4914 /* right is a pointer reg need both a & b */
4916 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4918 pic16_emitcode("mov","b,%s",l);
4919 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4920 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4925 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4927 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4929 pic16_emitpLabel(lbl->key);
4931 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4938 /*-----------------------------------------------------------------*/
4939 /* gencjne - compare and jump if not equal */
4940 /*-----------------------------------------------------------------*/
4941 static void gencjne(operand *left, operand *right, iCode *ifx)
4943 symbol *tlbl = newiTempLabel(NULL);
4945 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4946 gencjneshort(left, right, lbl);
4948 pic16_emitcode("mov","a,%s",one);
4949 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4950 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4951 pic16_emitcode("clr","a");
4952 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4954 pic16_emitpLabel(lbl->key);
4955 pic16_emitpLabel(tlbl->key);
4960 /*-----------------------------------------------------------------*/
4961 /* genCmpEq - generates code for equal to */
4962 /*-----------------------------------------------------------------*/
4963 static void genCmpEq (iCode *ic, iCode *ifx)
4965 operand *left, *right, *result;
4966 unsigned long lit = 0L;
4969 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4972 DEBUGpic16_emitcode ("; ifx is non-null","");
4974 DEBUGpic16_emitcode ("; ifx is null","");
4976 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4977 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4978 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4980 size = max(AOP_SIZE(left),AOP_SIZE(right));
4982 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4984 /* if literal, literal on the right or
4985 if the right is in a pointer register and left
4987 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4988 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4989 operand *tmp = right ;
4995 if(ifx && !AOP_SIZE(result)){
4997 /* if they are both bit variables */
4998 if (AOP_TYPE(left) == AOP_CRY &&
4999 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5000 if(AOP_TYPE(right) == AOP_LIT){
5001 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5003 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5004 pic16_emitcode("cpl","c");
5005 } else if(lit == 1L) {
5006 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5008 pic16_emitcode("clr","c");
5010 /* AOP_TYPE(right) == AOP_CRY */
5012 symbol *lbl = newiTempLabel(NULL);
5013 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5014 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5015 pic16_emitcode("cpl","c");
5016 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5018 /* if true label then we jump if condition
5020 tlbl = newiTempLabel(NULL);
5021 if ( IC_TRUE(ifx) ) {
5022 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5023 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5025 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5026 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5028 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5031 /* left and right are both bit variables, result is carry */
5034 resolveIfx(&rIfx,ifx);
5036 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5037 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5038 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5039 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5044 /* They're not both bit variables. Is the right a literal? */
5045 if(AOP_TYPE(right) == AOP_LIT) {
5046 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5051 switch(lit & 0xff) {
5053 if ( IC_TRUE(ifx) ) {
5054 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5056 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5058 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5059 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5063 if ( IC_TRUE(ifx) ) {
5064 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5066 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5068 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5069 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5073 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5075 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5080 /* end of size == 1 */
5084 genc16bit2lit(left,lit,offset);
5087 /* end of size == 2 */
5092 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5093 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5094 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5095 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5099 /* search for patterns that can be optimized */
5101 genc16bit2lit(left,lit,0);
5104 genSkipz(ifx,IC_TRUE(ifx) == NULL);
5106 genc16bit2lit(left,lit,2);
5108 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5109 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5122 } else if(AOP_TYPE(right) == AOP_CRY ) {
5123 /* we know the left is not a bit, but that the right is */
5124 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5125 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5126 pic16_popGet(AOP(right),offset));
5127 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5129 /* if the two are equal, then W will be 0 and the Z bit is set
5130 * we could test Z now, or go ahead and check the high order bytes if
5131 * the variable we're comparing is larger than a byte. */
5134 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5136 if ( IC_TRUE(ifx) ) {
5138 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5139 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5142 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5143 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5147 /* They're both variables that are larger than bits */
5150 tlbl = newiTempLabel(NULL);
5153 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5154 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5156 if ( IC_TRUE(ifx) ) {
5160 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5162 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5163 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5167 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5170 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5171 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5176 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5178 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5179 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5183 if(s>1 && IC_TRUE(ifx)) {
5184 pic16_emitpLabel(tlbl->key);
5185 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5189 /* mark the icode as generated */
5194 /* if they are both bit variables */
5195 if (AOP_TYPE(left) == AOP_CRY &&
5196 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5197 if(AOP_TYPE(right) == AOP_LIT){
5198 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5200 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5201 pic16_emitcode("cpl","c");
5202 } else if(lit == 1L) {
5203 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5205 pic16_emitcode("clr","c");
5207 /* AOP_TYPE(right) == AOP_CRY */
5209 symbol *lbl = newiTempLabel(NULL);
5210 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5211 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5212 pic16_emitcode("cpl","c");
5213 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5216 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5217 pic16_outBitC(result);
5221 genIfxJump (ifx,"c");
5224 /* if the result is used in an arithmetic operation
5225 then put the result in place */
5226 pic16_outBitC(result);
5229 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5230 gencjne(left,right,result,ifx);
5233 gencjne(left,right,newiTempLabel(NULL));
5235 if(IC_TRUE(ifx)->key)
5236 gencjne(left,right,IC_TRUE(ifx)->key);
5238 gencjne(left,right,IC_FALSE(ifx)->key);
5242 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5243 pic16_aopPut(AOP(result),"a",0);
5248 genIfxJump (ifx,"a");
5252 /* if the result is used in an arithmetic operation
5253 then put the result in place */
5255 if (AOP_TYPE(result) != AOP_CRY)
5256 pic16_outAcc(result);
5258 /* leave the result in acc */
5262 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5263 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5264 pic16_freeAsmop(result,NULL,ic,TRUE);
5267 /*-----------------------------------------------------------------*/
5268 /* ifxForOp - returns the icode containing the ifx for operand */
5269 /*-----------------------------------------------------------------*/
5270 static iCode *ifxForOp ( operand *op, iCode *ic )
5272 /* if true symbol then needs to be assigned */
5273 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5274 if (IS_TRUE_SYMOP(op))
5277 /* if this has register type condition and
5278 the next instruction is ifx with the same operand
5279 and live to of the operand is upto the ifx only then */
5281 ic->next->op == IFX &&
5282 IC_COND(ic->next)->key == op->key &&
5283 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5287 ic->next->op == IFX &&
5288 IC_COND(ic->next)->key == op->key) {
5289 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5293 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5295 ic->next->op == IFX)
5296 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5299 ic->next->op == IFX &&
5300 IC_COND(ic->next)->key == op->key) {
5301 DEBUGpic16_emitcode ("; "," key is okay");
5302 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5303 OP_SYMBOL(op)->liveTo,
5310 /*-----------------------------------------------------------------*/
5311 /* genAndOp - for && operation */
5312 /*-----------------------------------------------------------------*/
5313 static void genAndOp (iCode *ic)
5315 operand *left,*right, *result;
5318 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5319 /* note here that && operations that are in an
5320 if statement are taken away by backPatchLabels
5321 only those used in arthmetic operations remain */
5322 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5323 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5324 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5326 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5328 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5329 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5330 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5332 /* if both are bit variables */
5333 /* if (AOP_TYPE(left) == AOP_CRY && */
5334 /* AOP_TYPE(right) == AOP_CRY ) { */
5335 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5336 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5337 /* pic16_outBitC(result); */
5339 /* tlbl = newiTempLabel(NULL); */
5340 /* pic16_toBoolean(left); */
5341 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5342 /* pic16_toBoolean(right); */
5343 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5344 /* pic16_outBitAcc(result); */
5347 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5348 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5349 pic16_freeAsmop(result,NULL,ic,TRUE);
5353 /*-----------------------------------------------------------------*/
5354 /* genOrOp - for || operation */
5355 /*-----------------------------------------------------------------*/
5358 modified this code, but it doesn't appear to ever get called
5361 static void genOrOp (iCode *ic)
5363 operand *left,*right, *result;
5366 /* note here that || operations that are in an
5367 if statement are taken away by backPatchLabels
5368 only those used in arthmetic operations remain */
5369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5370 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5371 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5372 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5374 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5376 /* if both are bit variables */
5377 if (AOP_TYPE(left) == AOP_CRY &&
5378 AOP_TYPE(right) == AOP_CRY ) {
5379 pic16_emitcode("clrc","");
5380 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5381 AOP(left)->aopu.aop_dir,
5382 AOP(left)->aopu.aop_dir);
5383 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5384 AOP(right)->aopu.aop_dir,
5385 AOP(right)->aopu.aop_dir);
5386 pic16_emitcode("setc","");
5389 tlbl = newiTempLabel(NULL);
5390 pic16_toBoolean(left);
5392 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5393 pic16_toBoolean(right);
5394 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5396 pic16_outBitAcc(result);
5399 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5400 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5401 pic16_freeAsmop(result,NULL,ic,TRUE);
5404 /*-----------------------------------------------------------------*/
5405 /* isLiteralBit - test if lit == 2^n */
5406 /*-----------------------------------------------------------------*/
5407 static int isLiteralBit(unsigned long lit)
5409 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5410 0x100L,0x200L,0x400L,0x800L,
5411 0x1000L,0x2000L,0x4000L,0x8000L,
5412 0x10000L,0x20000L,0x40000L,0x80000L,
5413 0x100000L,0x200000L,0x400000L,0x800000L,
5414 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5415 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5418 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5419 for(idx = 0; idx < 32; idx++)
5425 /*-----------------------------------------------------------------*/
5426 /* continueIfTrue - */
5427 /*-----------------------------------------------------------------*/
5428 static void continueIfTrue (iCode *ic)
5430 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5432 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5436 /*-----------------------------------------------------------------*/
5438 /*-----------------------------------------------------------------*/
5439 static void jumpIfTrue (iCode *ic)
5441 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5443 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5447 /*-----------------------------------------------------------------*/
5448 /* jmpTrueOrFalse - */
5449 /*-----------------------------------------------------------------*/
5450 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5452 // ugly but optimized by peephole
5453 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5455 symbol *nlbl = newiTempLabel(NULL);
5456 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5457 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5458 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5459 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5462 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5463 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5468 /*-----------------------------------------------------------------*/
5469 /* genAnd - code for and */
5470 /*-----------------------------------------------------------------*/
5471 static void genAnd (iCode *ic, iCode *ifx)
5473 operand *left, *right, *result;
5475 unsigned long lit = 0L;
5480 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5481 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5482 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5483 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5485 resolveIfx(&rIfx,ifx);
5487 /* if left is a literal & right is not then exchange them */
5488 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5489 AOP_NEEDSACC(left)) {
5490 operand *tmp = right ;
5495 /* if result = right then exchange them */
5496 if(pic16_sameRegs(AOP(result),AOP(right))){
5497 operand *tmp = right ;
5502 /* if right is bit then exchange them */
5503 if (AOP_TYPE(right) == AOP_CRY &&
5504 AOP_TYPE(left) != AOP_CRY){
5505 operand *tmp = right ;
5509 if(AOP_TYPE(right) == AOP_LIT)
5510 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5512 size = AOP_SIZE(result);
5514 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5517 // result = bit & yy;
5518 if (AOP_TYPE(left) == AOP_CRY){
5519 // c = bit & literal;
5520 if(AOP_TYPE(right) == AOP_LIT){
5522 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5525 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5528 if(size && (AOP_TYPE(result) == AOP_CRY)){
5529 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5532 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5536 pic16_emitcode("clr","c");
5539 if (AOP_TYPE(right) == AOP_CRY){
5541 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5542 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5545 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5547 pic16_emitcode("rrc","a");
5548 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5554 pic16_outBitC(result);
5556 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5557 genIfxJump(ifx, "c");
5561 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5562 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5563 if((AOP_TYPE(right) == AOP_LIT) &&
5564 (AOP_TYPE(result) == AOP_CRY) &&
5565 (AOP_TYPE(left) != AOP_CRY)){
5566 int posbit = isLiteralBit(lit);
5570 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5573 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5579 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5580 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5582 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5583 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5586 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5587 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5588 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5595 symbol *tlbl = newiTempLabel(NULL);
5596 int sizel = AOP_SIZE(left);
5598 pic16_emitcode("setb","c");
5600 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5601 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5603 if((posbit = isLiteralBit(bytelit)) != 0)
5604 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5606 if(bytelit != 0x0FFL)
5607 pic16_emitcode("anl","a,%s",
5608 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5609 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5614 // bit = left & literal
5616 pic16_emitcode("clr","c");
5617 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5619 // if(left & literal)
5622 jmpTrueOrFalse(ifx, tlbl);
5626 pic16_outBitC(result);
5630 /* if left is same as result */
5631 if(pic16_sameRegs(AOP(result),AOP(left))){
5633 for(;size--; offset++,lit>>=8) {
5634 if(AOP_TYPE(right) == AOP_LIT){
5635 switch(lit & 0xff) {
5637 /* and'ing with 0 has clears the result */
5638 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5639 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5642 /* and'ing with 0xff is a nop when the result and left are the same */
5647 int p = my_powof2( (~lit) & 0xff );
5649 /* only one bit is set in the literal, so use a bcf instruction */
5650 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5651 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5654 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5655 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5656 if(know_W != (lit&0xff))
5657 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5659 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5664 if (AOP_TYPE(left) == AOP_ACC) {
5665 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5667 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5668 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5675 // left & result in different registers
5676 if(AOP_TYPE(result) == AOP_CRY){
5678 // if(size), result in bit
5679 // if(!size && ifx), conditional oper: if(left & right)
5680 symbol *tlbl = newiTempLabel(NULL);
5681 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5683 pic16_emitcode("setb","c");
5685 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5686 pic16_emitcode("anl","a,%s",
5687 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5688 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5693 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5694 pic16_outBitC(result);
5696 jmpTrueOrFalse(ifx, tlbl);
5698 for(;(size--);offset++) {
5700 // result = left & right
5701 if(AOP_TYPE(right) == AOP_LIT){
5702 int t = (lit >> (offset*8)) & 0x0FFL;
5705 pic16_emitcode("clrf","%s",
5706 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5707 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5710 pic16_emitcode("movf","%s,w",
5711 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5712 pic16_emitcode("movwf","%s",
5713 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5714 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5715 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5718 pic16_emitcode("movlw","0x%x",t);
5719 pic16_emitcode("andwf","%s,w",
5720 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5721 pic16_emitcode("movwf","%s",
5722 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5724 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5725 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5726 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5731 if (AOP_TYPE(left) == AOP_ACC) {
5732 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5733 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5735 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5736 pic16_emitcode("andwf","%s,w",
5737 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5738 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5739 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5741 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5742 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5748 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5749 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5750 pic16_freeAsmop(result,NULL,ic,TRUE);
5753 /*-----------------------------------------------------------------*/
5754 /* genOr - code for or */
5755 /*-----------------------------------------------------------------*/
5756 static void genOr (iCode *ic, iCode *ifx)
5758 operand *left, *right, *result;
5760 unsigned long lit = 0L;
5762 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5764 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5765 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5766 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5768 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5770 /* if left is a literal & right is not then exchange them */
5771 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5772 AOP_NEEDSACC(left)) {
5773 operand *tmp = right ;
5778 /* if result = right then exchange them */
5779 if(pic16_sameRegs(AOP(result),AOP(right))){
5780 operand *tmp = right ;
5785 /* if right is bit then exchange them */
5786 if (AOP_TYPE(right) == AOP_CRY &&
5787 AOP_TYPE(left) != AOP_CRY){
5788 operand *tmp = right ;
5793 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5795 if(AOP_TYPE(right) == AOP_LIT)
5796 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5798 size = AOP_SIZE(result);
5802 if (AOP_TYPE(left) == AOP_CRY){
5803 if(AOP_TYPE(right) == AOP_LIT){
5804 // c = bit & literal;
5806 // lit != 0 => result = 1
5807 if(AOP_TYPE(result) == AOP_CRY){
5809 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5810 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5811 // AOP(result)->aopu.aop_dir,
5812 // AOP(result)->aopu.aop_dir);
5814 continueIfTrue(ifx);
5818 // lit == 0 => result = left
5819 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5821 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5824 if (AOP_TYPE(right) == AOP_CRY){
5825 if(pic16_sameRegs(AOP(result),AOP(left))){
5827 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5828 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5829 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5831 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5832 AOP(result)->aopu.aop_dir,
5833 AOP(result)->aopu.aop_dir);
5834 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5835 AOP(right)->aopu.aop_dir,
5836 AOP(right)->aopu.aop_dir);
5837 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5838 AOP(result)->aopu.aop_dir,
5839 AOP(result)->aopu.aop_dir);
5841 if( AOP_TYPE(result) == AOP_ACC) {
5842 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5843 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5844 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5845 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5849 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5850 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5851 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5852 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5854 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5855 AOP(result)->aopu.aop_dir,
5856 AOP(result)->aopu.aop_dir);
5857 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5858 AOP(right)->aopu.aop_dir,
5859 AOP(right)->aopu.aop_dir);
5860 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5861 AOP(left)->aopu.aop_dir,
5862 AOP(left)->aopu.aop_dir);
5863 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5864 AOP(result)->aopu.aop_dir,
5865 AOP(result)->aopu.aop_dir);
5870 symbol *tlbl = newiTempLabel(NULL);
5871 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5874 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5875 if( AOP_TYPE(right) == AOP_ACC) {
5876 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5878 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5879 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5884 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5885 pic16_emitcode(";XXX setb","c");
5886 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5887 AOP(left)->aopu.aop_dir,tlbl->key+100);
5888 pic16_toBoolean(right);
5889 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5890 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5891 jmpTrueOrFalse(ifx, tlbl);
5895 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5902 pic16_outBitC(result);
5904 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5905 genIfxJump(ifx, "c");
5909 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5910 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5911 if((AOP_TYPE(right) == AOP_LIT) &&
5912 (AOP_TYPE(result) == AOP_CRY) &&
5913 (AOP_TYPE(left) != AOP_CRY)){
5915 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5918 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5920 continueIfTrue(ifx);
5923 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5924 // lit = 0, result = boolean(left)
5926 pic16_emitcode(";XXX setb","c");
5927 pic16_toBoolean(right);
5929 symbol *tlbl = newiTempLabel(NULL);
5930 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5932 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5934 genIfxJump (ifx,"a");
5938 pic16_outBitC(result);
5942 /* if left is same as result */
5943 if(pic16_sameRegs(AOP(result),AOP(left))){
5945 for(;size--; offset++,lit>>=8) {
5946 if(AOP_TYPE(right) == AOP_LIT){
5947 if((lit & 0xff) == 0)
5948 /* or'ing with 0 has no effect */
5951 int p = my_powof2(lit & 0xff);
5953 /* only one bit is set in the literal, so use a bsf instruction */
5954 pic16_emitpcode(POC_BSF,
5955 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5957 if(know_W != (lit & 0xff))
5958 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5959 know_W = lit & 0xff;
5960 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5965 if (AOP_TYPE(left) == AOP_ACC) {
5966 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5967 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5969 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5970 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5972 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5973 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5979 // left & result in different registers
5980 if(AOP_TYPE(result) == AOP_CRY){
5982 // if(size), result in bit
5983 // if(!size && ifx), conditional oper: if(left | right)
5984 symbol *tlbl = newiTempLabel(NULL);
5985 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5986 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5990 pic16_emitcode(";XXX setb","c");
5992 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5993 pic16_emitcode(";XXX orl","a,%s",
5994 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5995 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6000 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6001 pic16_outBitC(result);
6003 jmpTrueOrFalse(ifx, tlbl);
6004 } else for(;(size--);offset++){
6006 // result = left & right
6007 if(AOP_TYPE(right) == AOP_LIT){
6008 int t = (lit >> (offset*8)) & 0x0FFL;
6011 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6012 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6014 pic16_emitcode("movf","%s,w",
6015 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6016 pic16_emitcode("movwf","%s",
6017 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6020 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6021 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6022 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6024 pic16_emitcode("movlw","0x%x",t);
6025 pic16_emitcode("iorwf","%s,w",
6026 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6027 pic16_emitcode("movwf","%s",
6028 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6034 // faster than result <- left, anl result,right
6035 // and better if result is SFR
6036 if (AOP_TYPE(left) == AOP_ACC) {
6037 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6038 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6040 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6041 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6043 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6044 pic16_emitcode("iorwf","%s,w",
6045 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6047 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6048 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6053 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6054 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6055 pic16_freeAsmop(result,NULL,ic,TRUE);
6058 /*-----------------------------------------------------------------*/
6059 /* genXor - code for xclusive or */
6060 /*-----------------------------------------------------------------*/
6061 static void genXor (iCode *ic, iCode *ifx)
6063 operand *left, *right, *result;
6065 unsigned long lit = 0L;
6067 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6069 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6070 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6071 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6073 /* if left is a literal & right is not ||
6074 if left needs acc & right does not */
6075 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6076 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6077 operand *tmp = right ;
6082 /* if result = right then exchange them */
6083 if(pic16_sameRegs(AOP(result),AOP(right))){
6084 operand *tmp = right ;
6089 /* if right is bit then exchange them */
6090 if (AOP_TYPE(right) == AOP_CRY &&
6091 AOP_TYPE(left) != AOP_CRY){
6092 operand *tmp = right ;
6096 if(AOP_TYPE(right) == AOP_LIT)
6097 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6099 size = AOP_SIZE(result);
6103 if (AOP_TYPE(left) == AOP_CRY){
6104 if(AOP_TYPE(right) == AOP_LIT){
6105 // c = bit & literal;
6107 // lit>>1 != 0 => result = 1
6108 if(AOP_TYPE(result) == AOP_CRY){
6110 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6111 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6113 continueIfTrue(ifx);
6116 pic16_emitcode("setb","c");
6120 // lit == 0, result = left
6121 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6123 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6125 // lit == 1, result = not(left)
6126 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6127 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6128 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6129 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6132 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6133 pic16_emitcode("cpl","c");
6140 symbol *tlbl = newiTempLabel(NULL);
6141 if (AOP_TYPE(right) == AOP_CRY){
6143 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6146 int sizer = AOP_SIZE(right);
6148 // if val>>1 != 0, result = 1
6149 pic16_emitcode("setb","c");
6151 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6153 // test the msb of the lsb
6154 pic16_emitcode("anl","a,#0xfe");
6155 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6159 pic16_emitcode("rrc","a");
6161 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6162 pic16_emitcode("cpl","c");
6163 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6168 pic16_outBitC(result);
6170 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6171 genIfxJump(ifx, "c");
6175 if(pic16_sameRegs(AOP(result),AOP(left))){
6176 /* if left is same as result */
6177 for(;size--; offset++) {
6178 if(AOP_TYPE(right) == AOP_LIT){
6179 int t = (lit >> (offset*8)) & 0x0FFL;
6183 if (IS_AOP_PREG(left)) {
6184 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6185 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6186 pic16_aopPut(AOP(result),"a",offset);
6188 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6189 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6190 pic16_emitcode("xrl","%s,%s",
6191 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6192 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6195 if (AOP_TYPE(left) == AOP_ACC)
6196 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6198 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6199 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6201 if (IS_AOP_PREG(left)) {
6202 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6203 pic16_aopPut(AOP(result),"a",offset);
6205 pic16_emitcode("xrl","%s,a",
6206 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6212 // left & result in different registers
6213 if(AOP_TYPE(result) == AOP_CRY){
6215 // if(size), result in bit
6216 // if(!size && ifx), conditional oper: if(left ^ right)
6217 symbol *tlbl = newiTempLabel(NULL);
6218 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6220 pic16_emitcode("setb","c");
6222 if((AOP_TYPE(right) == AOP_LIT) &&
6223 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6224 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6226 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6227 pic16_emitcode("xrl","a,%s",
6228 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6230 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6235 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6236 pic16_outBitC(result);
6238 jmpTrueOrFalse(ifx, tlbl);
6239 } else for(;(size--);offset++){
6241 // result = left & right
6242 if(AOP_TYPE(right) == AOP_LIT){
6243 int t = (lit >> (offset*8)) & 0x0FFL;
6246 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6247 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6248 pic16_emitcode("movf","%s,w",
6249 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6250 pic16_emitcode("movwf","%s",
6251 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6254 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6255 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6256 pic16_emitcode("comf","%s,w",
6257 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6258 pic16_emitcode("movwf","%s",
6259 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6262 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6263 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6264 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6265 pic16_emitcode("movlw","0x%x",t);
6266 pic16_emitcode("xorwf","%s,w",
6267 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6268 pic16_emitcode("movwf","%s",
6269 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6275 // faster than result <- left, anl result,right
6276 // and better if result is SFR
6277 if (AOP_TYPE(left) == AOP_ACC) {
6278 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6279 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6281 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6282 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6283 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6284 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6286 if ( AOP_TYPE(result) != AOP_ACC){
6287 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6288 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6294 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6295 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6296 pic16_freeAsmop(result,NULL,ic,TRUE);
6299 /*-----------------------------------------------------------------*/
6300 /* genInline - write the inline code out */
6301 /*-----------------------------------------------------------------*/
6302 static void genInline (iCode *ic)
6304 char *buffer, *bp, *bp1;
6306 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6308 _G.inLine += (!options.asmpeep);
6310 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6311 strcpy(buffer,IC_INLINE(ic));
6313 /* emit each line as a code */
6319 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6320 // inline directly, no process
6327 pic16_emitcode(bp1,"");
6333 if ((bp1 != bp) && *bp1)
6334 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6338 _G.inLine -= (!options.asmpeep);
6341 /*-----------------------------------------------------------------*/
6342 /* genRRC - rotate right with carry */
6343 /*-----------------------------------------------------------------*/
6344 static void genRRC (iCode *ic)
6346 operand *left , *result ;
6347 int size, offset = 0, same;
6349 /* rotate right with carry */
6351 result=IC_RESULT(ic);
6352 pic16_aopOp (left,ic,FALSE);
6353 pic16_aopOp (result,ic,FALSE);
6355 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6357 same = pic16_sameRegs(AOP(result),AOP(left));
6359 size = AOP_SIZE(result);
6361 /* get the lsb and put it into the carry */
6362 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6369 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6371 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6372 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6378 pic16_freeAsmop(left,NULL,ic,TRUE);
6379 pic16_freeAsmop(result,NULL,ic,TRUE);
6382 /*-----------------------------------------------------------------*/
6383 /* genRLC - generate code for rotate left with carry */
6384 /*-----------------------------------------------------------------*/
6385 static void genRLC (iCode *ic)
6387 operand *left , *result ;
6388 int size, offset = 0;
6391 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6392 /* rotate right with carry */
6394 result=IC_RESULT(ic);
6395 pic16_aopOp (left,ic,FALSE);
6396 pic16_aopOp (result,ic,FALSE);
6398 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6400 same = pic16_sameRegs(AOP(result),AOP(left));
6402 /* move it to the result */
6403 size = AOP_SIZE(result);
6405 /* get the msb and put it into the carry */
6406 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6413 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6415 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6416 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6423 pic16_freeAsmop(left,NULL,ic,TRUE);
6424 pic16_freeAsmop(result,NULL,ic,TRUE);
6427 /*-----------------------------------------------------------------*/
6428 /* genGetHbit - generates code get highest order bit */
6429 /*-----------------------------------------------------------------*/
6430 static void genGetHbit (iCode *ic)
6432 operand *left, *result;
6434 result=IC_RESULT(ic);
6435 pic16_aopOp (left,ic,FALSE);
6436 pic16_aopOp (result,ic,FALSE);
6438 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6439 /* get the highest order byte into a */
6440 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6441 if(AOP_TYPE(result) == AOP_CRY){
6442 pic16_emitcode("rlc","a");
6443 pic16_outBitC(result);
6446 pic16_emitcode("rl","a");
6447 pic16_emitcode("anl","a,#0x01");
6448 pic16_outAcc(result);
6452 pic16_freeAsmop(left,NULL,ic,TRUE);
6453 pic16_freeAsmop(result,NULL,ic,TRUE);
6456 /*-----------------------------------------------------------------*/
6457 /* AccRol - rotate left accumulator by known count */
6458 /*-----------------------------------------------------------------*/
6459 static void AccRol (int shCount)
6461 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6462 shCount &= 0x0007; // shCount : 0..7
6467 pic16_emitcode("rl","a");
6470 pic16_emitcode("rl","a");
6471 pic16_emitcode("rl","a");
6474 pic16_emitcode("swap","a");
6475 pic16_emitcode("rr","a");
6478 pic16_emitcode("swap","a");
6481 pic16_emitcode("swap","a");
6482 pic16_emitcode("rl","a");
6485 pic16_emitcode("rr","a");
6486 pic16_emitcode("rr","a");
6489 pic16_emitcode("rr","a");
6494 /*-----------------------------------------------------------------*/
6495 /* AccLsh - left shift accumulator by known count */
6496 /*-----------------------------------------------------------------*/
6497 static void AccLsh (int shCount)
6499 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6502 pic16_emitcode("add","a,acc");
6505 pic16_emitcode("add","a,acc");
6506 pic16_emitcode("add","a,acc");
6508 /* rotate left accumulator */
6510 /* and kill the lower order bits */
6511 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6516 /*-----------------------------------------------------------------*/
6517 /* AccRsh - right shift accumulator by known count */
6518 /*-----------------------------------------------------------------*/
6519 static void AccRsh (int shCount)
6521 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6525 pic16_emitcode("rrc","a");
6527 /* rotate right accumulator */
6528 AccRol(8 - shCount);
6529 /* and kill the higher order bits */
6530 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6536 /*-----------------------------------------------------------------*/
6537 /* AccSRsh - signed right shift accumulator by known count */
6538 /*-----------------------------------------------------------------*/
6539 static void AccSRsh (int shCount)
6542 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6545 pic16_emitcode("mov","c,acc.7");
6546 pic16_emitcode("rrc","a");
6547 } else if(shCount == 2){
6548 pic16_emitcode("mov","c,acc.7");
6549 pic16_emitcode("rrc","a");
6550 pic16_emitcode("mov","c,acc.7");
6551 pic16_emitcode("rrc","a");
6553 tlbl = newiTempLabel(NULL);
6554 /* rotate right accumulator */
6555 AccRol(8 - shCount);
6556 /* and kill the higher order bits */
6557 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6558 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6559 pic16_emitcode("orl","a,#0x%02x",
6560 (unsigned char)~SRMask[shCount]);
6561 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6566 /*-----------------------------------------------------------------*/
6567 /* shiftR1Left2Result - shift right one byte from left to result */
6568 /*-----------------------------------------------------------------*/
6569 static void shiftR1Left2ResultSigned (operand *left, int offl,
6570 operand *result, int offr,
6575 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6577 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6581 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6583 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6585 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6586 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6592 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6594 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6596 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6597 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6599 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6600 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6606 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6608 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6609 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6612 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6613 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6614 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6616 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6617 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6619 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6623 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6624 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6625 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6626 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6627 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6631 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6633 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6634 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6636 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6637 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6638 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6639 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6640 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6645 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6646 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6647 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6648 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6649 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6650 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6652 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6653 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6654 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6655 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6656 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6662 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6663 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6664 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6665 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6667 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6668 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6669 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6677 /*-----------------------------------------------------------------*/
6678 /* shiftR1Left2Result - shift right one byte from left to result */
6679 /*-----------------------------------------------------------------*/
6680 static void shiftR1Left2Result (operand *left, int offl,
6681 operand *result, int offr,
6682 int shCount, int sign)
6686 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6688 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6690 /* Copy the msb into the carry if signed. */
6692 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6702 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6704 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6705 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6711 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6713 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6714 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6717 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6722 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6724 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6725 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6728 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6729 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6730 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6731 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6735 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6736 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6737 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6741 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6742 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6743 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6745 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6750 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6751 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6752 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6753 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6754 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6759 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6760 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6761 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6770 /*-----------------------------------------------------------------*/
6771 /* shiftL1Left2Result - shift left one byte from left to result */
6772 /*-----------------------------------------------------------------*/
6773 static void shiftL1Left2Result (operand *left, int offl,
6774 operand *result, int offr, int shCount)
6779 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6781 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6782 DEBUGpic16_emitcode ("; ***","same = %d",same);
6783 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6785 /* shift left accumulator */
6786 //AccLsh(shCount); // don't comment out just yet...
6787 // pic16_aopPut(AOP(result),"a",offr);
6791 /* Shift left 1 bit position */
6792 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6794 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6796 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6797 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6801 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6802 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6803 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6804 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6807 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6808 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6809 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6810 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6811 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6814 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6815 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6816 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6819 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6820 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6821 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6822 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6825 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6826 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6827 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6828 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6829 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6832 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6833 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6834 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6838 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6843 /*-----------------------------------------------------------------*/
6844 /* movLeft2Result - move byte from left to result */
6845 /*-----------------------------------------------------------------*/
6846 static void movLeft2Result (operand *left, int offl,
6847 operand *result, int offr)
6850 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6851 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6852 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6854 if (*l == '@' && (IS_AOP_PREG(result))) {
6855 pic16_emitcode("mov","a,%s",l);
6856 pic16_aopPut(AOP(result),"a",offr);
6858 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6859 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6864 /*-----------------------------------------------------------------*/
6865 /* shiftL2Left2Result - shift left two bytes from left to result */
6866 /*-----------------------------------------------------------------*/
6867 static void shiftL2Left2Result (operand *left, int offl,
6868 operand *result, int offr, int shCount)
6872 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6874 if(pic16_sameRegs(AOP(result), AOP(left))) {
6882 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6883 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6884 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6888 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6889 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6895 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6896 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6897 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6898 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6899 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6900 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6901 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6903 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6904 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6908 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6909 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6910 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6911 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6912 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6913 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6914 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6915 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6916 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6917 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6920 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6921 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6922 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6923 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6924 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6934 /* note, use a mov/add for the shift since the mov has a
6935 chance of getting optimized out */
6936 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6937 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6938 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6939 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6940 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6944 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6945 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6951 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6952 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6953 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6954 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6955 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6956 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6957 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6958 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6962 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6963 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6967 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6968 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6969 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6970 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6972 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6973 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6974 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6975 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6976 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6977 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6978 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6979 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6982 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6983 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6984 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6985 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6986 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6991 /*-----------------------------------------------------------------*/
6992 /* shiftR2Left2Result - shift right two bytes from left to result */
6993 /*-----------------------------------------------------------------*/
6994 static void shiftR2Left2Result (operand *left, int offl,
6995 operand *result, int offr,
6996 int shCount, int sign)
7000 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7001 same = pic16_sameRegs(AOP(result), AOP(left));
7003 if(same && ((offl + MSB16) == offr)){
7005 /* don't crash result[offr] */
7006 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
7007 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
7010 movLeft2Result(left,offl, result, offr);
7011 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
7014 /* a:x >> shCount (x = lsb(result))*/
7017 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
7019 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
7028 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7033 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7034 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7036 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7037 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7038 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7039 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7044 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7047 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7048 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7055 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7056 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7057 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7059 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7060 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7061 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7062 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7064 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7065 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7066 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7068 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7069 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7070 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7071 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7072 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7076 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7077 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7081 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7082 pic16_emitpcode(POC_BTFSC,
7083 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7084 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7092 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7093 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7095 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7096 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7097 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7098 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7100 pic16_emitpcode(POC_BTFSC,
7101 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7102 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7104 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7105 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7106 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7107 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7109 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7110 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7111 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7112 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7113 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7114 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7115 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7116 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7118 pic16_emitpcode(POC_BTFSC,
7119 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7120 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7122 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7123 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7130 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7131 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7132 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7133 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7136 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7138 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7143 /*-----------------------------------------------------------------*/
7144 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7145 /*-----------------------------------------------------------------*/
7146 static void shiftLLeftOrResult (operand *left, int offl,
7147 operand *result, int offr, int shCount)
7149 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7150 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
7151 /* shift left accumulator */
7153 /* or with result */
7154 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
7155 /* back to result */
7156 pic16_aopPut(AOP(result),"a",offr);
7159 /*-----------------------------------------------------------------*/
7160 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7161 /*-----------------------------------------------------------------*/
7162 static void shiftRLeftOrResult (operand *left, int offl,
7163 operand *result, int offr, int shCount)
7165 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7166 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
7167 /* shift right accumulator */
7169 /* or with result */
7170 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
7171 /* back to result */
7172 pic16_aopPut(AOP(result),"a",offr);
7175 /*-----------------------------------------------------------------*/
7176 /* genlshOne - left shift a one byte quantity by known count */
7177 /*-----------------------------------------------------------------*/
7178 static void genlshOne (operand *result, operand *left, int shCount)
7180 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7181 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7184 /*-----------------------------------------------------------------*/
7185 /* genlshTwo - left shift two bytes by known amount != 0 */
7186 /*-----------------------------------------------------------------*/
7187 static void genlshTwo (operand *result,operand *left, int shCount)
7191 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7192 size = pic16_getDataSize(result);
7194 /* if shCount >= 8 */
7200 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7202 movLeft2Result(left, LSB, result, MSB16);
7204 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7207 /* 1 <= shCount <= 7 */
7210 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7212 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7216 /*-----------------------------------------------------------------*/
7217 /* shiftLLong - shift left one long from left to result */
7218 /* offl = LSB or MSB16 */
7219 /*-----------------------------------------------------------------*/
7220 static void shiftLLong (operand *left, operand *result, int offr )
7223 int size = AOP_SIZE(result);
7225 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7226 if(size >= LSB+offr){
7227 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7229 pic16_emitcode("add","a,acc");
7230 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7231 size >= MSB16+offr && offr != LSB )
7232 pic16_emitcode("xch","a,%s",
7233 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7235 pic16_aopPut(AOP(result),"a",LSB+offr);
7238 if(size >= MSB16+offr){
7239 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7240 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7243 pic16_emitcode("rlc","a");
7244 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7245 size >= MSB24+offr && offr != LSB)
7246 pic16_emitcode("xch","a,%s",
7247 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7249 pic16_aopPut(AOP(result),"a",MSB16+offr);
7252 if(size >= MSB24+offr){
7253 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7254 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7257 pic16_emitcode("rlc","a");
7258 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7259 size >= MSB32+offr && offr != LSB )
7260 pic16_emitcode("xch","a,%s",
7261 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7263 pic16_aopPut(AOP(result),"a",MSB24+offr);
7266 if(size > MSB32+offr){
7267 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7268 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7271 pic16_emitcode("rlc","a");
7272 pic16_aopPut(AOP(result),"a",MSB32+offr);
7275 pic16_aopPut(AOP(result),zero,LSB);
7278 /*-----------------------------------------------------------------*/
7279 /* genlshFour - shift four byte by a known amount != 0 */
7280 /*-----------------------------------------------------------------*/
7281 static void genlshFour (operand *result, operand *left, int shCount)
7285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7286 size = AOP_SIZE(result);
7288 /* if shifting more that 3 bytes */
7289 if (shCount >= 24 ) {
7292 /* lowest order of left goes to the highest
7293 order of the destination */
7294 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7296 movLeft2Result(left, LSB, result, MSB32);
7297 pic16_aopPut(AOP(result),zero,LSB);
7298 pic16_aopPut(AOP(result),zero,MSB16);
7299 pic16_aopPut(AOP(result),zero,MSB32);
7303 /* more than two bytes */
7304 else if ( shCount >= 16 ) {
7305 /* lower order two bytes goes to higher order two bytes */
7307 /* if some more remaining */
7309 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7311 movLeft2Result(left, MSB16, result, MSB32);
7312 movLeft2Result(left, LSB, result, MSB24);
7314 pic16_aopPut(AOP(result),zero,MSB16);
7315 pic16_aopPut(AOP(result),zero,LSB);
7319 /* if more than 1 byte */
7320 else if ( shCount >= 8 ) {
7321 /* lower order three bytes goes to higher order three bytes */
7325 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7327 movLeft2Result(left, LSB, result, MSB16);
7329 else{ /* size = 4 */
7331 movLeft2Result(left, MSB24, result, MSB32);
7332 movLeft2Result(left, MSB16, result, MSB24);
7333 movLeft2Result(left, LSB, result, MSB16);
7334 pic16_aopPut(AOP(result),zero,LSB);
7336 else if(shCount == 1)
7337 shiftLLong(left, result, MSB16);
7339 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7340 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7341 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7342 pic16_aopPut(AOP(result),zero,LSB);
7347 /* 1 <= shCount <= 7 */
7348 else if(shCount <= 2){
7349 shiftLLong(left, result, LSB);
7351 shiftLLong(result, result, LSB);
7353 /* 3 <= shCount <= 7, optimize */
7355 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7356 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7357 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7361 /*-----------------------------------------------------------------*/
7362 /* genLeftShiftLiteral - left shifting by known count */
7363 /*-----------------------------------------------------------------*/
7364 static void genLeftShiftLiteral (operand *left,
7369 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7372 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7373 pic16_freeAsmop(right,NULL,ic,TRUE);
7375 pic16_aopOp(left,ic,FALSE);
7376 pic16_aopOp(result,ic,FALSE);
7378 size = getSize(operandType(result));
7381 pic16_emitcode("; shift left ","result %d, left %d",size,
7385 /* I suppose that the left size >= result size */
7388 movLeft2Result(left, size, result, size);
7392 else if(shCount >= (size * 8))
7394 pic16_aopPut(AOP(result),zero,size);
7398 genlshOne (result,left,shCount);
7403 genlshTwo (result,left,shCount);
7407 genlshFour (result,left,shCount);
7411 pic16_freeAsmop(left,NULL,ic,TRUE);
7412 pic16_freeAsmop(result,NULL,ic,TRUE);
7415 /*-----------------------------------------------------------------*
7416 * genMultiAsm - repeat assembly instruction for size of register.
7417 * if endian == 1, then the high byte (i.e base address + size of
7418 * register) is used first else the low byte is used first;
7419 *-----------------------------------------------------------------*/
7420 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7425 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7438 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7443 /*-----------------------------------------------------------------*/
7444 /* genLeftShift - generates code for left shifting */
7445 /*-----------------------------------------------------------------*/
7446 static void genLeftShift (iCode *ic)
7448 operand *left,*right, *result;
7451 symbol *tlbl , *tlbl1;
7454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7456 right = IC_RIGHT(ic);
7458 result = IC_RESULT(ic);
7460 pic16_aopOp(right,ic,FALSE);
7462 /* if the shift count is known then do it
7463 as efficiently as possible */
7464 if (AOP_TYPE(right) == AOP_LIT) {
7465 genLeftShiftLiteral (left,right,result,ic);
7469 /* shift count is unknown then we have to form
7470 a loop get the loop count in B : Note: we take
7471 only the lower order byte since shifting
7472 more that 32 bits make no sense anyway, ( the
7473 largest size of an object can be only 32 bits ) */
7476 pic16_aopOp(left,ic,FALSE);
7477 pic16_aopOp(result,ic,FALSE);
7479 /* now move the left to the result if they are not the
7481 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7482 AOP_SIZE(result) > 1) {
7484 size = AOP_SIZE(result);
7487 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7488 if (*l == '@' && (IS_AOP_PREG(result))) {
7490 pic16_emitcode("mov","a,%s",l);
7491 pic16_aopPut(AOP(result),"a",offset);
7493 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7494 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7495 //pic16_aopPut(AOP(result),l,offset);
7501 size = AOP_SIZE(result);
7503 /* if it is only one byte then */
7505 if(optimized_for_speed) {
7506 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7507 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7508 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7509 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7510 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7511 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7512 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7513 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7514 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7515 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7516 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7517 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7520 tlbl = newiTempLabel(NULL);
7521 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7522 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7523 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7526 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7527 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7528 pic16_emitpLabel(tlbl->key);
7529 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7530 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7532 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7537 if (pic16_sameRegs(AOP(left),AOP(result))) {
7539 tlbl = newiTempLabel(NULL);
7540 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7541 genMultiAsm(POC_RRCF, result, size,1);
7542 pic16_emitpLabel(tlbl->key);
7543 genMultiAsm(POC_RLCF, result, size,0);
7544 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7546 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7550 //tlbl = newiTempLabel(NULL);
7552 //tlbl1 = newiTempLabel(NULL);
7554 //reAdjustPreg(AOP(result));
7556 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7557 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7558 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7560 //pic16_emitcode("add","a,acc");
7561 //pic16_aopPut(AOP(result),"a",offset++);
7563 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7565 // pic16_emitcode("rlc","a");
7566 // pic16_aopPut(AOP(result),"a",offset++);
7568 //reAdjustPreg(AOP(result));
7570 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7571 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7574 tlbl = newiTempLabel(NULL);
7575 tlbl1= newiTempLabel(NULL);
7577 size = AOP_SIZE(result);
7580 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7582 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7584 /* offset should be 0, 1 or 3 */
7585 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7587 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7589 pic16_emitpcode(POC_MOVWF, pctemp);
7592 pic16_emitpLabel(tlbl->key);
7595 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7597 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7599 pic16_emitpcode(POC_DECFSZ, pctemp);
7600 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7601 pic16_emitpLabel(tlbl1->key);
7603 pic16_popReleaseTempReg(pctemp);
7607 pic16_freeAsmop (right,NULL,ic,TRUE);
7608 pic16_freeAsmop(left,NULL,ic,TRUE);
7609 pic16_freeAsmop(result,NULL,ic,TRUE);
7612 /*-----------------------------------------------------------------*/
7613 /* genrshOne - right shift a one byte quantity by known count */
7614 /*-----------------------------------------------------------------*/
7615 static void genrshOne (operand *result, operand *left,
7616 int shCount, int sign)
7618 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7619 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7622 /*-----------------------------------------------------------------*/
7623 /* genrshTwo - right shift two bytes by known amount != 0 */
7624 /*-----------------------------------------------------------------*/
7625 static void genrshTwo (operand *result,operand *left,
7626 int shCount, int sign)
7628 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7629 /* if shCount >= 8 */
7633 shiftR1Left2Result(left, MSB16, result, LSB,
7636 movLeft2Result(left, MSB16, result, LSB);
7638 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7641 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7642 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7646 /* 1 <= shCount <= 7 */
7648 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7651 /*-----------------------------------------------------------------*/
7652 /* shiftRLong - shift right one long from left to result */
7653 /* offl = LSB or MSB16 */
7654 /*-----------------------------------------------------------------*/
7655 static void shiftRLong (operand *left, int offl,
7656 operand *result, int sign)
7658 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7660 pic16_emitcode("clr","c");
7661 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7663 pic16_emitcode("mov","c,acc.7");
7664 pic16_emitcode("rrc","a");
7665 pic16_aopPut(AOP(result),"a",MSB32-offl);
7667 /* add sign of "a" */
7668 pic16_addSign(result, MSB32, sign);
7670 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7671 pic16_emitcode("rrc","a");
7672 pic16_aopPut(AOP(result),"a",MSB24-offl);
7674 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7675 pic16_emitcode("rrc","a");
7676 pic16_aopPut(AOP(result),"a",MSB16-offl);
7679 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7680 pic16_emitcode("rrc","a");
7681 pic16_aopPut(AOP(result),"a",LSB);
7685 /*-----------------------------------------------------------------*/
7686 /* genrshFour - shift four byte by a known amount != 0 */
7687 /*-----------------------------------------------------------------*/
7688 static void genrshFour (operand *result, operand *left,
7689 int shCount, int sign)
7691 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7692 /* if shifting more that 3 bytes */
7693 if(shCount >= 24 ) {
7696 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7698 movLeft2Result(left, MSB32, result, LSB);
7700 pic16_addSign(result, MSB16, sign);
7702 else if(shCount >= 16){
7705 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7707 movLeft2Result(left, MSB24, result, LSB);
7708 movLeft2Result(left, MSB32, result, MSB16);
7710 pic16_addSign(result, MSB24, sign);
7712 else if(shCount >= 8){
7715 shiftRLong(left, MSB16, result, sign);
7716 else if(shCount == 0){
7717 movLeft2Result(left, MSB16, result, LSB);
7718 movLeft2Result(left, MSB24, result, MSB16);
7719 movLeft2Result(left, MSB32, result, MSB24);
7720 pic16_addSign(result, MSB32, sign);
7723 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7724 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7725 /* the last shift is signed */
7726 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7727 pic16_addSign(result, MSB32, sign);
7730 else{ /* 1 <= shCount <= 7 */
7732 shiftRLong(left, LSB, result, sign);
7734 shiftRLong(result, LSB, result, sign);
7737 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7738 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7739 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7744 /*-----------------------------------------------------------------*/
7745 /* genRightShiftLiteral - right shifting by known count */
7746 /*-----------------------------------------------------------------*/
7747 static void genRightShiftLiteral (operand *left,
7753 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7756 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7757 pic16_freeAsmop(right,NULL,ic,TRUE);
7759 pic16_aopOp(left,ic,FALSE);
7760 pic16_aopOp(result,ic,FALSE);
7763 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7767 lsize = pic16_getDataSize(left);
7768 res_size = pic16_getDataSize(result);
7769 /* test the LEFT size !!! */
7771 /* I suppose that the left size >= result size */
7774 movLeft2Result(left, lsize, result, res_size);
7777 else if(shCount >= (lsize * 8)){
7780 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7782 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7783 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7788 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7789 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7790 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7792 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7797 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7804 genrshOne (result,left,shCount,sign);
7808 genrshTwo (result,left,shCount,sign);
7812 genrshFour (result,left,shCount,sign);
7820 pic16_freeAsmop(left,NULL,ic,TRUE);
7821 pic16_freeAsmop(result,NULL,ic,TRUE);
7824 /*-----------------------------------------------------------------*/
7825 /* genSignedRightShift - right shift of signed number */
7826 /*-----------------------------------------------------------------*/
7827 static void genSignedRightShift (iCode *ic)
7829 operand *right, *left, *result;
7832 symbol *tlbl, *tlbl1 ;
7835 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7837 /* we do it the hard way put the shift count in b
7838 and loop thru preserving the sign */
7839 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7841 right = IC_RIGHT(ic);
7843 result = IC_RESULT(ic);
7845 pic16_aopOp(right,ic,FALSE);
7846 pic16_aopOp(left,ic,FALSE);
7847 pic16_aopOp(result,ic,FALSE);
7850 if ( AOP_TYPE(right) == AOP_LIT) {
7851 genRightShiftLiteral (left,right,result,ic,1);
7854 /* shift count is unknown then we have to form
7855 a loop get the loop count in B : Note: we take
7856 only the lower order byte since shifting
7857 more that 32 bits make no sense anyway, ( the
7858 largest size of an object can be only 32 bits ) */
7860 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7861 //pic16_emitcode("inc","b");
7862 //pic16_freeAsmop (right,NULL,ic,TRUE);
7863 //pic16_aopOp(left,ic,FALSE);
7864 //pic16_aopOp(result,ic,FALSE);
7866 /* now move the left to the result if they are not the
7868 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7869 AOP_SIZE(result) > 1) {
7871 size = AOP_SIZE(result);
7875 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7876 if (*l == '@' && IS_AOP_PREG(result)) {
7878 pic16_emitcode("mov","a,%s",l);
7879 pic16_aopPut(AOP(result),"a",offset);
7881 pic16_aopPut(AOP(result),l,offset);
7883 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7884 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7890 /* mov the highest order bit to OVR */
7891 tlbl = newiTempLabel(NULL);
7892 tlbl1= newiTempLabel(NULL);
7894 size = AOP_SIZE(result);
7897 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7899 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7901 /* offset should be 0, 1 or 3 */
7902 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7904 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7906 pic16_emitpcode(POC_MOVWF, pctemp);
7909 pic16_emitpLabel(tlbl->key);
7911 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7912 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7915 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7918 pic16_emitpcode(POC_DECFSZ, pctemp);
7919 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7920 pic16_emitpLabel(tlbl1->key);
7922 pic16_popReleaseTempReg(pctemp);
7924 size = AOP_SIZE(result);
7926 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7927 pic16_emitcode("rlc","a");
7928 pic16_emitcode("mov","ov,c");
7929 /* if it is only one byte then */
7931 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7933 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7934 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7935 pic16_emitcode("mov","c,ov");
7936 pic16_emitcode("rrc","a");
7937 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7938 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7939 pic16_aopPut(AOP(result),"a",0);
7943 reAdjustPreg(AOP(result));
7944 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7945 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7946 pic16_emitcode("mov","c,ov");
7948 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7950 pic16_emitcode("rrc","a");
7951 pic16_aopPut(AOP(result),"a",offset--);
7953 reAdjustPreg(AOP(result));
7954 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7955 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7960 pic16_freeAsmop(left,NULL,ic,TRUE);
7961 pic16_freeAsmop(result,NULL,ic,TRUE);
7962 pic16_freeAsmop(right,NULL,ic,TRUE);
7965 /*-----------------------------------------------------------------*/
7966 /* genRightShift - generate code for right shifting */
7967 /*-----------------------------------------------------------------*/
7968 static void genRightShift (iCode *ic)
7970 operand *right, *left, *result;
7974 symbol *tlbl, *tlbl1 ;
7976 /* if signed then we do it the hard way preserve the
7977 sign bit moving it inwards */
7978 retype = getSpec(operandType(IC_RESULT(ic)));
7979 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7981 if (!SPEC_USIGN(retype)) {
7982 genSignedRightShift (ic);
7986 /* signed & unsigned types are treated the same : i.e. the
7987 signed is NOT propagated inwards : quoting from the
7988 ANSI - standard : "for E1 >> E2, is equivalent to division
7989 by 2**E2 if unsigned or if it has a non-negative value,
7990 otherwise the result is implementation defined ", MY definition
7991 is that the sign does not get propagated */
7993 right = IC_RIGHT(ic);
7995 result = IC_RESULT(ic);
7997 pic16_aopOp(right,ic,FALSE);
7999 /* if the shift count is known then do it
8000 as efficiently as possible */
8001 if (AOP_TYPE(right) == AOP_LIT) {
8002 genRightShiftLiteral (left,right,result,ic, 0);
8006 /* shift count is unknown then we have to form
8007 a loop get the loop count in B : Note: we take
8008 only the lower order byte since shifting
8009 more that 32 bits make no sense anyway, ( the
8010 largest size of an object can be only 32 bits ) */
8012 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8013 pic16_emitcode("inc","b");
8014 pic16_aopOp(left,ic,FALSE);
8015 pic16_aopOp(result,ic,FALSE);
8017 /* now move the left to the result if they are not the
8019 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8020 AOP_SIZE(result) > 1) {
8022 size = AOP_SIZE(result);
8025 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8026 if (*l == '@' && IS_AOP_PREG(result)) {
8028 pic16_emitcode("mov","a,%s",l);
8029 pic16_aopPut(AOP(result),"a",offset);
8031 pic16_aopPut(AOP(result),l,offset);
8036 tlbl = newiTempLabel(NULL);
8037 tlbl1= newiTempLabel(NULL);
8038 size = AOP_SIZE(result);
8041 /* if it is only one byte then */
8044 tlbl = newiTempLabel(NULL);
8045 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8046 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8047 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8050 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8051 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8052 pic16_emitpLabel(tlbl->key);
8053 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8054 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8056 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8061 reAdjustPreg(AOP(result));
8062 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8063 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8066 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8068 pic16_emitcode("rrc","a");
8069 pic16_aopPut(AOP(result),"a",offset--);
8071 reAdjustPreg(AOP(result));
8073 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8074 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8077 pic16_freeAsmop(left,NULL,ic,TRUE);
8078 pic16_freeAsmop (right,NULL,ic,TRUE);
8079 pic16_freeAsmop(result,NULL,ic,TRUE);
8082 /*-----------------------------------------------------------------*/
8083 /* genUnpackBits - generates code for unpacking bits */
8084 /*-----------------------------------------------------------------*/
8085 static void genUnpackBits (operand *result, char *rname, int ptype)
8092 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8093 etype = getSpec(operandType(result));
8095 /* read the first byte */
8100 pic16_emitcode("mov","a,@%s",rname);
8104 pic16_emitcode("movx","a,@%s",rname);
8108 pic16_emitcode("movx","a,@dptr");
8112 pic16_emitcode("clr","a");
8113 pic16_emitcode("movc","a","@a+dptr");
8117 pic16_emitcode("lcall","__gptrget");
8121 /* if we have bitdisplacement then it fits */
8122 /* into this byte completely or if length is */
8123 /* less than a byte */
8124 if ((shCnt = SPEC_BSTR(etype)) ||
8125 (SPEC_BLEN(etype) <= 8)) {
8127 /* shift right acc */
8130 pic16_emitcode("anl","a,#0x%02x",
8131 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8132 pic16_aopPut(AOP(result),"a",offset);
8136 /* bit field did not fit in a byte */
8137 rlen = SPEC_BLEN(etype) - 8;
8138 pic16_aopPut(AOP(result),"a",offset++);
8145 pic16_emitcode("inc","%s",rname);
8146 pic16_emitcode("mov","a,@%s",rname);
8150 pic16_emitcode("inc","%s",rname);
8151 pic16_emitcode("movx","a,@%s",rname);
8155 pic16_emitcode("inc","dptr");
8156 pic16_emitcode("movx","a,@dptr");
8160 pic16_emitcode("clr","a");
8161 pic16_emitcode("inc","dptr");
8162 pic16_emitcode("movc","a","@a+dptr");
8166 pic16_emitcode("inc","dptr");
8167 pic16_emitcode("lcall","__gptrget");
8172 /* if we are done */
8176 pic16_aopPut(AOP(result),"a",offset++);
8181 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8182 pic16_aopPut(AOP(result),"a",offset);
8189 /*-----------------------------------------------------------------*/
8190 /* genDataPointerGet - generates code when ptr offset is known */
8191 /*-----------------------------------------------------------------*/
8192 static void genDataPointerGet (operand *left,
8196 int size , offset = 0;
8199 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8202 /* optimization - most of the time, left and result are the same
8203 * address, but different types. for the pic code, we could omit
8207 pic16_aopOp(result,ic,TRUE);
8209 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8211 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8213 size = AOP_SIZE(result);
8216 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8220 pic16_freeAsmop(left,NULL,ic,TRUE);
8221 pic16_freeAsmop(result,NULL,ic,TRUE);
8224 /*-----------------------------------------------------------------*/
8225 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8226 /*-----------------------------------------------------------------*/
8227 static void genNearPointerGet (operand *left,
8232 //regs *preg = NULL ;
8234 sym_link *rtype, *retype;
8235 sym_link *ltype = operandType(left);
8238 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8240 rtype = operandType(result);
8241 retype= getSpec(rtype);
8243 pic16_aopOp(left,ic,FALSE);
8245 /* if left is rematerialisable and
8246 result is not bit variable type and
8247 the left is pointer to data space i.e
8248 lower 128 bytes of space */
8249 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8250 !IS_BITVAR(retype) &&
8251 DCL_TYPE(ltype) == POINTER) {
8252 //genDataPointerGet (left,result,ic);
8256 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8258 /* if the value is already in a pointer register
8259 then don't need anything more */
8260 if (!AOP_INPREG(AOP(left))) {
8261 /* otherwise get a free pointer register */
8262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8265 preg = getFreePtr(ic,&aop,FALSE);
8266 pic16_emitcode("mov","%s,%s",
8268 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8269 rname = preg->name ;
8273 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8275 pic16_aopOp (result,ic,FALSE);
8277 /* if bitfield then unpack the bits */
8278 if (IS_BITVAR(retype))
8279 genUnpackBits (result,rname,POINTER);
8281 /* we have can just get the values */
8282 int size = AOP_SIZE(result);
8285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8287 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8288 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8290 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8291 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8293 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8297 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8299 pic16_emitcode("mov","a,@%s",rname);
8300 pic16_aopPut(AOP(result),"a",offset);
8302 sprintf(buffer,"@%s",rname);
8303 pic16_aopPut(AOP(result),buffer,offset);
8307 pic16_emitcode("inc","%s",rname);
8312 /* now some housekeeping stuff */
8314 /* we had to allocate for this iCode */
8315 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8316 pic16_freeAsmop(NULL,aop,ic,TRUE);
8318 /* we did not allocate which means left
8319 already in a pointer register, then
8320 if size > 0 && this could be used again
8321 we have to point it back to where it
8323 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8324 if (AOP_SIZE(result) > 1 &&
8325 !OP_SYMBOL(left)->remat &&
8326 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8328 int size = AOP_SIZE(result) - 1;
8330 pic16_emitcode("dec","%s",rname);
8335 pic16_freeAsmop(left,NULL,ic,TRUE);
8336 pic16_freeAsmop(result,NULL,ic,TRUE);
8340 /*-----------------------------------------------------------------*/
8341 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8342 /*-----------------------------------------------------------------*/
8343 static void genPagedPointerGet (operand *left,
8350 sym_link *rtype, *retype;
8352 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8354 rtype = operandType(result);
8355 retype= getSpec(rtype);
8357 pic16_aopOp(left,ic,FALSE);
8359 /* if the value is already in a pointer register
8360 then don't need anything more */
8361 if (!AOP_INPREG(AOP(left))) {
8362 /* otherwise get a free pointer register */
8364 preg = getFreePtr(ic,&aop,FALSE);
8365 pic16_emitcode("mov","%s,%s",
8367 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8368 rname = preg->name ;
8370 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8372 pic16_freeAsmop(left,NULL,ic,TRUE);
8373 pic16_aopOp (result,ic,FALSE);
8375 /* if bitfield then unpack the bits */
8376 if (IS_BITVAR(retype))
8377 genUnpackBits (result,rname,PPOINTER);
8379 /* we have can just get the values */
8380 int size = AOP_SIZE(result);
8385 pic16_emitcode("movx","a,@%s",rname);
8386 pic16_aopPut(AOP(result),"a",offset);
8391 pic16_emitcode("inc","%s",rname);
8395 /* now some housekeeping stuff */
8397 /* we had to allocate for this iCode */
8398 pic16_freeAsmop(NULL,aop,ic,TRUE);
8400 /* we did not allocate which means left
8401 already in a pointer register, then
8402 if size > 0 && this could be used again
8403 we have to point it back to where it
8405 if (AOP_SIZE(result) > 1 &&
8406 !OP_SYMBOL(left)->remat &&
8407 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8409 int size = AOP_SIZE(result) - 1;
8411 pic16_emitcode("dec","%s",rname);
8416 pic16_freeAsmop(result,NULL,ic,TRUE);
8421 /*-----------------------------------------------------------------*/
8422 /* genFarPointerGet - gget value from far space */
8423 /*-----------------------------------------------------------------*/
8424 static void genFarPointerGet (operand *left,
8425 operand *result, iCode *ic)
8428 sym_link *retype = getSpec(operandType(result));
8430 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8432 pic16_aopOp(left,ic,FALSE);
8434 /* if the operand is already in dptr
8435 then we do nothing else we move the value to dptr */
8436 if (AOP_TYPE(left) != AOP_STR) {
8437 /* if this is remateriazable */
8438 if (AOP_TYPE(left) == AOP_IMMD)
8439 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8440 else { /* we need to get it byte by byte */
8441 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8442 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8443 if (options.model == MODEL_FLAT24)
8445 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8449 /* so dptr know contains the address */
8450 pic16_freeAsmop(left,NULL,ic,TRUE);
8451 pic16_aopOp(result,ic,FALSE);
8453 /* if bit then unpack */
8454 if (IS_BITVAR(retype))
8455 genUnpackBits(result,"dptr",FPOINTER);
8457 size = AOP_SIZE(result);
8461 pic16_emitcode("movx","a,@dptr");
8462 pic16_aopPut(AOP(result),"a",offset++);
8464 pic16_emitcode("inc","dptr");
8468 pic16_freeAsmop(result,NULL,ic,TRUE);
8471 /*-----------------------------------------------------------------*/
8472 /* genCodePointerGet - get value from code space */
8473 /*-----------------------------------------------------------------*/
8474 static void genCodePointerGet (operand *left,
8475 operand *result, iCode *ic)
8478 sym_link *retype = getSpec(operandType(result));
8480 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8482 pic16_aopOp(left,ic,FALSE);
8484 /* if the operand is already in dptr
8485 then we do nothing else we move the value to dptr */
8486 if (AOP_TYPE(left) != AOP_STR) {
8487 /* if this is remateriazable */
8488 if (AOP_TYPE(left) == AOP_IMMD)
8489 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8490 else { /* we need to get it byte by byte */
8491 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8492 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8493 if (options.model == MODEL_FLAT24)
8495 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8499 /* so dptr know contains the address */
8500 pic16_freeAsmop(left,NULL,ic,TRUE);
8501 pic16_aopOp(result,ic,FALSE);
8503 /* if bit then unpack */
8504 if (IS_BITVAR(retype))
8505 genUnpackBits(result,"dptr",CPOINTER);
8507 size = AOP_SIZE(result);
8511 pic16_emitcode("clr","a");
8512 pic16_emitcode("movc","a,@a+dptr");
8513 pic16_aopPut(AOP(result),"a",offset++);
8515 pic16_emitcode("inc","dptr");
8519 pic16_freeAsmop(result,NULL,ic,TRUE);
8522 /*-----------------------------------------------------------------*/
8523 /* genGenPointerGet - gget value from generic pointer space */
8524 /*-----------------------------------------------------------------*/
8525 static void genGenPointerGet (operand *left,
8526 operand *result, iCode *ic)
8529 sym_link *retype = getSpec(operandType(result));
8531 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8532 pic16_aopOp(left,ic,FALSE);
8533 pic16_aopOp(result,ic,FALSE);
8536 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8538 /* if the operand is already in dptr
8539 then we do nothing else we move the value to dptr */
8540 // if (AOP_TYPE(left) != AOP_STR) {
8541 /* if this is remateriazable */
8542 if (AOP_TYPE(left) == AOP_IMMD) {
8543 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8544 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8546 else { /* we need to get it byte by byte */
8548 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8549 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8551 size = AOP_SIZE(result);
8555 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8556 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8558 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8563 /* so dptr know contains the address */
8565 /* if bit then unpack */
8566 if (IS_BITVAR(retype))
8567 genUnpackBits(result,"BAD",GPOINTER);
8570 pic16_freeAsmop(left,NULL,ic,TRUE);
8571 pic16_freeAsmop(result,NULL,ic,TRUE);
8575 /*-----------------------------------------------------------------*/
8576 /* genConstPointerGet - get value from const generic pointer space */
8577 /*-----------------------------------------------------------------*/
8578 static void genConstPointerGet (operand *left,
8579 operand *result, iCode *ic)
8581 //sym_link *retype = getSpec(operandType(result));
8582 symbol *albl = newiTempLabel(NULL);
8583 symbol *blbl = newiTempLabel(NULL);
8586 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8587 pic16_aopOp(left,ic,FALSE);
8588 pic16_aopOp(result,ic,FALSE);
8591 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8593 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8595 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8596 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8597 pic16_emitpLabel(albl->key);
8599 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8601 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8602 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8603 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8604 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8605 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8607 pic16_emitpLabel(blbl->key);
8609 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8612 pic16_freeAsmop(left,NULL,ic,TRUE);
8613 pic16_freeAsmop(result,NULL,ic,TRUE);
8616 /*-----------------------------------------------------------------*/
8617 /* genPointerGet - generate code for pointer get */
8618 /*-----------------------------------------------------------------*/
8619 static void genPointerGet (iCode *ic)
8621 operand *left, *result ;
8622 sym_link *type, *etype;
8625 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8628 result = IC_RESULT(ic) ;
8630 /* depending on the type of pointer we need to
8631 move it to the correct pointer register */
8632 type = operandType(left);
8633 etype = getSpec(type);
8636 if (IS_PTR_CONST(type))
8638 if (IS_CODEPTR(type))
8640 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8642 /* if left is of type of pointer then it is simple */
8643 if (IS_PTR(type) && !IS_FUNC(type->next))
8644 p_type = DCL_TYPE(type);
8646 /* we have to go by the storage class */
8647 p_type = PTR_TYPE(SPEC_OCLS(etype));
8649 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8651 if (SPEC_OCLS(etype)->codesp ) {
8652 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8653 //p_type = CPOINTER ;
8656 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8657 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8658 /*p_type = FPOINTER ;*/
8660 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8661 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8662 /* p_type = PPOINTER; */
8664 if (SPEC_OCLS(etype) == idata )
8665 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8666 /* p_type = IPOINTER; */
8668 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8669 /* p_type = POINTER ; */
8672 /* now that we have the pointer type we assign
8673 the pointer values */
8678 genNearPointerGet (left,result,ic);
8682 genPagedPointerGet(left,result,ic);
8686 genFarPointerGet (left,result,ic);
8690 genConstPointerGet (left,result,ic);
8691 //pic16_emitcodePointerGet (left,result,ic);
8696 if (IS_PTR_CONST(type))
8697 genConstPointerGet (left,result,ic);
8700 genGenPointerGet (left,result,ic);
8706 /*-----------------------------------------------------------------*/
8707 /* genPackBits - generates code for packed bit storage */
8708 /*-----------------------------------------------------------------*/
8709 static void genPackBits (sym_link *etype ,
8711 char *rname, int p_type)
8719 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8720 blen = SPEC_BLEN(etype);
8721 bstr = SPEC_BSTR(etype);
8723 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8726 /* if the bit lenth is less than or */
8727 /* it exactly fits a byte then */
8728 if (SPEC_BLEN(etype) <= 8 ) {
8729 shCount = SPEC_BSTR(etype) ;
8731 /* shift left acc */
8734 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8739 pic16_emitcode ("mov","b,a");
8740 pic16_emitcode("mov","a,@%s",rname);
8744 pic16_emitcode ("mov","b,a");
8745 pic16_emitcode("movx","a,@dptr");
8749 pic16_emitcode ("push","b");
8750 pic16_emitcode ("push","acc");
8751 pic16_emitcode ("lcall","__gptrget");
8752 pic16_emitcode ("pop","b");
8756 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8757 ((unsigned char)(0xFF << (blen+bstr)) |
8758 (unsigned char)(0xFF >> (8-bstr)) ) );
8759 pic16_emitcode ("orl","a,b");
8760 if (p_type == GPOINTER)
8761 pic16_emitcode("pop","b");
8767 pic16_emitcode("mov","@%s,a",rname);
8771 pic16_emitcode("movx","@dptr,a");
8775 DEBUGpic16_emitcode(";lcall","__gptrput");
8780 if ( SPEC_BLEN(etype) <= 8 )
8783 pic16_emitcode("inc","%s",rname);
8784 rLen = SPEC_BLEN(etype) ;
8786 /* now generate for lengths greater than one byte */
8789 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8799 pic16_emitcode("mov","@%s,a",rname);
8801 pic16_emitcode("mov","@%s,%s",rname,l);
8806 pic16_emitcode("movx","@dptr,a");
8811 DEBUGpic16_emitcode(";lcall","__gptrput");
8814 pic16_emitcode ("inc","%s",rname);
8819 /* last last was not complete */
8821 /* save the byte & read byte */
8824 pic16_emitcode ("mov","b,a");
8825 pic16_emitcode("mov","a,@%s",rname);
8829 pic16_emitcode ("mov","b,a");
8830 pic16_emitcode("movx","a,@dptr");
8834 pic16_emitcode ("push","b");
8835 pic16_emitcode ("push","acc");
8836 pic16_emitcode ("lcall","__gptrget");
8837 pic16_emitcode ("pop","b");
8841 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8842 pic16_emitcode ("orl","a,b");
8845 if (p_type == GPOINTER)
8846 pic16_emitcode("pop","b");
8851 pic16_emitcode("mov","@%s,a",rname);
8855 pic16_emitcode("movx","@dptr,a");
8859 DEBUGpic16_emitcode(";lcall","__gptrput");
8863 /*-----------------------------------------------------------------*/
8864 /* genDataPointerSet - remat pointer to data space */
8865 /*-----------------------------------------------------------------*/
8866 static void genDataPointerSet(operand *right,
8870 int size, offset = 0 ;
8871 char *l, buffer[256];
8873 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8874 pic16_aopOp(right,ic,FALSE);
8876 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8877 size = AOP_SIZE(right);
8879 if ( AOP_TYPE(result) == AOP_PCODE) {
8880 fprintf(stderr,"genDataPointerSet %s, %d\n",
8881 AOP(result)->aopu.pcop->name,
8882 PCOI(AOP(result)->aopu.pcop)->offset);
8886 // tsd, was l+1 - the underline `_' prefix was being stripped
8889 sprintf(buffer,"(%s + %d)",l,offset);
8890 fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer);
8892 sprintf(buffer,"%s",l);
8894 if (AOP_TYPE(right) == AOP_LIT) {
8895 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8896 lit = lit >> (8*offset);
8898 pic16_emitcode("movlw","%d",lit);
8899 pic16_emitcode("movwf","%s",buffer);
8901 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8902 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
8903 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8906 pic16_emitcode("clrf","%s",buffer);
8907 //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer));
8908 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8911 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8912 pic16_emitcode("movwf","%s",buffer);
8914 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8915 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
8916 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8923 pic16_freeAsmop(right,NULL,ic,TRUE);
8924 pic16_freeAsmop(result,NULL,ic,TRUE);
8927 /*-----------------------------------------------------------------*/
8928 /* genNearPointerSet - pic16_emitcode for near pointer put */
8929 /*-----------------------------------------------------------------*/
8930 static void genNearPointerSet (operand *right,
8937 sym_link *ptype = operandType(result);
8940 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8941 retype= getSpec(operandType(right));
8943 pic16_aopOp(result,ic,FALSE);
8946 /* if the result is rematerializable &
8947 in data space & not a bit variable */
8948 //if (AOP_TYPE(result) == AOP_IMMD &&
8949 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8950 DCL_TYPE(ptype) == POINTER &&
8951 !IS_BITVAR(retype)) {
8952 genDataPointerSet (right,result,ic);
8953 pic16_freeAsmop(result,NULL,ic,TRUE);
8957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8958 pic16_aopOp(right,ic,FALSE);
8959 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8961 /* if the value is already in a pointer register
8962 then don't need anything more */
8963 if (!AOP_INPREG(AOP(result))) {
8964 /* otherwise get a free pointer register */
8965 //aop = newAsmop(0);
8966 //preg = getFreePtr(ic,&aop,FALSE);
8967 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8968 //pic16_emitcode("mov","%s,%s",
8970 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8971 //rname = preg->name ;
8972 //pic16_emitcode("movwf","fsr0");
8973 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8974 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8975 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8976 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8980 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8982 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8984 /* if bitfield then unpack the bits */
8985 if (IS_BITVAR(retype)) {
8986 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8987 "The programmer is obviously confused");
8988 // genPackBits (retype,right,"BAD",POINTER);
8992 /* we have can just get the values */
8993 int size = AOP_SIZE(right);
8996 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8998 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9001 //pic16_emitcode("mov","@%s,a",rname);
9002 pic16_emitcode("movf","indf0,w ;1");
9005 if (AOP_TYPE(right) == AOP_LIT) {
9006 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9008 pic16_emitcode("movlw","%s",l);
9009 pic16_emitcode("movwf","indf0 ;2");
9011 pic16_emitcode("clrf","indf0");
9013 pic16_emitcode("movf","%s,w",l);
9014 pic16_emitcode("movwf","indf0 ;2");
9016 //pic16_emitcode("mov","@%s,%s",rname,l);
9019 pic16_emitcode("incf","fsr0,f ;3");
9020 //pic16_emitcode("inc","%s",rname);
9025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9026 /* now some housekeeping stuff */
9028 /* we had to allocate for this iCode */
9029 pic16_freeAsmop(NULL,aop,ic,TRUE);
9031 /* we did not allocate which means left
9032 already in a pointer register, then
9033 if size > 0 && this could be used again
9034 we have to point it back to where it
9036 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9037 if (AOP_SIZE(right) > 1 &&
9038 !OP_SYMBOL(result)->remat &&
9039 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9041 int size = AOP_SIZE(right) - 1;
9043 pic16_emitcode("decf","fsr0,f");
9044 //pic16_emitcode("dec","%s",rname);
9048 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9051 pic16_freeAsmop(right,NULL,ic,TRUE);
9052 pic16_freeAsmop(result,NULL,ic,TRUE);
9055 /*-----------------------------------------------------------------*/
9056 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9057 /*-----------------------------------------------------------------*/
9058 static void genPagedPointerSet (operand *right,
9067 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9069 retype= getSpec(operandType(right));
9071 pic16_aopOp(result,ic,FALSE);
9073 /* if the value is already in a pointer register
9074 then don't need anything more */
9075 if (!AOP_INPREG(AOP(result))) {
9076 /* otherwise get a free pointer register */
9078 preg = getFreePtr(ic,&aop,FALSE);
9079 pic16_emitcode("mov","%s,%s",
9081 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9082 rname = preg->name ;
9084 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9086 pic16_freeAsmop(result,NULL,ic,TRUE);
9087 pic16_aopOp (right,ic,FALSE);
9089 /* if bitfield then unpack the bits */
9090 if (IS_BITVAR(retype))
9091 genPackBits (retype,right,rname,PPOINTER);
9093 /* we have can just get the values */
9094 int size = AOP_SIZE(right);
9098 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9101 pic16_emitcode("movx","@%s,a",rname);
9104 pic16_emitcode("inc","%s",rname);
9110 /* now some housekeeping stuff */
9112 /* we had to allocate for this iCode */
9113 pic16_freeAsmop(NULL,aop,ic,TRUE);
9115 /* we did not allocate which means left
9116 already in a pointer register, then
9117 if size > 0 && this could be used again
9118 we have to point it back to where it
9120 if (AOP_SIZE(right) > 1 &&
9121 !OP_SYMBOL(result)->remat &&
9122 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9124 int size = AOP_SIZE(right) - 1;
9126 pic16_emitcode("dec","%s",rname);
9131 pic16_freeAsmop(right,NULL,ic,TRUE);
9136 /*-----------------------------------------------------------------*/
9137 /* genFarPointerSet - set value from far space */
9138 /*-----------------------------------------------------------------*/
9139 static void genFarPointerSet (operand *right,
9140 operand *result, iCode *ic)
9143 sym_link *retype = getSpec(operandType(right));
9145 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9146 pic16_aopOp(result,ic,FALSE);
9148 /* if the operand is already in dptr
9149 then we do nothing else we move the value to dptr */
9150 if (AOP_TYPE(result) != AOP_STR) {
9151 /* if this is remateriazable */
9152 if (AOP_TYPE(result) == AOP_IMMD)
9153 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9154 else { /* we need to get it byte by byte */
9155 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9156 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9157 if (options.model == MODEL_FLAT24)
9159 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9163 /* so dptr know contains the address */
9164 pic16_freeAsmop(result,NULL,ic,TRUE);
9165 pic16_aopOp(right,ic,FALSE);
9167 /* if bit then unpack */
9168 if (IS_BITVAR(retype))
9169 genPackBits(retype,right,"dptr",FPOINTER);
9171 size = AOP_SIZE(right);
9175 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9177 pic16_emitcode("movx","@dptr,a");
9179 pic16_emitcode("inc","dptr");
9183 pic16_freeAsmop(right,NULL,ic,TRUE);
9186 /*-----------------------------------------------------------------*/
9187 /* genGenPointerSet - set value from generic pointer space */
9188 /*-----------------------------------------------------------------*/
9189 static void genGenPointerSet (operand *right,
9190 operand *result, iCode *ic)
9193 sym_link *retype = getSpec(operandType(right));
9195 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9197 pic16_aopOp(result,ic,FALSE);
9198 pic16_aopOp(right,ic,FALSE);
9199 size = AOP_SIZE(right);
9201 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9203 /* if the operand is already in dptr
9204 then we do nothing else we move the value to dptr */
9205 if (AOP_TYPE(result) != AOP_STR) {
9206 /* if this is remateriazable */
9207 if (AOP_TYPE(result) == AOP_IMMD) {
9208 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9209 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9211 else { /* we need to get it byte by byte */
9212 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9213 size = AOP_SIZE(right);
9216 /* hack hack! see if this the FSR. If so don't load W */
9217 if(AOP_TYPE(right) != AOP_ACC) {
9219 // pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(result), pic16_popCopyReg(&pic16_pc_fsr0), 0));
9221 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9222 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9224 if(AOP_SIZE(result) > 1) {
9225 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9226 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9227 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9232 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9234 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9235 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9239 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9240 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9243 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9250 if(aopIdx(AOP(result),0) != 4) {
9252 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9256 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9261 /* so dptr know contains the address */
9264 /* if bit then unpack */
9265 if (IS_BITVAR(retype))
9266 genPackBits(retype,right,"dptr",GPOINTER);
9268 size = AOP_SIZE(right);
9271 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9275 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9276 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9278 if (AOP_TYPE(right) == AOP_LIT)
9279 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9281 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9283 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9290 pic16_freeAsmop(right,NULL,ic,TRUE);
9291 pic16_freeAsmop(result,NULL,ic,TRUE);
9294 /*-----------------------------------------------------------------*/
9295 /* genPointerSet - stores the value into a pointer location */
9296 /*-----------------------------------------------------------------*/
9297 static void genPointerSet (iCode *ic)
9299 operand *right, *result ;
9300 sym_link *type, *etype;
9303 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9305 right = IC_RIGHT(ic);
9306 result = IC_RESULT(ic) ;
9308 /* depending on the type of pointer we need to
9309 move it to the correct pointer register */
9310 type = operandType(result);
9311 etype = getSpec(type);
9312 /* if left is of type of pointer then it is simple */
9313 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9314 p_type = DCL_TYPE(type);
9317 /* we have to go by the storage class */
9318 p_type = PTR_TYPE(SPEC_OCLS(etype));
9320 /* if (SPEC_OCLS(etype)->codesp ) { */
9321 /* p_type = CPOINTER ; */
9324 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9325 /* p_type = FPOINTER ; */
9327 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9328 /* p_type = PPOINTER ; */
9330 /* if (SPEC_OCLS(etype) == idata ) */
9331 /* p_type = IPOINTER ; */
9333 /* p_type = POINTER ; */
9336 /* now that we have the pointer type we assign
9337 the pointer values */
9342 genNearPointerSet (right,result,ic);
9346 genPagedPointerSet (right,result,ic);
9350 genFarPointerSet (right,result,ic);
9354 genGenPointerSet (right,result,ic);
9358 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9359 "genPointerSet: illegal pointer type");
9363 /*-----------------------------------------------------------------*/
9364 /* genIfx - generate code for Ifx statement */
9365 /*-----------------------------------------------------------------*/
9366 static void genIfx (iCode *ic, iCode *popIc)
9368 operand *cond = IC_COND(ic);
9371 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9373 pic16_aopOp(cond,ic,FALSE);
9375 /* get the value into acc */
9376 if (AOP_TYPE(cond) != AOP_CRY)
9377 pic16_toBoolean(cond);
9380 /* the result is now in the accumulator */
9381 pic16_freeAsmop(cond,NULL,ic,TRUE);
9383 /* if there was something to be popped then do it */
9387 /* if the condition is a bit variable */
9388 if (isbit && IS_ITEMP(cond) &&
9390 genIfxJump(ic,SPIL_LOC(cond)->rname);
9391 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9394 if (isbit && !IS_ITEMP(cond))
9395 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9403 /*-----------------------------------------------------------------*/
9404 /* genAddrOf - generates code for address of */
9405 /*-----------------------------------------------------------------*/
9407 static void genAddrOf (iCode *ic)
9409 operand *right, *result, *left;
9412 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9415 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9417 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9418 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9419 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9421 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9423 size = AOP_SIZE(IC_RESULT(ic));
9428 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9429 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9434 pic16_freeAsmop(left,NULL,ic,FALSE);
9435 pic16_freeAsmop(result,NULL,ic,TRUE);
9439 #else /* new genAddrOf */
9441 static void genAddrOf (iCode *ic)
9443 operand *result, *left;
9445 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9446 pCodeOp *pcop0, *pcop1, *pcop2;
9448 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9450 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9451 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9453 sym = OP_SYMBOL( left );
9455 size = AOP_SIZE(IC_RESULT(ic));
9457 if(pic16_debug_verbose) {
9458 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9459 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9462 /* Assume that what we want the address of is in data space
9463 * since there is no stack on the PIC, yet! -- VR */
9465 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9468 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9471 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9475 pic16_emitpcode(POC_MOVLW, pcop0);
9476 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9477 pic16_emitpcode(POC_MOVLW, pcop1);
9478 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9479 pic16_emitpcode(POC_MOVLW, pcop2);
9480 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9483 pic16_emitpcode(POC_MOVLW, pcop0);
9484 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9485 pic16_emitpcode(POC_MOVLW, pcop1);
9486 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9488 pic16_emitpcode(POC_MOVLW, pcop0);
9489 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9492 pic16_freeAsmop(result,NULL,ic,TRUE);
9493 pic16_freeAsmop(left, NULL, ic, FALSE);
9496 #endif /* new genAddrOf */
9499 /*-----------------------------------------------------------------*/
9500 /* genFarFarAssign - assignment when both are in far space */
9501 /*-----------------------------------------------------------------*/
9502 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9504 int size = AOP_SIZE(right);
9507 /* first push the right side on to the stack */
9509 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9511 pic16_emitcode ("push","acc");
9514 pic16_freeAsmop(right,NULL,ic,FALSE);
9515 /* now assign DPTR to result */
9516 pic16_aopOp(result,ic,FALSE);
9517 size = AOP_SIZE(result);
9519 pic16_emitcode ("pop","acc");
9520 pic16_aopPut(AOP(result),"a",--offset);
9522 pic16_freeAsmop(result,NULL,ic,FALSE);
9527 /*-----------------------------------------------------------------*/
9528 /* genAssign - generate code for assignment */
9529 /*-----------------------------------------------------------------*/
9530 static void genAssign (iCode *ic)
9532 operand *result, *right;
9533 int size, offset,know_W;
9534 unsigned long lit = 0L;
9536 result = IC_RESULT(ic);
9537 right = IC_RIGHT(ic) ;
9539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9541 /* if they are the same */
9542 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9545 pic16_aopOp(right,ic,FALSE);
9546 pic16_aopOp(result,ic,TRUE);
9548 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9550 /* if they are the same registers */
9551 if (pic16_sameRegs(AOP(right),AOP(result)))
9554 /* if the result is a bit */
9555 if (AOP_TYPE(result) == AOP_CRY) {
9556 /* if the right size is a literal then
9557 we know what the value is */
9558 if (AOP_TYPE(right) == AOP_LIT) {
9560 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9561 pic16_popGet(AOP(result),0));
9563 if (((int) operandLitValue(right)))
9564 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9565 AOP(result)->aopu.aop_dir,
9566 AOP(result)->aopu.aop_dir);
9568 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9569 AOP(result)->aopu.aop_dir,
9570 AOP(result)->aopu.aop_dir);
9574 /* the right is also a bit variable */
9575 if (AOP_TYPE(right) == AOP_CRY) {
9576 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9577 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9578 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9580 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9581 AOP(result)->aopu.aop_dir,
9582 AOP(result)->aopu.aop_dir);
9583 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9584 AOP(right)->aopu.aop_dir,
9585 AOP(right)->aopu.aop_dir);
9586 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9587 AOP(result)->aopu.aop_dir,
9588 AOP(result)->aopu.aop_dir);
9593 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9594 pic16_toBoolean(right);
9596 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9597 //pic16_aopPut(AOP(result),"a",0);
9601 /* bit variables done */
9603 size = AOP_SIZE(result);
9605 if(AOP_TYPE(right) == AOP_LIT)
9606 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9608 /* VR - What is this?! */
9609 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9610 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9611 if(aopIdx(AOP(result),0) == 4) {
9612 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9613 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9614 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9617 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9622 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9623 if(AOP_TYPE(right) == AOP_LIT) {
9625 if(know_W != (lit&0xff))
9626 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9628 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9630 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9634 } else if (AOP_TYPE(right) == AOP_CRY) {
9635 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9637 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9638 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9641 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9644 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9645 normally should work, but mind that the W register live range
9646 is not checked, so if the code generator assumes that the W
9647 is already loaded after such a pair, wrong code will be generated.
9649 Checking the live range is the next step.
9650 This is experimental code yet and has not been fully tested yet.
9651 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9652 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9654 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9656 /* This is the old code, which is assumed(?!) that works fine(!?) */
9658 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9659 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9668 pic16_freeAsmop (right,NULL,ic,FALSE);
9669 pic16_freeAsmop (result,NULL,ic,TRUE);
9672 /*-----------------------------------------------------------------*/
9673 /* genJumpTab - generates code for jump table */
9674 /*-----------------------------------------------------------------*/
9675 static void genJumpTab (iCode *ic)
9680 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9682 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9683 /* get the condition into accumulator */
9684 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9686 /* multiply by three */
9687 pic16_emitcode("add","a,acc");
9688 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9690 jtab = newiTempLabel(NULL);
9691 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9692 pic16_emitcode("jmp","@a+dptr");
9693 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9695 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9696 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9698 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9699 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9700 pic16_emitpLabel(jtab->key);
9702 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9704 /* now generate the jump labels */
9705 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9706 jtab = setNextItem(IC_JTLABELS(ic))) {
9707 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9708 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9714 /*-----------------------------------------------------------------*/
9715 /* genMixedOperation - gen code for operators between mixed types */
9716 /*-----------------------------------------------------------------*/
9718 TSD - Written for the PIC port - but this unfortunately is buggy.
9719 This routine is good in that it is able to efficiently promote
9720 types to different (larger) sizes. Unfortunately, the temporary
9721 variables that are optimized out by this routine are sometimes
9722 used in other places. So until I know how to really parse the
9723 iCode tree, I'm going to not be using this routine :(.
9725 static int genMixedOperation (iCode *ic)
9728 operand *result = IC_RESULT(ic);
9729 sym_link *ctype = operandType(IC_LEFT(ic));
9730 operand *right = IC_RIGHT(ic);
9736 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9738 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9744 nextright = IC_RIGHT(nextic);
9745 nextleft = IC_LEFT(nextic);
9746 nextresult = IC_RESULT(nextic);
9748 pic16_aopOp(right,ic,FALSE);
9749 pic16_aopOp(result,ic,FALSE);
9750 pic16_aopOp(nextright, nextic, FALSE);
9751 pic16_aopOp(nextleft, nextic, FALSE);
9752 pic16_aopOp(nextresult, nextic, FALSE);
9754 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9760 pic16_emitcode(";remove right +","");
9762 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9768 pic16_emitcode(";remove left +","");
9772 big = AOP_SIZE(nextleft);
9773 small = AOP_SIZE(nextright);
9775 switch(nextic->op) {
9778 pic16_emitcode(";optimize a +","");
9779 /* if unsigned or not an integral type */
9780 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9781 pic16_emitcode(";add a bit to something","");
9784 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9786 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9787 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9788 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9790 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9798 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9799 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9800 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9803 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9805 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9806 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9807 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9808 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9809 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9812 pic16_emitcode("rlf","known_zero,w");
9819 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9820 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9821 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9823 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9833 pic16_freeAsmop(right,NULL,ic,TRUE);
9834 pic16_freeAsmop(result,NULL,ic,TRUE);
9835 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9836 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9838 nextic->generated = 1;
9845 /*-----------------------------------------------------------------*/
9846 /* genCast - gen code for casting */
9847 /*-----------------------------------------------------------------*/
9848 static void genCast (iCode *ic)
9850 operand *result = IC_RESULT(ic);
9851 sym_link *ctype = operandType(IC_LEFT(ic));
9852 sym_link *rtype = operandType(IC_RIGHT(ic));
9853 operand *right = IC_RIGHT(ic);
9856 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9857 /* if they are equivalent then do nothing */
9858 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9861 pic16_aopOp(right,ic,FALSE) ;
9862 pic16_aopOp(result,ic,FALSE);
9864 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9866 /* if the result is a bit */
9867 if (AOP_TYPE(result) == AOP_CRY) {
9869 /* if the right size is a literal then
9870 * we know what the value is */
9871 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9873 if (AOP_TYPE(right) == AOP_LIT) {
9874 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9875 pic16_popGet(AOP(result),0));
9877 if (((int) operandLitValue(right)))
9878 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9879 AOP(result)->aopu.aop_dir,
9880 AOP(result)->aopu.aop_dir);
9882 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9883 AOP(result)->aopu.aop_dir,
9884 AOP(result)->aopu.aop_dir);
9888 /* the right is also a bit variable */
9889 if (AOP_TYPE(right) == AOP_CRY) {
9891 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9893 pic16_emitcode("clrc","");
9894 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9895 AOP(right)->aopu.aop_dir,
9896 AOP(right)->aopu.aop_dir);
9897 pic16_aopPut(AOP(result),"c",0);
9902 if (AOP_TYPE(right) == AOP_REG) {
9903 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9904 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9905 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9907 pic16_toBoolean(right);
9908 pic16_aopPut(AOP(result),"a",0);
9912 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9915 size = AOP_SIZE(result);
9917 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9919 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9920 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9921 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9924 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9929 /* if they are the same size : or less */
9930 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9932 /* if they are in the same place */
9933 if (pic16_sameRegs(AOP(right),AOP(result)))
9936 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9938 if (IS_PTR_CONST(rtype))
9940 if (IS_CODEPTR(rtype))
9942 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9945 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9947 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
9949 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9952 if(AOP_TYPE(right) == AOP_IMMD) {
9953 pCodeOp *pcop0, *pcop1, *pcop2;
9954 symbol *sym = OP_SYMBOL( right );
9956 size = AOP_SIZE(result);
9958 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9960 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9962 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9965 pic16_emitpcode(POC_MOVLW, pcop0);
9966 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9967 pic16_emitpcode(POC_MOVLW, pcop1);
9968 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9969 pic16_emitpcode(POC_MOVLW, pcop2);
9970 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9973 pic16_emitpcode(POC_MOVLW, pcop0);
9974 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9975 pic16_emitpcode(POC_MOVLW, pcop1);
9976 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9978 pic16_emitpcode(POC_MOVLW, pcop0);
9979 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9983 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9984 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9985 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9986 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9987 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9988 if(AOP_SIZE(result) <2)
9989 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9991 /* if they in different places then copy */
9992 size = AOP_SIZE(result);
9995 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9996 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10003 /* if the result is of type pointer */
10004 if (IS_PTR(ctype)) {
10006 sym_link *type = operandType(right);
10007 sym_link *etype = getSpec(type);
10009 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10011 /* pointer to generic pointer */
10012 if (IS_GENPTR(ctype)) {
10016 p_type = DCL_TYPE(type);
10018 /* we have to go by the storage class */
10019 p_type = PTR_TYPE(SPEC_OCLS(etype));
10021 /* if (SPEC_OCLS(etype)->codesp ) */
10022 /* p_type = CPOINTER ; */
10024 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10025 /* p_type = FPOINTER ; */
10027 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10028 /* p_type = PPOINTER; */
10030 /* if (SPEC_OCLS(etype) == idata ) */
10031 /* p_type = IPOINTER ; */
10033 /* p_type = POINTER ; */
10036 /* the first two bytes are known */
10037 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10038 size = GPTRSIZE - 1;
10041 if(offset < AOP_SIZE(right)) {
10042 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10043 if ((AOP_TYPE(right) == AOP_PCODE) &&
10044 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10045 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10046 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10048 pic16_aopPut(AOP(result),
10049 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10053 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10056 /* the last byte depending on type */
10060 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10063 pic16_emitcode(";BUG!? ","%d",__LINE__);
10067 pic16_emitcode(";BUG!? ","%d",__LINE__);
10071 pic16_emitcode(";BUG!? ","%d",__LINE__);
10076 /* this should never happen */
10077 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10078 "got unknown pointer type");
10081 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10085 /* just copy the pointers */
10086 size = AOP_SIZE(result);
10089 pic16_aopPut(AOP(result),
10090 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10099 /* so we now know that the size of destination is greater
10100 than the size of the source.
10101 Now, if the next iCode is an operator then we might be
10102 able to optimize the operation without performing a cast.
10104 if(genMixedOperation(ic))
10107 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10109 /* we move to result for the size of source */
10110 size = AOP_SIZE(right);
10113 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10114 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10118 /* now depending on the sign of the destination */
10119 size = AOP_SIZE(result) - AOP_SIZE(right);
10120 /* if unsigned or not an integral type */
10121 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10123 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10125 /* we need to extend the sign :( */
10128 /* Save one instruction of casting char to int */
10129 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10130 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10131 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10133 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10136 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10138 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10140 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10143 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10148 pic16_freeAsmop(right,NULL,ic,TRUE);
10149 pic16_freeAsmop(result,NULL,ic,TRUE);
10153 /*-----------------------------------------------------------------*/
10154 /* genDjnz - generate decrement & jump if not zero instrucion */
10155 /*-----------------------------------------------------------------*/
10156 static int genDjnz (iCode *ic, iCode *ifx)
10158 symbol *lbl, *lbl1;
10159 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10164 /* if the if condition has a false label
10165 then we cannot save */
10169 /* if the minus is not of the form
10171 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10172 !IS_OP_LITERAL(IC_RIGHT(ic)))
10175 if (operandLitValue(IC_RIGHT(ic)) != 1)
10178 /* if the size of this greater than one then no
10180 if (getSize(operandType(IC_RESULT(ic))) > 1)
10183 /* otherwise we can save BIG */
10184 lbl = newiTempLabel(NULL);
10185 lbl1= newiTempLabel(NULL);
10187 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10189 if (IS_AOP_PREG(IC_RESULT(ic))) {
10190 pic16_emitcode("dec","%s",
10191 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10192 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10193 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10197 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10198 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10200 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10201 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10204 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10205 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10206 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10207 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10210 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10211 ifx->generated = 1;
10215 /*-----------------------------------------------------------------*/
10216 /* genReceive - generate code for a receive iCode */
10217 /*-----------------------------------------------------------------*/
10218 static void genReceive (iCode *ic)
10220 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10222 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10223 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10224 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10226 int size = getSize(operandType(IC_RESULT(ic)));
10227 int offset = pic16_fReturnSizePic - size;
10230 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10231 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10235 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10237 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10238 size = AOP_SIZE(IC_RESULT(ic));
10241 pic16_emitcode ("pop","acc");
10242 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10245 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10248 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10250 assignResultValue(IC_RESULT(ic));
10253 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10256 /*-----------------------------------------------------------------*/
10257 /* genDummyRead - generate code for dummy read of volatiles */
10258 /*-----------------------------------------------------------------*/
10260 genDummyRead (iCode * ic)
10262 pic16_emitcode ("; genDummyRead","");
10263 pic16_emitcode ("; not implemented","");
10268 /*-----------------------------------------------------------------*/
10269 /* genpic16Code - generate code for pic16 based controllers */
10270 /*-----------------------------------------------------------------*/
10272 * At this point, ralloc.c has gone through the iCode and attempted
10273 * to optimize in a way suitable for a PIC. Now we've got to generate
10274 * PIC instructions that correspond to the iCode.
10276 * Once the instructions are generated, we'll pass through both the
10277 * peep hole optimizer and the pCode optimizer.
10278 *-----------------------------------------------------------------*/
10280 void genpic16Code (iCode *lic)
10285 lineHead = lineCurr = NULL;
10287 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10288 pic16_addpBlock(pb);
10291 /* if debug information required */
10292 if (options.debug && currFunc) {
10294 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10296 if (IS_STATIC(currFunc->etype)) {
10297 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10298 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10300 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10301 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10310 for (ic = lic ; ic ; ic = ic->next ) {
10312 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10313 // DEBUGpic16_emitcode("; VR", "");
10314 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10315 if ( cln != ic->lineno ) {
10316 if ( options.debug ) {
10318 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10319 FileBaseName(ic->filename),ic->lineno,
10320 ic->level,ic->block);
10324 if(!options.noCcodeInAsm) {
10325 pic16_addpCode2pBlock(pb,
10326 pic16_newpCodeCSource(ic->lineno, ic->filename,
10327 printCLine(ic->filename, ic->lineno)));
10333 if(options.iCodeInAsm) {
10334 /* insert here code to print iCode as comment */
10337 /* if the result is marked as
10338 spilt and rematerializable or code for
10339 this has already been generated then
10341 if (resultRemat(ic) || ic->generated )
10344 /* depending on the operation */
10363 /* IPOP happens only when trying to restore a
10364 spilt live range, if there is an ifx statement
10365 following this pop then the if statement might
10366 be using some of the registers being popped which
10367 would destroy the contents of the register so
10368 we need to check for this condition and handle it */
10370 ic->next->op == IFX &&
10371 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10372 genIfx (ic->next,ic);
10390 genEndFunction (ic);
10406 pic16_genPlus (ic) ;
10410 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10411 pic16_genMinus (ic);
10427 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10431 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10438 /* note these two are xlated by algebraic equivalence
10439 during parsing SDCC.y */
10440 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10441 "got '>=' or '<=' shouldn't have come here");
10445 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10457 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10461 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10465 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10489 genRightShift (ic);
10492 case GET_VALUE_AT_ADDRESS:
10497 if (POINTER_SET(ic))
10524 addSet(&_G.sendSet,ic);
10527 case DUMMY_READ_VOLATILE:
10537 /* now we are ready to call the
10538 peep hole optimizer */
10539 if (!options.nopeep) {
10540 peepHole (&lineHead);
10542 /* now do the actual printing */
10543 printLine (lineHead,codeOutFile);
10546 DFPRINTF((stderr,"printing pBlock\n\n"));
10547 pic16_printpBlock(stdout,pb);