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));
276 /*-----------------------------------------------------------------*/
277 /* pic16_emitcode - writes the code into a file : for now it is simple */
278 /*-----------------------------------------------------------------*/
279 void pic16_emitcode (char *inst,char *fmt, ...)
282 char lb[INITIAL_INLINEASM];
289 sprintf(lb,"%s\t",inst);
291 sprintf(lb,"%s",inst);
292 vsprintf(lb+(strlen(lb)),fmt,ap);
296 while (isspace(*lbp)) lbp++;
299 lineCurr = (lineCurr ?
300 connectLine(lineCurr,newLineNode(lb)) :
301 (lineHead = newLineNode(lb)));
302 lineCurr->isInline = _G.inLine;
303 lineCurr->isDebug = _G.debugLine;
305 // VR fprintf(stderr, "lb = <%s>\n", lbp);
307 // if(pic16_debug_verbose)
308 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
314 /*-----------------------------------------------------------------*/
315 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
316 /*-----------------------------------------------------------------*/
317 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
319 bool r0iu = FALSE , r1iu = FALSE;
320 bool r0ou = FALSE , r1ou = FALSE;
322 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
324 /* the logic: if r0 & r1 used in the instruction
325 then we are in trouble otherwise */
327 /* first check if r0 & r1 are used by this
328 instruction, in which case we are in trouble */
329 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
330 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
335 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
336 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
338 /* if no usage of r0 then return it */
339 if (!r0iu && !r0ou) {
340 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
341 (*aopp)->type = AOP_R0;
343 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
346 /* if no usage of r1 then return it */
347 if (!r1iu && !r1ou) {
348 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
349 (*aopp)->type = AOP_R1;
351 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
354 /* now we know they both have usage */
355 /* if r0 not used in this instruction */
357 /* push it if not already pushed */
359 //pic16_emitcode ("push","%s",
360 // pic16_regWithIdx(R0_IDX)->dname);
364 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
365 (*aopp)->type = AOP_R0;
367 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
370 /* if r1 not used then */
373 /* push it if not already pushed */
375 //pic16_emitcode ("push","%s",
376 // pic16_regWithIdx(R1_IDX)->dname);
380 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
381 (*aopp)->type = AOP_R1;
382 return pic16_regWithIdx(R1_IDX);
386 /* I said end of world but not quite end of world yet */
387 /* if this is a result then we can push it on the stack*/
389 (*aopp)->type = AOP_STK;
393 /* other wise this is true end of the world */
394 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
395 "getFreePtr should never reach here");
399 /*-----------------------------------------------------------------*/
400 /* newAsmop - creates a new asmOp */
401 /*-----------------------------------------------------------------*/
402 static asmop *newAsmop (short type)
406 aop = Safe_calloc(1,sizeof(asmop));
411 static void genSetDPTR(int n)
415 pic16_emitcode(";", "Select standard DPTR");
416 pic16_emitcode("mov", "dps, #0x00");
420 pic16_emitcode(";", "Select alternate DPTR");
421 pic16_emitcode("mov", "dps, #0x01");
425 /*-----------------------------------------------------------------*/
426 /* resolveIfx - converts an iCode ifx into a form more useful for */
427 /* generating code */
428 /*-----------------------------------------------------------------*/
429 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
434 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
436 resIfx->condition = 1; /* assume that the ifx is true */
437 resIfx->generated = 0; /* indicate that the ifx has not been used */
440 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
442 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
443 __FUNCTION__,__LINE__,resIfx->lbl->key);
447 resIfx->lbl = IC_TRUE(ifx);
449 resIfx->lbl = IC_FALSE(ifx);
450 resIfx->condition = 0;
454 DEBUGpic16_emitcode("; ***","ifx true is non-null");
456 DEBUGpic16_emitcode("; ***","ifx false is non-null");
460 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
463 /*-----------------------------------------------------------------*/
464 /* pointerCode - returns the code for a pointer type */
465 /*-----------------------------------------------------------------*/
466 static int pointerCode (sym_link *etype)
469 return PTR_TYPE(SPEC_OCLS(etype));
473 /*-----------------------------------------------------------------*/
474 /* aopForSym - for a true symbol */
475 /*-----------------------------------------------------------------*/
476 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
479 memmap *space= SPEC_OCLS(sym->etype);
481 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
482 /* if already has one */
484 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
488 /* assign depending on the storage class */
489 /* if it is on the stack or indirectly addressable */
490 /* space we need to assign either r0 or r1 to it */
491 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
492 sym->aop = aop = newAsmop(0);
493 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
494 aop->size = getSize(sym->type);
496 /* now assign the address of the variable to
497 the pointer register */
498 if (aop->type != AOP_STK) {
502 pic16_emitcode("push","acc");
504 pic16_emitcode("mov","a,_bp");
505 pic16_emitcode("add","a,#0x%02x",
507 ((char)(sym->stack - _G.nRegsSaved )) :
508 ((char)sym->stack)) & 0xff);
509 pic16_emitcode("mov","%s,a",
510 aop->aopu.aop_ptr->name);
513 pic16_emitcode("pop","acc");
515 pic16_emitcode("mov","%s,#%s",
516 aop->aopu.aop_ptr->name,
518 aop->paged = space->paged;
520 aop->aopu.aop_stk = sym->stack;
524 if (sym->onStack && options.stack10bit)
526 /* It's on the 10 bit stack, which is located in
530 //DEBUGpic16_emitcode(";","%d",__LINE__);
533 pic16_emitcode("push","acc");
535 pic16_emitcode("mov","a,_bp");
536 pic16_emitcode("add","a,#0x%02x",
538 ((char)(sym->stack - _G.nRegsSaved )) :
539 ((char)sym->stack)) & 0xff);
542 pic16_emitcode ("mov","dpx1,#0x40");
543 pic16_emitcode ("mov","dph1,#0x00");
544 pic16_emitcode ("mov","dpl1, a");
548 pic16_emitcode("pop","acc");
550 sym->aop = aop = newAsmop(AOP_DPTR2);
551 aop->size = getSize(sym->type);
555 //DEBUGpic16_emitcode(";","%d",__LINE__);
556 /* if in bit space */
557 if (IN_BITSPACE(space)) {
558 sym->aop = aop = newAsmop (AOP_CRY);
559 aop->aopu.aop_dir = sym->rname ;
560 aop->size = getSize(sym->type);
561 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
564 /* if it is in direct space */
565 if (IN_DIRSPACE(space)) {
566 sym->aop = aop = newAsmop (AOP_DIR);
567 aop->aopu.aop_dir = sym->rname ;
568 aop->size = getSize(sym->type);
569 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
573 /* special case for a function */
574 if (IS_FUNC(sym->type)) {
575 sym->aop = aop = newAsmop(AOP_IMMD);
576 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
577 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
578 strcpy(aop->aopu.aop_immd,sym->rname);
579 aop->size = FPTRSIZE;
580 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
585 /* only remaining is far space */
586 /* in which case DPTR gets the address */
587 sym->aop = aop = newAsmop(AOP_PCODE);
589 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
590 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
591 PCOI(aop->aopu.pcop)->index = 0;
593 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
594 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
596 pic16_allocDirReg (IC_LEFT(ic));
598 aop->size = FPTRSIZE;
600 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
601 sym->aop = aop = newAsmop(AOP_DPTR);
602 pic16_emitcode ("mov","dptr,#%s", sym->rname);
603 aop->size = getSize(sym->type);
605 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
608 /* if it is in code space */
609 if (IN_CODESPACE(space))
615 /*-----------------------------------------------------------------*/
616 /* aopForRemat - rematerialzes an object */
617 /*-----------------------------------------------------------------*/
618 static asmop *aopForRemat (operand *op) // x symbol *sym)
620 symbol *sym = OP_SYMBOL(op);
622 asmop *aop = newAsmop(AOP_PCODE);
626 ic = sym->rematiCode;
628 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
629 if(IS_OP_POINTER(op)) {
630 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
634 val += (int) operandLitValue(IC_RIGHT(ic));
635 } else if (ic->op == '-') {
636 val -= (int) operandLitValue(IC_RIGHT(ic));
640 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
643 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
644 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
646 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
648 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
650 PCOI(aop->aopu.pcop)->index = val;
652 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
653 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
655 val, IS_PTR_CONST(operandType(op)));
657 val, IS_CODEPTR(operandType(op)));
660 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
662 pic16_allocDirReg (IC_LEFT(ic));
667 static int aopIdx (asmop *aop, int offset)
672 if(aop->type != AOP_REG)
675 return aop->aopu.aop_reg[offset]->rIdx;
678 /*-----------------------------------------------------------------*/
679 /* regsInCommon - two operands have some registers in common */
680 /*-----------------------------------------------------------------*/
681 static bool regsInCommon (operand *op1, operand *op2)
686 /* if they have registers in common */
687 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
690 sym1 = OP_SYMBOL(op1);
691 sym2 = OP_SYMBOL(op2);
693 if (sym1->nRegs == 0 || sym2->nRegs == 0)
696 for (i = 0 ; i < sym1->nRegs ; i++) {
701 for (j = 0 ; j < sym2->nRegs ;j++ ) {
705 if (sym2->regs[j] == sym1->regs[i])
713 /*-----------------------------------------------------------------*/
714 /* operandsEqu - equivalent */
715 /*-----------------------------------------------------------------*/
716 static bool operandsEqu ( operand *op1, operand *op2)
720 /* if they not symbols */
721 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
724 sym1 = OP_SYMBOL(op1);
725 sym2 = OP_SYMBOL(op2);
727 /* if both are itemps & one is spilt
728 and the other is not then false */
729 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
730 sym1->isspilt != sym2->isspilt )
733 /* if they are the same */
737 if (strcmp(sym1->rname,sym2->rname) == 0)
741 /* if left is a tmp & right is not */
745 (sym1->usl.spillLoc == sym2))
752 (sym2->usl.spillLoc == sym1))
758 /*-----------------------------------------------------------------*/
759 /* pic16_sameRegs - two asmops have the same registers */
760 /*-----------------------------------------------------------------*/
761 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
768 if (aop1->type != AOP_REG ||
769 aop2->type != AOP_REG )
772 if (aop1->size != aop2->size )
775 for (i = 0 ; i < aop1->size ; i++ )
776 if (aop1->aopu.aop_reg[i] !=
777 aop2->aopu.aop_reg[i] )
783 /*-----------------------------------------------------------------*/
784 /* pic16_aopOp - allocates an asmop for an operand : */
785 /*-----------------------------------------------------------------*/
786 void pic16_aopOp (operand *op, iCode *ic, bool result)
795 // DEBUGpic16_emitcode(";","%d",__LINE__);
797 /* if this a literal */
798 if (IS_OP_LITERAL(op)) {
799 op->aop = aop = newAsmop(AOP_LIT);
800 aop->aopu.aop_lit = op->operand.valOperand;
801 aop->size = getSize(operandType(op));
806 sym_link *type = operandType(op);
808 if(IS_PTR_CONST(type))
812 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
815 /* if already has a asmop then continue */
819 /* if the underlying symbol has a aop */
820 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
821 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
822 op->aop = OP_SYMBOL(op)->aop;
826 /* if this is a true symbol */
827 if (IS_TRUE_SYMOP(op)) {
828 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
829 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
833 /* this is a temporary : this has
839 e) can be a return use only */
843 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
844 /* if the type is a conditional */
845 if (sym->regType == REG_CND) {
846 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
851 /* if it is spilt then two situations
853 b) has a spill location */
854 if (sym->isspilt || sym->nRegs == 0) {
856 DEBUGpic16_emitcode(";","%d",__LINE__);
857 /* rematerialize it NOW */
860 sym->aop = op->aop = aop =
862 aop->size = getSize(sym->type);
863 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
869 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
870 aop->size = getSize(sym->type);
871 for ( i = 0 ; i < 2 ; i++ )
872 aop->aopu.aop_str[i] = accUse[i];
873 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
879 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
880 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
881 //pic16_allocDirReg (IC_LEFT(ic));
882 aop->size = getSize(sym->type);
887 aop = op->aop = sym->aop = newAsmop(AOP_STR);
888 aop->size = getSize(sym->type);
889 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
890 aop->aopu.aop_str[i] = fReturn[i];
892 DEBUGpic16_emitcode(";","%d",__LINE__);
896 /* else spill location */
897 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
898 /* force a new aop if sizes differ */
899 sym->usl.spillLoc->aop = NULL;
901 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
902 __FUNCTION__,__LINE__,
903 sym->usl.spillLoc->rname,
904 sym->rname, sym->usl.spillLoc->offset);
906 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
907 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
908 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
910 sym->usl.spillLoc->offset);
911 aop->size = getSize(sym->type);
917 sym_link *type = operandType(op);
919 if(IS_PTR_CONST(type))
923 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
926 /* must be in a register */
927 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
928 sym->aop = op->aop = aop = newAsmop(AOP_REG);
929 aop->size = sym->nRegs;
930 for ( i = 0 ; i < sym->nRegs ;i++)
931 aop->aopu.aop_reg[i] = sym->regs[i];
934 /*-----------------------------------------------------------------*/
935 /* pic16_freeAsmop - free up the asmop given to an operand */
936 /*----------------------------------------------------------------*/
937 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
954 /* depending on the asmop type only three cases need work AOP_RO
955 , AOP_R1 && AOP_STK */
961 pic16_emitcode ("pop","ar0");
965 bitVectUnSetBit(ic->rUsed,R0_IDX);
971 pic16_emitcode ("pop","ar1");
975 bitVectUnSetBit(ic->rUsed,R1_IDX);
981 int stk = aop->aopu.aop_stk + aop->size;
982 bitVectUnSetBit(ic->rUsed,R0_IDX);
983 bitVectUnSetBit(ic->rUsed,R1_IDX);
985 getFreePtr(ic,&aop,FALSE);
987 if (options.stack10bit)
989 /* I'm not sure what to do here yet... */
992 "*** Warning: probably generating bad code for "
993 "10 bit stack mode.\n");
997 pic16_emitcode ("mov","a,_bp");
998 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
999 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1001 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1005 pic16_emitcode("pop","acc");
1006 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1008 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1011 pic16_freeAsmop(op,NULL,ic,TRUE);
1013 pic16_emitcode("pop","ar0");
1018 pic16_emitcode("pop","ar1");
1026 /* all other cases just dealloc */
1030 OP_SYMBOL(op)->aop = NULL;
1031 /* if the symbol has a spill */
1033 SPIL_LOC(op)->aop = NULL;
1038 /*-----------------------------------------------------------------*/
1039 /* pic16_aopGet - for fetching value of the aop */
1040 /*-----------------------------------------------------------------*/
1041 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1046 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1047 /* offset is greater than
1049 if (offset > (aop->size - 1) &&
1050 aop->type != AOP_LIT)
1053 /* depending on type */
1054 switch (aop->type) {
1058 DEBUGpic16_emitcode(";","%d",__LINE__);
1059 /* if we need to increment it */
1060 while (offset > aop->coff) {
1061 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1065 while (offset < aop->coff) {
1066 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1070 aop->coff = offset ;
1072 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1073 return (dname ? "acc" : "a");
1075 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1076 rs = Safe_calloc(1,strlen(s)+1);
1082 DEBUGpic16_emitcode(";","%d",__LINE__);
1083 if (aop->type == AOP_DPTR2)
1088 while (offset > aop->coff) {
1089 pic16_emitcode ("inc","dptr");
1093 while (offset < aop->coff) {
1094 pic16_emitcode("lcall","__decdptr");
1100 pic16_emitcode("clr","a");
1101 pic16_emitcode("movc","a,@a+dptr");
1104 pic16_emitcode("movx","a,@dptr");
1107 if (aop->type == AOP_DPTR2)
1112 return (dname ? "acc" : "a");
1117 sprintf (s,"%s",aop->aopu.aop_immd);
1120 sprintf(s,"(%s >> %d)",
1125 aop->aopu.aop_immd);
1126 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1127 rs = Safe_calloc(1,strlen(s)+1);
1133 sprintf(s,"(%s + %d)",
1136 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1138 sprintf(s,"%s",aop->aopu.aop_dir);
1139 rs = Safe_calloc(1,strlen(s)+1);
1145 // return aop->aopu.aop_reg[offset]->dname;
1147 return aop->aopu.aop_reg[offset]->name;
1150 //pic16_emitcode(";","%d",__LINE__);
1151 return aop->aopu.aop_dir;
1154 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1155 return "AOP_accumulator_bug";
1158 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1159 rs = Safe_calloc(1,strlen(s)+1);
1164 aop->coff = offset ;
1165 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1168 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1170 return aop->aopu.aop_str[offset];
1174 pCodeOp *pcop = aop->aopu.pcop;
1175 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1177 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1178 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1179 sprintf(s,"%s", pcop->name);
1181 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1184 rs = Safe_calloc(1,strlen(s)+1);
1190 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1191 "aopget got unsupported aop->type");
1196 /*-----------------------------------------------------------------*/
1197 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1198 /*-----------------------------------------------------------------*/
1199 pCodeOp *pic16_popGetTempReg(void)
1204 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1205 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1206 PCOR(pcop)->r->wasUsed=1;
1207 PCOR(pcop)->r->isFree=0;
1213 /*-----------------------------------------------------------------*/
1214 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1215 /*-----------------------------------------------------------------*/
1216 void pic16_popReleaseTempReg(pCodeOp *pcop)
1219 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1220 PCOR(pcop)->r->isFree = 1;
1223 /*-----------------------------------------------------------------*/
1224 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *pic16_popGetLabel(unsigned int key)
1229 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1234 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1237 /*-----------------------------------------------------------------*/
1238 /* pic16_popCopyReg - copy a pcode operator */
1239 /*-----------------------------------------------------------------*/
1240 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1244 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1245 pcor->pcop.type = pc->pcop.type;
1247 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1248 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1250 pcor->pcop.name = NULL;
1253 pcor->rIdx = pc->rIdx;
1256 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1261 /*-----------------------------------------------------------------*/
1262 /* pic16_popGetLit - asm operator to pcode operator conversion */
1263 /*-----------------------------------------------------------------*/
1264 pCodeOp *pic16_popGetLit(unsigned int lit)
1266 return pic16_newpCodeOpLit(lit);
1269 /*-----------------------------------------------------------------*/
1270 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1271 /*-----------------------------------------------------------------*/
1272 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1274 return pic16_newpCodeOpLit2(lit, arg2);
1278 /*-----------------------------------------------------------------*/
1279 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1280 /*-----------------------------------------------------------------*/
1281 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1284 return pic16_newpCodeOpImmd(name, offset,index, 0);
1288 /*-----------------------------------------------------------------*/
1289 /* pic16_popGet - asm operator to pcode operator conversion */
1290 /*-----------------------------------------------------------------*/
1291 pCodeOp *pic16_popGetWithString(char *str)
1297 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1301 pcop = pic16_newpCodeOp(str,PO_STR);
1306 /*-----------------------------------------------------------------*/
1307 /* pic16_popRegFromString - */
1308 /*-----------------------------------------------------------------*/
1309 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1312 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1313 pcop->type = PO_DIR;
1315 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1316 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1321 pcop->name = Safe_calloc(1,strlen(str)+1);
1322 strcpy(pcop->name,str);
1324 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1326 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1327 if(PCOR(pcop)->r == NULL) {
1328 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1329 // __FUNCTION__, __LINE__, str, size, offset);
1330 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1332 //fprintf(stderr, "allocating new register -> %s\n", str);
1334 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1336 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1338 PCOR(pcop)->instance = offset;
1343 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1347 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1349 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1350 PCOR(pcop)->rIdx = rIdx;
1351 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1352 PCOR(pcop)->r->isFree = 0;
1353 PCOR(pcop)->r->wasUsed = 1;
1355 pcop->type = PCOR(pcop)->r->pc_type;
1360 /*---------------------------------------------------------------------------------*/
1361 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1363 /*---------------------------------------------------------------------------------*/
1364 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1369 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1371 /* comment the following check, so errors to throw up */
1372 // if(!pcop2)return NULL;
1374 temp = pic16_popGet(aop_dst, offset);
1375 pcop2->pcop2 = temp;
1380 /*---------------------------------------------------------------------------------*/
1381 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1382 /* movff instruction */
1383 /*---------------------------------------------------------------------------------*/
1384 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1389 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1390 pcop2->pcop2 = pic16_popCopyReg(dst);
1392 /* the pCodeOp may be already allocated */
1393 pcop2 = (pCodeOpReg2 *)(src);
1394 pcop2->pcop2 = (pCodeOp *)(dst);
1401 /*-----------------------------------------------------------------*/
1402 /* pic16_popGet - asm operator to pcode operator conversion */
1403 /*-----------------------------------------------------------------*/
1404 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1406 //char *s = buffer ;
1411 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1412 /* offset is greater than
1415 if (offset > (aop->size - 1) &&
1416 aop->type != AOP_LIT)
1417 return NULL; //zero;
1419 /* depending on type */
1420 switch (aop->type) {
1427 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1428 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1432 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1433 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1436 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1437 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1441 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1443 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1444 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1445 PCOR(pcop)->rIdx = rIdx;
1446 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1447 PCOR(pcop)->r->wasUsed=1;
1448 PCOR(pcop)->r->isFree=0;
1450 PCOR(pcop)->instance = offset;
1451 pcop->type = PCOR(pcop)->r->pc_type;
1452 //rs = aop->aopu.aop_reg[offset]->name;
1453 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1458 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1460 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1461 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1462 //if(PCOR(pcop)->r == NULL)
1463 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1467 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1468 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1471 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1472 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1475 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1476 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1477 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1478 pcop->type = PCOR(pcop)->r->pc_type;
1479 pcop->name = PCOR(pcop)->r->name;
1485 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1487 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1488 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1489 PCOI(pcop)->offset = offset;
1493 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1494 "pic16_popGet got unsupported aop->type");
1497 /*-----------------------------------------------------------------*/
1498 /* pic16_aopPut - puts a string for a aop */
1499 /*-----------------------------------------------------------------*/
1500 void pic16_aopPut (asmop *aop, char *s, int offset)
1505 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1507 if (aop->size && offset > ( aop->size - 1)) {
1508 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1509 "pic16_aopPut got offset > aop->size");
1513 /* will assign value to value */
1514 /* depending on where it is ofcourse */
1515 switch (aop->type) {
1518 sprintf(d,"(%s + %d)",
1519 aop->aopu.aop_dir,offset);
1520 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1523 sprintf(d,"%s",aop->aopu.aop_dir);
1526 DEBUGpic16_emitcode(";","%d",__LINE__);
1528 pic16_emitcode("movf","%s,w",s);
1529 pic16_emitcode("movwf","%s",d);
1532 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1533 if(offset >= aop->size) {
1534 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1537 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1540 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1547 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1548 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1551 strcmp(s,"r0") == 0 ||
1552 strcmp(s,"r1") == 0 ||
1553 strcmp(s,"r2") == 0 ||
1554 strcmp(s,"r3") == 0 ||
1555 strcmp(s,"r4") == 0 ||
1556 strcmp(s,"r5") == 0 ||
1557 strcmp(s,"r6") == 0 ||
1558 strcmp(s,"r7") == 0 )
1559 pic16_emitcode("mov","%s,%s ; %d",
1560 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1564 if(strcmp(s,"W")==0 )
1565 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1567 pic16_emitcode("movwf","%s",
1568 aop->aopu.aop_reg[offset]->name);
1570 if(strcmp(s,zero)==0) {
1571 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1573 } else if(strcmp(s,"W")==0) {
1574 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1575 pcop->type = PO_GPR_REGISTER;
1577 PCOR(pcop)->rIdx = -1;
1578 PCOR(pcop)->r = NULL;
1580 DEBUGpic16_emitcode(";","%d",__LINE__);
1581 pcop->name = Safe_strdup(s);
1582 pic16_emitpcode(POC_MOVFW,pcop);
1583 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1584 } else if(strcmp(s,one)==0) {
1585 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1586 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1588 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1596 if (aop->type == AOP_DPTR2)
1602 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1603 "pic16_aopPut writting to code space");
1607 while (offset > aop->coff) {
1609 pic16_emitcode ("inc","dptr");
1612 while (offset < aop->coff) {
1614 pic16_emitcode("lcall","__decdptr");
1619 /* if not in accumulater */
1622 pic16_emitcode ("movx","@dptr,a");
1624 if (aop->type == AOP_DPTR2)
1632 while (offset > aop->coff) {
1634 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1636 while (offset < aop->coff) {
1638 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1644 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1649 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1651 if (strcmp(s,"r0") == 0 ||
1652 strcmp(s,"r1") == 0 ||
1653 strcmp(s,"r2") == 0 ||
1654 strcmp(s,"r3") == 0 ||
1655 strcmp(s,"r4") == 0 ||
1656 strcmp(s,"r5") == 0 ||
1657 strcmp(s,"r6") == 0 ||
1658 strcmp(s,"r7") == 0 ) {
1660 sprintf(buffer,"a%s",s);
1661 pic16_emitcode("mov","@%s,%s",
1662 aop->aopu.aop_ptr->name,buffer);
1664 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1669 if (strcmp(s,"a") == 0)
1670 pic16_emitcode("push","acc");
1672 pic16_emitcode("push","%s",s);
1677 /* if bit variable */
1678 if (!aop->aopu.aop_dir) {
1679 pic16_emitcode("clr","a");
1680 pic16_emitcode("rlc","a");
1683 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1686 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1689 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1691 lbl = newiTempLabel(NULL);
1693 if (strcmp(s,"a")) {
1696 pic16_emitcode("clr","c");
1697 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1698 pic16_emitcode("cpl","c");
1699 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1700 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1707 if (strcmp(aop->aopu.aop_str[offset],s))
1708 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1713 if (!offset && (strcmp(s,"acc") == 0))
1716 if (strcmp(aop->aopu.aop_str[offset],s))
1717 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1721 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1722 "pic16_aopPut got unsupported aop->type");
1728 /*-----------------------------------------------------------------*/
1729 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1730 /*-----------------------------------------------------------------*/
1731 static void mov2w (asmop *aop, int offset)
1737 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1739 if ( aop->type == AOP_PCODE ||
1740 aop->type == AOP_LIT )
1741 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1743 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1748 void pic16_pushpCodeOpReg(pCodeOpReg *pcop)
1750 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pcop, &pic16_pc_postdec1, 0));
1753 void pic16_poppCodeOpReg(pCodeOpReg *pcop)
1755 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, pcop, 0));
1759 /*-----------------------------------------------------------------*/
1760 /* pushw - pushes wreg to stack */
1761 /*-----------------------------------------------------------------*/
1764 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1765 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1769 /*-----------------------------------------------------------------*/
1770 /* pushaop - pushes aop to stack */
1771 /*-----------------------------------------------------------------*/
1772 void pushaop(asmop *aop, int offset)
1774 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1775 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1778 /*-----------------------------------------------------------------*/
1779 /* popaop - pops aop from stack */
1780 /*-----------------------------------------------------------------*/
1781 void popaop(asmop *aop, int offset)
1783 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1784 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1787 void popaopidx(asmop *aop, int offset, int index)
1791 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1793 if(STACK_MODEL_LARGE)ofs++;
1795 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1796 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1799 /*-----------------------------------------------------------------*/
1800 /* reAdjustPreg - points a register back to where it should */
1801 /*-----------------------------------------------------------------*/
1802 static void reAdjustPreg (asmop *aop)
1806 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1808 if ((size = aop->size) <= 1)
1811 switch (aop->type) {
1815 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1819 if (aop->type == AOP_DPTR2)
1825 pic16_emitcode("lcall","__decdptr");
1828 if (aop->type == AOP_DPTR2)
1840 /*-----------------------------------------------------------------*/
1841 /* opIsGptr: returns non-zero if the passed operand is */
1842 /* a generic pointer type. */
1843 /*-----------------------------------------------------------------*/
1844 static int opIsGptr(operand *op)
1846 sym_link *type = operandType(op);
1848 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1849 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1857 /*-----------------------------------------------------------------*/
1858 /* pic16_getDataSize - get the operand data size */
1859 /*-----------------------------------------------------------------*/
1860 int pic16_getDataSize(operand *op)
1862 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1865 return AOP_SIZE(op);
1867 // tsd- in the pic port, the genptr size is 1, so this code here
1868 // fails. ( in the 8051 port, the size was 4).
1871 size = AOP_SIZE(op);
1872 if (size == GPTRSIZE)
1874 sym_link *type = operandType(op);
1875 if (IS_GENPTR(type))
1877 /* generic pointer; arithmetic operations
1878 * should ignore the high byte (pointer type).
1881 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1888 /*-----------------------------------------------------------------*/
1889 /* pic16_outAcc - output Acc */
1890 /*-----------------------------------------------------------------*/
1891 void pic16_outAcc(operand *result)
1894 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1895 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1898 size = pic16_getDataSize(result);
1900 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1903 /* unsigned or positive */
1905 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1910 /*-----------------------------------------------------------------*/
1911 /* pic16_outBitC - output a bit C */
1912 /*-----------------------------------------------------------------*/
1913 void pic16_outBitC(operand *result)
1916 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1917 /* if the result is bit */
1918 if (AOP_TYPE(result) == AOP_CRY)
1919 pic16_aopPut(AOP(result),"c",0);
1921 pic16_emitcode("clr","a ; %d", __LINE__);
1922 pic16_emitcode("rlc","a");
1923 pic16_outAcc(result);
1927 /*-----------------------------------------------------------------*/
1928 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1929 /*-----------------------------------------------------------------*/
1930 void pic16_toBoolean(operand *oper)
1932 int size = AOP_SIZE(oper) - 1;
1935 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1937 if ( AOP_TYPE(oper) != AOP_ACC) {
1938 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1941 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1946 #if !defined(GEN_Not)
1947 /*-----------------------------------------------------------------*/
1948 /* genNot - generate code for ! operation */
1949 /*-----------------------------------------------------------------*/
1950 static void pic16_genNot (iCode *ic)
1955 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1956 /* assign asmOps to operand & result */
1957 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1958 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1960 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1961 /* if in bit space then a special case */
1962 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1963 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1964 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1965 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1967 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1968 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1969 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1974 size = AOP_SIZE(IC_LEFT(ic));
1976 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1977 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1978 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1981 pic16_toBoolean(IC_LEFT(ic));
1983 tlbl = newiTempLabel(NULL);
1984 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1985 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1986 pic16_outBitC(IC_RESULT(ic));
1989 /* release the aops */
1990 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1991 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1996 #if !defined(GEN_Cpl)
1997 /*-----------------------------------------------------------------*/
1998 /* genCpl - generate code for complement */
1999 /*-----------------------------------------------------------------*/
2000 static void pic16_genCpl (iCode *ic)
2006 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2007 /* assign asmOps to operand & result */
2008 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2009 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2011 /* if both are in bit space then
2013 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2014 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2016 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2017 pic16_emitcode("cpl","c");
2018 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2022 size = AOP_SIZE(IC_RESULT(ic));
2025 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2027 pic16_emitcode("cpl","a");
2028 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2030 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2031 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2033 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2034 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2042 /* release the aops */
2043 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2044 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2048 /*-----------------------------------------------------------------*/
2049 /* genUminusFloat - unary minus for floating points */
2050 /*-----------------------------------------------------------------*/
2051 static void genUminusFloat(operand *op,operand *result)
2053 int size ,offset =0 ;
2056 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2057 /* for this we just need to flip the
2058 first it then copy the rest in place */
2059 size = AOP_SIZE(op) - 1;
2060 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2064 pic16_emitcode("cpl","acc.7");
2065 pic16_aopPut(AOP(result),"a",3);
2068 pic16_aopPut(AOP(result),
2069 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2075 /*-----------------------------------------------------------------*/
2076 /* genUminus - unary minus code generation */
2077 /*-----------------------------------------------------------------*/
2078 static void genUminus (iCode *ic)
2081 sym_link *optype, *rtype;
2084 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2086 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2087 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2089 /* if both in bit space then special
2091 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2092 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2094 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2095 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2096 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2101 optype = operandType(IC_LEFT(ic));
2102 rtype = operandType(IC_RESULT(ic));
2104 /* if float then do float stuff */
2105 if (IS_FLOAT(optype)) {
2106 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2110 /* otherwise subtract from zero by taking the 2's complement */
2111 size = AOP_SIZE(IC_LEFT(ic));
2113 for(i=0; i<size; i++) {
2114 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2115 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2117 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2118 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2122 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2123 for(i=1; i<size; i++) {
2125 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2129 /* release the aops */
2130 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2131 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2134 /*-----------------------------------------------------------------*/
2135 /* saveRegisters - will look for a call and save the registers */
2136 /*-----------------------------------------------------------------*/
2137 static void saveRegisters(iCode *lic)
2144 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2146 for (ic = lic ; ic ; ic = ic->next)
2147 if (ic->op == CALL || ic->op == PCALL)
2151 fprintf(stderr,"found parameter push with no function call\n");
2155 /* if the registers have been saved already then
2157 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2160 /* find the registers in use at this time
2161 and push them away to safety */
2162 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2166 if (options.useXstack) {
2167 if (bitVectBitValue(rsave,R0_IDX))
2168 pic16_emitcode("mov","b,r0");
2169 pic16_emitcode("mov","r0,%s",spname);
2170 for (i = 0 ; i < pic16_nRegs ; i++) {
2171 if (bitVectBitValue(rsave,i)) {
2173 pic16_emitcode("mov","a,b");
2175 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2176 pic16_emitcode("movx","@r0,a");
2177 pic16_emitcode("inc","r0");
2180 pic16_emitcode("mov","%s,r0",spname);
2181 if (bitVectBitValue(rsave,R0_IDX))
2182 pic16_emitcode("mov","r0,b");
2184 //for (i = 0 ; i < pic16_nRegs ; i++) {
2185 // if (bitVectBitValue(rsave,i))
2186 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2189 dtype = operandType(IC_LEFT(ic));
2190 if (currFunc && dtype &&
2191 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2192 IFFUNC_ISISR(currFunc->type) &&
2195 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2198 /*-----------------------------------------------------------------*/
2199 /* unsaveRegisters - pop the pushed registers */
2200 /*-----------------------------------------------------------------*/
2201 static void unsaveRegisters (iCode *ic)
2206 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2207 /* find the registers in use at this time
2208 and push them away to safety */
2209 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2212 if (options.useXstack) {
2213 pic16_emitcode("mov","r0,%s",spname);
2214 for (i = pic16_nRegs ; i >= 0 ; i--) {
2215 if (bitVectBitValue(rsave,i)) {
2216 pic16_emitcode("dec","r0");
2217 pic16_emitcode("movx","a,@r0");
2219 pic16_emitcode("mov","b,a");
2221 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2225 pic16_emitcode("mov","%s,r0",spname);
2226 if (bitVectBitValue(rsave,R0_IDX))
2227 pic16_emitcode("mov","r0,b");
2229 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2230 // if (bitVectBitValue(rsave,i))
2231 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2237 /*-----------------------------------------------------------------*/
2239 /*-----------------------------------------------------------------*/
2240 static void pushSide(operand * oper, int size)
2244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2246 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2247 if (AOP_TYPE(oper) != AOP_REG &&
2248 AOP_TYPE(oper) != AOP_DIR &&
2250 pic16_emitcode("mov","a,%s",l);
2251 pic16_emitcode("push","acc");
2253 pic16_emitcode("push","%s",l);
2258 /*-----------------------------------------------------------------*/
2259 /* assignResultValue - */
2260 /*-----------------------------------------------------------------*/
2261 static void assignResultValue(operand * oper)
2263 int size = AOP_SIZE(oper);
2265 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2266 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2268 if(!GpsuedoStkPtr) {
2269 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2270 /* The last byte in the assignment is in W */
2272 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2277 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2278 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2282 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2284 pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2287 pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2288 #endif /* STACK_SUPPORT */
2293 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2295 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2303 /*-----------------------------------------------------------------*/
2304 /* genIpush - genrate code for pushing this gets a little complex */
2305 /*-----------------------------------------------------------------*/
2306 static void genIpush (iCode *ic)
2309 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2311 int size, offset = 0 ;
2315 /* if this is not a parm push : ie. it is spill push
2316 and spill push is always done on the local stack */
2317 if (!ic->parmPush) {
2319 /* and the item is spilt then do nothing */
2320 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2323 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2324 size = AOP_SIZE(IC_LEFT(ic));
2325 /* push it on the stack */
2327 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2332 pic16_emitcode("push","%s",l);
2337 /* this is a paramter push: in this case we call
2338 the routine to find the call and save those
2339 registers that need to be saved */
2342 /* then do the push */
2343 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2346 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2347 size = AOP_SIZE(IC_LEFT(ic));
2350 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2351 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2352 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2354 pic16_emitcode("mov","a,%s",l);
2355 pic16_emitcode("push","acc");
2357 pic16_emitcode("push","%s",l);
2360 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2364 /*-----------------------------------------------------------------*/
2365 /* genIpop - recover the registers: can happen only for spilling */
2366 /*-----------------------------------------------------------------*/
2367 static void genIpop (iCode *ic)
2369 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2374 /* if the temp was not pushed then */
2375 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2378 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2379 size = AOP_SIZE(IC_LEFT(ic));
2382 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2385 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2389 /*-----------------------------------------------------------------*/
2390 /* unsaverbank - restores the resgister bank from stack */
2391 /*-----------------------------------------------------------------*/
2392 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2394 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2400 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2402 if (options.useXstack) {
2404 r = getFreePtr(ic,&aop,FALSE);
2407 pic16_emitcode("mov","%s,_spx",r->name);
2408 pic16_emitcode("movx","a,@%s",r->name);
2409 pic16_emitcode("mov","psw,a");
2410 pic16_emitcode("dec","%s",r->name);
2413 pic16_emitcode ("pop","psw");
2416 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2417 if (options.useXstack) {
2418 pic16_emitcode("movx","a,@%s",r->name);
2419 //pic16_emitcode("mov","(%s+%d),a",
2420 // regspic16[i].base,8*bank+regspic16[i].offset);
2421 pic16_emitcode("dec","%s",r->name);
2424 pic16_emitcode("pop",""); //"(%s+%d)",
2425 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2428 if (options.useXstack) {
2430 pic16_emitcode("mov","_spx,%s",r->name);
2431 pic16_freeAsmop(NULL,aop,ic,TRUE);
2437 /*-----------------------------------------------------------------*/
2438 /* saverbank - saves an entire register bank on the stack */
2439 /*-----------------------------------------------------------------*/
2440 static void saverbank (int bank, iCode *ic, bool pushPsw)
2442 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2448 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2449 if (options.useXstack) {
2452 r = getFreePtr(ic,&aop,FALSE);
2453 pic16_emitcode("mov","%s,_spx",r->name);
2457 for (i = 0 ; i < pic16_nRegs ;i++) {
2458 if (options.useXstack) {
2459 pic16_emitcode("inc","%s",r->name);
2460 //pic16_emitcode("mov","a,(%s+%d)",
2461 // regspic16[i].base,8*bank+regspic16[i].offset);
2462 pic16_emitcode("movx","@%s,a",r->name);
2464 pic16_emitcode("push","");// "(%s+%d)",
2465 //regspic16[i].base,8*bank+regspic16[i].offset);
2469 if (options.useXstack) {
2470 pic16_emitcode("mov","a,psw");
2471 pic16_emitcode("movx","@%s,a",r->name);
2472 pic16_emitcode("inc","%s",r->name);
2473 pic16_emitcode("mov","_spx,%s",r->name);
2474 pic16_freeAsmop (NULL,aop,ic,TRUE);
2477 pic16_emitcode("push","psw");
2479 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2487 /*-----------------------------------------------------------------*/
2488 /* genCall - generates a call statement */
2489 /*-----------------------------------------------------------------*/
2490 static void genCall (iCode *ic)
2495 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2497 /* if caller saves & we have not saved then */
2501 /* if we are calling a function that is not using
2502 * the same register bank then we need to save the
2503 * destination registers on the stack */
2504 dtype = operandType(IC_LEFT(ic));
2505 if (currFunc && dtype &&
2506 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2507 IFFUNC_ISISR(currFunc->type) &&
2510 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2512 /* if send set is not empty the assign */
2516 /* For the Pic port, there is no data stack.
2517 * So parameters passed to functions are stored
2518 * in registers. (The pCode optimizer will get
2519 * rid of most of these :). */
2521 int psuedoStkPtr=-1;
2522 int firstTimeThruLoop = 1;
2524 _G.sendSet = reverseSet(_G.sendSet);
2526 /* First figure how many parameters are getting passed */
2527 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2528 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2529 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2530 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2533 stackParms = psuedoStkPtr;
2535 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2536 int size, offset = 0;
2538 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2539 size = AOP_SIZE(IC_LEFT(sic));
2542 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2543 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2544 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2546 if(!firstTimeThruLoop) {
2547 /* If this is not the first time we've been through the loop
2548 * then we need to save the parameter in a temporary
2549 * register. The last byte of the last parameter is
2555 --psuedoStkPtr; // sanity check
2557 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2560 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2561 #endif /* STACK_SUPPORT */
2564 firstTimeThruLoop=0;
2566 mov2w (AOP(IC_LEFT(sic)), offset);
2569 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2575 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2576 OP_SYMBOL(IC_LEFT(ic))->rname :
2577 OP_SYMBOL(IC_LEFT(ic))->name));
2580 /* if we need assign a result value */
2581 if ((IS_ITEMP(IC_RESULT(ic)) &&
2582 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2583 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2584 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2587 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2590 assignResultValue(IC_RESULT(ic));
2592 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2593 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2595 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2599 if(USE_STACK && stackParms>0) {
2600 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2601 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2602 if(STACK_MODEL_LARGE) {
2604 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2609 /* adjust the stack for parameters if required */
2610 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2612 if (ic->parmBytes) {
2615 if (ic->parmBytes > 3) {
2616 pic16_emitcode("mov","a,%s",spname);
2617 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2618 pic16_emitcode("mov","%s,a",spname);
2620 for ( i = 0 ; i < ic->parmBytes ;i++)
2621 pic16_emitcode("dec","%s",spname);
2624 /* if register bank was saved then pop them */
2626 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2628 /* if we hade saved some registers then unsave them */
2629 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2630 unsaveRegisters (ic);
2633 /*-----------------------------------------------------------------*/
2634 /* genPcall - generates a call by pointer statement */
2635 /*-----------------------------------------------------------------*/
2636 static void genPcall (iCode *ic)
2639 symbol *rlbl = newiTempLabel(NULL);
2642 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2643 /* if caller saves & we have not saved then */
2647 /* if we are calling a function that is not using
2648 the same register bank then we need to save the
2649 destination registers on the stack */
2650 dtype = operandType(IC_LEFT(ic));
2651 if (currFunc && dtype &&
2652 IFFUNC_ISISR(currFunc->type) &&
2653 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2654 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2657 /* push the return address on to the stack */
2658 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2659 pic16_emitcode("push","acc");
2660 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2661 pic16_emitcode("push","acc");
2663 if (options.model == MODEL_FLAT24)
2665 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2666 pic16_emitcode("push","acc");
2669 /* now push the calling address */
2670 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2672 pushSide(IC_LEFT(ic), FPTRSIZE);
2674 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2676 /* if send set is not empty the assign */
2680 for (sic = setFirstItem(_G.sendSet) ; sic ;
2681 sic = setNextItem(_G.sendSet)) {
2682 int size, offset = 0;
2683 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2684 size = AOP_SIZE(IC_LEFT(sic));
2686 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2688 if (strcmp(l,fReturn[offset]))
2689 pic16_emitcode("mov","%s,%s",
2694 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2699 pic16_emitcode("ret","");
2700 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2703 /* if we need assign a result value */
2704 if ((IS_ITEMP(IC_RESULT(ic)) &&
2705 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2706 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2707 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2710 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2713 assignResultValue(IC_RESULT(ic));
2715 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2718 /* adjust the stack for parameters if
2720 if (ic->parmBytes) {
2722 if (ic->parmBytes > 3) {
2723 pic16_emitcode("mov","a,%s",spname);
2724 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2725 pic16_emitcode("mov","%s,a",spname);
2727 for ( i = 0 ; i < ic->parmBytes ;i++)
2728 pic16_emitcode("dec","%s",spname);
2732 /* if register bank was saved then unsave them */
2733 if (currFunc && dtype &&
2734 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2735 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2737 /* if we hade saved some registers then
2740 unsaveRegisters (ic);
2744 /*-----------------------------------------------------------------*/
2745 /* resultRemat - result is rematerializable */
2746 /*-----------------------------------------------------------------*/
2747 static int resultRemat (iCode *ic)
2749 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2750 if (SKIP_IC(ic) || ic->op == IFX)
2753 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2754 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2755 if (sym->remat && !POINTER_SET(ic))
2762 #if defined(__BORLANDC__) || defined(_MSC_VER)
2763 #define STRCASECMP stricmp
2765 #define STRCASECMP strcasecmp
2769 /*-----------------------------------------------------------------*/
2770 /* inExcludeList - return 1 if the string is in exclude Reg list */
2771 /*-----------------------------------------------------------------*/
2772 static bool inExcludeList(char *s)
2774 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2777 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2778 if (options.excludeRegs[i] &&
2779 STRCASECMP(options.excludeRegs[i],"none") == 0)
2782 for ( i = 0 ; options.excludeRegs[i]; i++) {
2783 if (options.excludeRegs[i] &&
2784 STRCASECMP(s,options.excludeRegs[i]) == 0)
2791 /*-----------------------------------------------------------------*/
2792 /* genFunction - generated code for function entry */
2793 /*-----------------------------------------------------------------*/
2794 static void genFunction (iCode *ic)
2799 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2801 labelOffset += (max_key+4);
2805 /* create the function header */
2806 pic16_emitcode(";","-----------------------------------------");
2807 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2808 pic16_emitcode(";","-----------------------------------------");
2810 pic16_emitcode("","%s:",sym->rname);
2811 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
2816 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
2817 if(strcmp(ab->name, sym->name)) {
2818 pic16_pBlockConvert2Absolute(pb);
2824 ftype = operandType(IC_LEFT(ic));
2826 if(IFFUNC_ISNAKED(ftype)) {
2827 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
2832 /* if critical function then turn interrupts off */
2833 if (IFFUNC_ISCRITICAL(ftype))
2834 pic16_emitcode("clr","ea");
2836 /* here we need to generate the equates for the
2837 * register bank if required */
2839 if (FUNC_REGBANK(ftype) != rbank) {
2842 rbank = FUNC_REGBANK(ftype);
2843 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2844 if (strcmp(regspic16[i].base,"0") == 0)
2845 pic16_emitcode("","%s = 0x%02x",
2847 8*rbank+regspic16[i].offset);
2849 pic16_emitcode ("","%s = %s + 0x%02x",
2852 *rbank+regspic16[i].offset);
2857 /* if this is an interrupt service routine then
2858 * save acc, b, dpl, dph */
2859 if (IFFUNC_ISISR(sym->type)) {
2860 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2861 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2862 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2863 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2865 pic16_pBlockConvert2ISR(pb);
2867 if (!inExcludeList("acc"))
2868 pic16_emitcode ("push","acc");
2869 if (!inExcludeList("b"))
2870 pic16_emitcode ("push","b");
2871 if (!inExcludeList("dpl"))
2872 pic16_emitcode ("push","dpl");
2873 if (!inExcludeList("dph"))
2874 pic16_emitcode ("push","dph");
2876 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) {
2877 pic16_emitcode ("push", "dpx");
2879 /* Make sure we're using standard DPTR */
2880 pic16_emitcode ("push", "dps");
2881 pic16_emitcode ("mov", "dps, #0x00");
2882 if (options.stack10bit) {
2883 /* This ISR could conceivably use DPTR2. Better save it. */
2884 pic16_emitcode ("push", "dpl1");
2885 pic16_emitcode ("push", "dph1");
2886 pic16_emitcode ("push", "dpx1");
2890 /* if this isr has no bank i.e. is going to
2891 * run with bank 0 , then we need to save more
2893 if (!FUNC_REGBANK(sym->type)) {
2895 /* if this function does not call any other
2896 * function then we can be economical and
2897 * save only those registers that are used */
2898 if (! IFFUNC_HASFCALL(sym->type)) {
2901 /* if any registers used */
2902 if (sym->regsUsed) {
2903 /* save the registers used */
2904 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2905 if (bitVectBitValue(sym->regsUsed,i) ||
2906 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2907 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2912 /* this function has a function call cannot
2913 * determines register usage so we will have the
2915 saverbank(0,ic,FALSE);
2921 /* emit code to setup stack frame if user enabled,
2922 * and function is not main() */
2924 // fprintf(stderr, "function name: %s\n", sym->name);
2925 if(USE_STACK && strcmp(sym->name, "main")) {
2926 if(!options.ommitFramePtr || sym->regsUsed) {
2927 /* setup the stack frame */
2928 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
2929 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
2930 if(STACK_MODEL_LARGE)
2931 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
2936 /* if callee-save to be used for this function
2937 * then save the registers being used in this function */
2938 if (IFFUNC_CALLEESAVES(sym->type)) {
2941 // fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
2943 /* if any registers used */
2949 /* save the registers used */
2950 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
2951 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2952 if (bitVectBitValue(sym->regsUsed,i)) {
2953 // fprintf(stderr, "%s:%d function %s uses register %s\n",
2954 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
2955 // pic16_regWithIdx(i)->name);
2957 pic16_pushpCodeOpReg( PCOR(pic16_popRegFromIdx(i) ));
2958 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
2959 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
2960 // &pic16_pc_postdec1, 0));
2971 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2973 if (options.useXstack) {
2974 pic16_emitcode("mov","r0,%s",spname);
2975 pic16_emitcode("mov","a,_bp");
2976 pic16_emitcode("movx","@r0,a");
2977 pic16_emitcode("inc","%s",spname);
2979 /* set up the stack */
2980 pic16_emitcode ("push","_bp"); /* save the callers stack */
2982 pic16_emitcode ("mov","_bp,%s",spname);
2985 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
2987 /* adjust the stack for the function */
2992 werror(W_STACK_OVERFLOW,sym->name);
2994 if (i > 3 && sym->recvSize < 4) {
2995 pic16_emitcode ("mov","a,sp");
2996 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2997 pic16_emitcode ("mov","sp,a");
3000 pic16_emitcode("inc","sp");
3004 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3006 pic16_emitcode ("mov","a,_spx");
3007 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3008 pic16_emitcode ("mov","_spx,a");
3013 /*-----------------------------------------------------------------*/
3014 /* genEndFunction - generates epilogue for functions */
3015 /*-----------------------------------------------------------------*/
3016 static void genEndFunction (iCode *ic)
3018 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3020 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3022 if(IFFUNC_ISNAKED(sym->type)) {
3023 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3028 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3030 pic16_emitcode ("mov","%s,_bp",spname);
3034 /* if use external stack but some variables were
3035 added to the local stack then decrement the
3037 if (options.useXstack && sym->stack) {
3038 pic16_emitcode("mov","a,sp");
3039 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3040 pic16_emitcode("mov","sp,a");
3045 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3046 if (options.useXstack) {
3047 pic16_emitcode("mov","r0,%s",spname);
3048 pic16_emitcode("movx","a,@r0");
3049 pic16_emitcode("mov","_bp,a");
3050 pic16_emitcode("dec","%s",spname);
3054 pic16_emitcode ("pop","_bp");
3059 /* restore the register bank */
3060 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
3061 pic16_emitcode ("pop","psw");
3063 if (IFFUNC_ISISR(sym->type)) {
3065 /* now we need to restore the registers */
3066 /* if this isr has no bank i.e. is going to
3067 run with bank 0 , then we need to save more
3069 if (!FUNC_REGBANK(sym->type)) {
3071 /* if this function does not call any other
3072 function then we can be economical and
3073 save only those registers that are used */
3074 if (! IFFUNC_HASFCALL(sym->type)) {
3077 /* if any registers used */
3078 if (sym->regsUsed) {
3079 /* save the registers used */
3080 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3081 if (bitVectBitValue(sym->regsUsed,i) ||
3082 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3083 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
3088 /* this function has a function call cannot
3089 determines register usage so we will have the
3091 unsaverbank(0,ic,FALSE);
3095 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
3097 if (options.stack10bit)
3099 pic16_emitcode ("pop", "dpx1");
3100 pic16_emitcode ("pop", "dph1");
3101 pic16_emitcode ("pop", "dpl1");
3103 pic16_emitcode ("pop", "dps");
3104 pic16_emitcode ("pop", "dpx");
3106 if (!inExcludeList("dph"))
3107 pic16_emitcode ("pop","dph");
3108 if (!inExcludeList("dpl"))
3109 pic16_emitcode ("pop","dpl");
3110 if (!inExcludeList("b"))
3111 pic16_emitcode ("pop","b");
3112 if (!inExcludeList("acc"))
3113 pic16_emitcode ("pop","acc");
3115 if (IFFUNC_ISCRITICAL(sym->type))
3116 pic16_emitcode("setb","ea");
3119 /* if debug then send end of function */
3120 /* if (options.debug && currFunc) { */
3123 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3124 FileBaseName(ic->filename),currFunc->lastLine,
3125 ic->level,ic->block);
3126 if (IS_STATIC(currFunc->etype))
3127 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3129 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3133 // pic16_emitcode ("reti","");
3135 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
3136 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
3137 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
3138 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
3139 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
3142 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
3145 pic16_emitpcodeNULLop(POC_RETFIE);
3149 if (IFFUNC_ISCRITICAL(sym->type))
3150 pic16_emitcode("setb","ea");
3152 /* if any registers used */
3159 /* save the registers used */
3160 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3161 for ( i = sym->regsUsed->size; i >= 0; i--) {
3162 if (bitVectBitValue(sym->regsUsed,i)) {
3163 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3164 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3165 // pic16_regWithIdx(i)->name);
3167 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3169 PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3175 /* if debug then send end of function */
3178 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3179 FileBaseName(ic->filename),currFunc->lastLine,
3180 ic->level,ic->block);
3181 if (IS_STATIC(currFunc->etype))
3182 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3184 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3189 /* insert code to restore stack frame, if user enabled it
3190 * and function is not main() */
3192 if(USE_STACK && strcmp(sym->name, "main")) {
3193 if(!options.ommitFramePtr || sym->regsUsed) {
3194 /* restore stack frame */
3195 if(STACK_MODEL_LARGE)
3196 pic16_emitpcode(POC_MOVFF,
3197 pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h, 0));
3198 pic16_emitpcode(POC_MOVFF,
3199 pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l, 0));
3204 pic16_emitcode ("return","");
3205 pic16_emitpcodeNULLop(POC_RETURN);
3207 /* Mark the end of a function */
3208 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3213 /*-----------------------------------------------------------------*/
3214 /* genRet - generate code for return statement */
3215 /*-----------------------------------------------------------------*/
3216 static void genRet (iCode *ic)
3218 int size,offset = 0 , pushed = 0;
3220 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3221 /* if we have no return value then
3222 just generate the "ret" */
3226 /* we have something to return then
3227 move the return value into place */
3228 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3229 size = AOP_SIZE(IC_LEFT(ic));
3233 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3235 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3237 pic16_emitcode("push","%s",l);
3240 DEBUGpic16_emitcode(";", "%d", __LINE__);
3241 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3243 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3244 if (strcmp(fReturn[offset],l)) {
3245 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3246 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3247 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3249 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3252 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3262 if (strcmp(fReturn[pushed],"a"))
3263 pic16_emitcode("pop",fReturn[pushed]);
3265 pic16_emitcode("pop","acc");
3268 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3271 /* generate a jump to the return label
3272 if the next is not the return statement */
3273 if (!(ic->next && ic->next->op == LABEL &&
3274 IC_LABEL(ic->next) == returnLabel)) {
3276 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3277 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3282 /*-----------------------------------------------------------------*/
3283 /* genLabel - generates a label */
3284 /*-----------------------------------------------------------------*/
3285 static void genLabel (iCode *ic)
3287 /* special case never generate */
3288 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3289 if (IC_LABEL(ic) == entryLabel)
3292 pic16_emitpLabel(IC_LABEL(ic)->key);
3293 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3296 /*-----------------------------------------------------------------*/
3297 /* genGoto - generates a goto */
3298 /*-----------------------------------------------------------------*/
3300 static void genGoto (iCode *ic)
3302 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3303 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3307 /*-----------------------------------------------------------------*/
3308 /* genMultbits :- multiplication of bits */
3309 /*-----------------------------------------------------------------*/
3310 static void genMultbits (operand *left,
3314 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3316 if(!pic16_sameRegs(AOP(result),AOP(right)))
3317 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3319 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3320 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3321 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3326 /*-----------------------------------------------------------------*/
3327 /* genMultOneByte : 8 bit multiplication & division */
3328 /*-----------------------------------------------------------------*/
3329 static void genMultOneByte (operand *left,
3333 sym_link *opetype = operandType(result);
3338 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3339 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3340 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3342 /* (if two literals, the value is computed before) */
3343 /* if one literal, literal on the right */
3344 if (AOP_TYPE(left) == AOP_LIT){
3350 size = AOP_SIZE(result);
3353 if (AOP_TYPE(right) == AOP_LIT){
3354 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3355 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3356 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3357 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3358 pic16_emitcode("call","genMultLit");
3360 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3361 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3362 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3363 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3364 pic16_emitcode("call","pic16_genMult8X8_8");
3367 pic16_genMult8X8_8 (left, right,result);
3370 /* signed or unsigned */
3371 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3372 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3374 //pic16_emitcode("mul","ab");
3375 /* if result size = 1, mul signed = mul unsigned */
3376 //pic16_aopPut(AOP(result),"a",0);
3378 } else { // (size > 1)
3380 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3381 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3382 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3383 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3385 if (SPEC_USIGN(opetype)){
3386 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3387 pic16_genUMult8X8_16 (left, right, result, NULL);
3390 /* for filling the MSBs */
3391 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3392 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3396 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3398 pic16_emitcode("mov","a,b");
3400 /* adjust the MSB if left or right neg */
3402 /* if one literal */
3403 if (AOP_TYPE(right) == AOP_LIT){
3404 pic16_emitcode("multiply ","right is a lit");
3405 /* AND literal negative */
3406 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3407 /* adjust MSB (c==0 after mul) */
3408 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3412 pic16_genSMult8X8_16 (left, right, result, NULL);
3416 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3418 pic16_emitcode("rlc","a");
3419 pic16_emitcode("subb","a,acc");
3427 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3428 //pic16_aopPut(AOP(result),"a",offset++);
3432 /*-----------------------------------------------------------------*/
3433 /* genMult - generates code for multiplication */
3434 /*-----------------------------------------------------------------*/
3435 static void genMult (iCode *ic)
3437 operand *left = IC_LEFT(ic);
3438 operand *right = IC_RIGHT(ic);
3439 operand *result= IC_RESULT(ic);
3441 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3442 /* assign the amsops */
3443 pic16_aopOp (left,ic,FALSE);
3444 pic16_aopOp (right,ic,FALSE);
3445 pic16_aopOp (result,ic,TRUE);
3447 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3449 /* special cases first */
3451 if (AOP_TYPE(left) == AOP_CRY &&
3452 AOP_TYPE(right)== AOP_CRY) {
3453 genMultbits(left,right,result);
3457 /* if both are of size == 1 */
3458 if (AOP_SIZE(left) == 1 &&
3459 AOP_SIZE(right) == 1 ) {
3460 genMultOneByte(left,right,result);
3464 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3466 /* should have been converted to function call */
3470 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3471 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3472 pic16_freeAsmop(result,NULL,ic,TRUE);
3475 /*-----------------------------------------------------------------*/
3476 /* genDivbits :- division of bits */
3477 /*-----------------------------------------------------------------*/
3478 static void genDivbits (operand *left,
3485 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3486 /* the result must be bit */
3487 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3488 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3492 pic16_emitcode("div","ab");
3493 pic16_emitcode("rrc","a");
3494 pic16_aopPut(AOP(result),"c",0);
3497 /*-----------------------------------------------------------------*/
3498 /* genDivOneByte : 8 bit division */
3499 /*-----------------------------------------------------------------*/
3500 static void genDivOneByte (operand *left,
3504 sym_link *opetype = operandType(result);
3509 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3510 size = AOP_SIZE(result) - 1;
3512 /* signed or unsigned */
3513 if (SPEC_USIGN(opetype)) {
3514 /* unsigned is easy */
3515 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3516 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3518 pic16_emitcode("div","ab");
3519 pic16_aopPut(AOP(result),"a",0);
3521 pic16_aopPut(AOP(result),zero,offset++);
3525 /* signed is a little bit more difficult */
3527 /* save the signs of the operands */
3528 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3530 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3531 pic16_emitcode("push","acc"); /* save it on the stack */
3533 /* now sign adjust for both left & right */
3534 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3536 lbl = newiTempLabel(NULL);
3537 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3538 pic16_emitcode("cpl","a");
3539 pic16_emitcode("inc","a");
3540 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3541 pic16_emitcode("mov","b,a");
3543 /* sign adjust left side */
3544 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3547 lbl = newiTempLabel(NULL);
3548 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3549 pic16_emitcode("cpl","a");
3550 pic16_emitcode("inc","a");
3551 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3553 /* now the division */
3554 pic16_emitcode("div","ab");
3555 /* we are interested in the lower order
3557 pic16_emitcode("mov","b,a");
3558 lbl = newiTempLabel(NULL);
3559 pic16_emitcode("pop","acc");
3560 /* if there was an over flow we don't
3561 adjust the sign of the result */
3562 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3563 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3565 pic16_emitcode("clr","a");
3566 pic16_emitcode("subb","a,b");
3567 pic16_emitcode("mov","b,a");
3568 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3570 /* now we are done */
3571 pic16_aopPut(AOP(result),"b",0);
3573 pic16_emitcode("mov","c,b.7");
3574 pic16_emitcode("subb","a,acc");
3577 pic16_aopPut(AOP(result),"a",offset++);
3581 /*-----------------------------------------------------------------*/
3582 /* genDiv - generates code for division */
3583 /*-----------------------------------------------------------------*/
3584 static void genDiv (iCode *ic)
3586 operand *left = IC_LEFT(ic);
3587 operand *right = IC_RIGHT(ic);
3588 operand *result= IC_RESULT(ic);
3590 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3591 /* assign the amsops */
3592 pic16_aopOp (left,ic,FALSE);
3593 pic16_aopOp (right,ic,FALSE);
3594 pic16_aopOp (result,ic,TRUE);
3596 /* special cases first */
3598 if (AOP_TYPE(left) == AOP_CRY &&
3599 AOP_TYPE(right)== AOP_CRY) {
3600 genDivbits(left,right,result);
3604 /* if both are of size == 1 */
3605 if (AOP_SIZE(left) == 1 &&
3606 AOP_SIZE(right) == 1 ) {
3607 genDivOneByte(left,right,result);
3611 /* should have been converted to function call */
3614 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3615 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3616 pic16_freeAsmop(result,NULL,ic,TRUE);
3619 /*-----------------------------------------------------------------*/
3620 /* genModbits :- modulus of bits */
3621 /*-----------------------------------------------------------------*/
3622 static void genModbits (operand *left,
3629 /* the result must be bit */
3630 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3631 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3635 pic16_emitcode("div","ab");
3636 pic16_emitcode("mov","a,b");
3637 pic16_emitcode("rrc","a");
3638 pic16_aopPut(AOP(result),"c",0);
3641 /*-----------------------------------------------------------------*/
3642 /* genModOneByte : 8 bit modulus */
3643 /*-----------------------------------------------------------------*/
3644 static void genModOneByte (operand *left,
3648 sym_link *opetype = operandType(result);
3652 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3653 /* signed or unsigned */
3654 if (SPEC_USIGN(opetype)) {
3655 /* unsigned is easy */
3656 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3657 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3659 pic16_emitcode("div","ab");
3660 pic16_aopPut(AOP(result),"b",0);
3664 /* signed is a little bit more difficult */
3666 /* save the signs of the operands */
3667 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3670 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3671 pic16_emitcode("push","acc"); /* save it on the stack */
3673 /* now sign adjust for both left & right */
3674 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3677 lbl = newiTempLabel(NULL);
3678 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3679 pic16_emitcode("cpl","a");
3680 pic16_emitcode("inc","a");
3681 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3682 pic16_emitcode("mov","b,a");
3684 /* sign adjust left side */
3685 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3688 lbl = newiTempLabel(NULL);
3689 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3690 pic16_emitcode("cpl","a");
3691 pic16_emitcode("inc","a");
3692 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3694 /* now the multiplication */
3695 pic16_emitcode("div","ab");
3696 /* we are interested in the lower order
3698 lbl = newiTempLabel(NULL);
3699 pic16_emitcode("pop","acc");
3700 /* if there was an over flow we don't
3701 adjust the sign of the result */
3702 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3703 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3705 pic16_emitcode("clr","a");
3706 pic16_emitcode("subb","a,b");
3707 pic16_emitcode("mov","b,a");
3708 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3710 /* now we are done */
3711 pic16_aopPut(AOP(result),"b",0);
3715 /*-----------------------------------------------------------------*/
3716 /* genMod - generates code for division */
3717 /*-----------------------------------------------------------------*/
3718 static void genMod (iCode *ic)
3720 operand *left = IC_LEFT(ic);
3721 operand *right = IC_RIGHT(ic);
3722 operand *result= IC_RESULT(ic);
3724 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3725 /* assign the amsops */
3726 pic16_aopOp (left,ic,FALSE);
3727 pic16_aopOp (right,ic,FALSE);
3728 pic16_aopOp (result,ic,TRUE);
3730 /* special cases first */
3732 if (AOP_TYPE(left) == AOP_CRY &&
3733 AOP_TYPE(right)== AOP_CRY) {
3734 genModbits(left,right,result);
3738 /* if both are of size == 1 */
3739 if (AOP_SIZE(left) == 1 &&
3740 AOP_SIZE(right) == 1 ) {
3741 genModOneByte(left,right,result);
3745 /* should have been converted to function call */
3749 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3750 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3751 pic16_freeAsmop(result,NULL,ic,TRUE);
3754 /*-----------------------------------------------------------------*/
3755 /* genIfxJump :- will create a jump depending on the ifx */
3756 /*-----------------------------------------------------------------*/
3758 note: May need to add parameter to indicate when a variable is in bit space.
3760 static void genIfxJump (iCode *ic, char *jval)
3763 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3764 /* if true label then we jump if condition
3766 if ( IC_TRUE(ic) ) {
3768 if(strcmp(jval,"a") == 0)
3770 else if (strcmp(jval,"c") == 0)
3773 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3774 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3777 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3778 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3782 /* false label is present */
3783 if(strcmp(jval,"a") == 0)
3785 else if (strcmp(jval,"c") == 0)
3788 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3789 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3792 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3793 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3798 /* mark the icode as generated */
3802 /*-----------------------------------------------------------------*/
3804 /*-----------------------------------------------------------------*/
3805 static void genSkip(iCode *ifx,int status_bit)
3810 if ( IC_TRUE(ifx) ) {
3811 switch(status_bit) {
3826 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3827 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3831 switch(status_bit) {
3845 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3846 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3852 /*-----------------------------------------------------------------*/
3854 /*-----------------------------------------------------------------*/
3855 static void genSkipc(resolvedIfx *rifx)
3865 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3866 rifx->generated = 1;
3869 /*-----------------------------------------------------------------*/
3871 /*-----------------------------------------------------------------*/
3872 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3877 if( (rifx->condition ^ invert_condition) & 1)
3882 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3883 rifx->generated = 1;
3886 /*-----------------------------------------------------------------*/
3888 /*-----------------------------------------------------------------*/
3889 static void genSkipz(iCode *ifx, int condition)
3900 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3902 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3905 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3907 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3910 /*-----------------------------------------------------------------*/
3912 /*-----------------------------------------------------------------*/
3913 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3919 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3921 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3924 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3925 rifx->generated = 1;
3929 /*-----------------------------------------------------------------*/
3930 /* genChkZeroes :- greater or less than comparison */
3931 /* For each byte in a literal that is zero, inclusive or the */
3932 /* the corresponding byte in the operand with W */
3933 /* returns true if any of the bytes are zero */
3934 /*-----------------------------------------------------------------*/
3935 static int genChkZeroes(operand *op, int lit, int size)
3942 i = (lit >> (size*8)) & 0xff;
3946 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3948 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3957 /*-----------------------------------------------------------------*/
3958 /* genCmp :- greater or less than comparison */
3959 /*-----------------------------------------------------------------*/
3960 static void genCmp (operand *left,operand *right,
3961 operand *result, iCode *ifx, int sign)
3963 int size; //, offset = 0 ;
3964 unsigned long lit = 0L,i = 0;
3965 resolvedIfx rFalseIfx;
3966 // resolvedIfx rTrueIfx;
3968 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3971 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3972 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3976 resolveIfx(&rFalseIfx,ifx);
3977 truelbl = newiTempLabel(NULL);
3978 size = max(AOP_SIZE(left),AOP_SIZE(right));
3980 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3984 /* if literal is on the right then swap with left */
3985 if ((AOP_TYPE(right) == AOP_LIT)) {
3986 operand *tmp = right ;
3987 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3988 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3991 lit = (lit - 1) & mask;
3994 rFalseIfx.condition ^= 1;
3997 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3998 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4002 //if(IC_TRUE(ifx) == NULL)
4003 /* if left & right are bit variables */
4004 if (AOP_TYPE(left) == AOP_CRY &&
4005 AOP_TYPE(right) == AOP_CRY ) {
4006 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4007 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4009 /* subtract right from left if at the
4010 end the carry flag is set then we know that
4011 left is greater than right */
4015 symbol *lbl = newiTempLabel(NULL);
4018 if(AOP_TYPE(right) == AOP_LIT) {
4020 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4022 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4029 genSkipCond(&rFalseIfx,left,size-1,7);
4031 /* no need to compare to 0...*/
4032 /* NOTE: this is a de-generate compare that most certainly
4033 * creates some dead code. */
4034 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4036 if(ifx) ifx->generated = 1;
4043 //i = (lit >> (size*8)) & 0xff;
4044 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4046 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4048 i = ((0-lit) & 0xff);
4051 /* lit is 0x7f, all signed chars are less than
4052 * this except for 0x7f itself */
4053 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4054 genSkipz2(&rFalseIfx,0);
4056 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4057 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4058 genSkipc(&rFalseIfx);
4063 genSkipz2(&rFalseIfx,1);
4065 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4066 genSkipc(&rFalseIfx);
4070 if(ifx) ifx->generated = 1;
4074 /* chars are out of the way. now do ints and longs */
4077 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4084 genSkipCond(&rFalseIfx,left,size,7);
4085 if(ifx) ifx->generated = 1;
4090 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4092 //rFalseIfx.condition ^= 1;
4093 //genSkipCond(&rFalseIfx,left,size,7);
4094 //rFalseIfx.condition ^= 1;
4096 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4097 if(rFalseIfx.condition)
4098 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4100 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4102 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4103 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4104 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4107 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4109 if(rFalseIfx.condition) {
4111 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4117 genSkipc(&rFalseIfx);
4118 pic16_emitpLabel(truelbl->key);
4119 if(ifx) ifx->generated = 1;
4126 if( (lit & 0xff) == 0) {
4127 /* lower byte is zero */
4128 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4129 i = ((lit >> 8) & 0xff) ^0x80;
4130 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4131 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4132 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4133 genSkipc(&rFalseIfx);
4136 if(ifx) ifx->generated = 1;
4141 /* Special cases for signed longs */
4142 if( (lit & 0xffffff) == 0) {
4143 /* lower byte is zero */
4144 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4145 i = ((lit >> 8*3) & 0xff) ^0x80;
4146 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4147 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4148 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4149 genSkipc(&rFalseIfx);
4152 if(ifx) ifx->generated = 1;
4160 if(lit & (0x80 << (size*8))) {
4161 /* lit is negative */
4162 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4164 //genSkipCond(&rFalseIfx,left,size,7);
4166 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4168 if(rFalseIfx.condition)
4169 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4171 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4175 /* lit is positive */
4176 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4177 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4178 if(rFalseIfx.condition)
4179 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4181 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4186 This works, but is only good for ints.
4187 It also requires a "known zero" register.
4188 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4189 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4190 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4191 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4192 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4193 genSkipc(&rFalseIfx);
4195 pic16_emitpLabel(truelbl->key);
4196 if(ifx) ifx->generated = 1;
4200 /* There are no more special cases, so perform a general compare */
4202 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4203 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4207 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4209 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4211 //rFalseIfx.condition ^= 1;
4212 genSkipc(&rFalseIfx);
4214 pic16_emitpLabel(truelbl->key);
4216 if(ifx) ifx->generated = 1;
4223 /* sign is out of the way. So now do an unsigned compare */
4224 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4227 /* General case - compare to an unsigned literal on the right.*/
4229 i = (lit >> (size*8)) & 0xff;
4230 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4231 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4233 i = (lit >> (size*8)) & 0xff;
4236 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4238 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4240 /* this byte of the lit is zero,
4241 *if it's not the last then OR in the variable */
4243 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4248 pic16_emitpLabel(lbl->key);
4249 //if(emitFinalCheck)
4250 genSkipc(&rFalseIfx);
4252 pic16_emitpLabel(truelbl->key);
4254 if(ifx) ifx->generated = 1;
4261 if(AOP_TYPE(left) == AOP_LIT) {
4262 //symbol *lbl = newiTempLabel(NULL);
4264 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4267 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4270 if((lit == 0) && (sign == 0)){
4273 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4275 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4277 genSkipz2(&rFalseIfx,0);
4278 if(ifx) ifx->generated = 1;
4285 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4286 /* degenerate compare can never be true */
4287 if(rFalseIfx.condition == 0)
4288 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4290 if(ifx) ifx->generated = 1;
4295 /* signed comparisons to a literal byte */
4297 int lp1 = (lit+1) & 0xff;
4299 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4302 rFalseIfx.condition ^= 1;
4303 genSkipCond(&rFalseIfx,right,0,7);
4306 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4307 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4308 genSkipz2(&rFalseIfx,1);
4311 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4312 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4313 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4314 rFalseIfx.condition ^= 1;
4315 genSkipc(&rFalseIfx);
4319 /* unsigned comparisons to a literal byte */
4321 switch(lit & 0xff ) {
4323 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4324 genSkipz2(&rFalseIfx,0);
4327 rFalseIfx.condition ^= 1;
4328 genSkipCond(&rFalseIfx,right,0,7);
4332 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4333 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4334 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4335 rFalseIfx.condition ^= 1;
4336 if (AOP_TYPE(result) == AOP_CRY)
4337 genSkipc(&rFalseIfx);
4339 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4340 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4346 if(ifx) ifx->generated = 1;
4352 /* Size is greater than 1 */
4360 /* this means lit = 0xffffffff, or -1 */
4363 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4364 rFalseIfx.condition ^= 1;
4365 genSkipCond(&rFalseIfx,right,size,7);
4366 if(ifx) ifx->generated = 1;
4373 if(rFalseIfx.condition) {
4374 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4375 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4378 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4380 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4384 if(rFalseIfx.condition) {
4385 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4386 pic16_emitpLabel(truelbl->key);
4388 rFalseIfx.condition ^= 1;
4389 genSkipCond(&rFalseIfx,right,s,7);
4392 if(ifx) ifx->generated = 1;
4396 if((size == 1) && (0 == (lp1&0xff))) {
4397 /* lower byte of signed word is zero */
4398 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4399 i = ((lp1 >> 8) & 0xff) ^0x80;
4400 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4401 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4402 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4403 rFalseIfx.condition ^= 1;
4404 genSkipc(&rFalseIfx);
4407 if(ifx) ifx->generated = 1;
4411 if(lit & (0x80 << (size*8))) {
4412 /* Lit is less than zero */
4413 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4414 //rFalseIfx.condition ^= 1;
4415 //genSkipCond(&rFalseIfx,left,size,7);
4416 //rFalseIfx.condition ^= 1;
4417 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4418 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4420 if(rFalseIfx.condition)
4421 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4423 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4427 /* Lit is greater than or equal to zero */
4428 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4429 //rFalseIfx.condition ^= 1;
4430 //genSkipCond(&rFalseIfx,right,size,7);
4431 //rFalseIfx.condition ^= 1;
4433 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4434 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4436 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4437 if(rFalseIfx.condition)
4438 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4440 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4445 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4446 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4450 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4452 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4454 rFalseIfx.condition ^= 1;
4455 //rFalseIfx.condition = 1;
4456 genSkipc(&rFalseIfx);
4458 pic16_emitpLabel(truelbl->key);
4460 if(ifx) ifx->generated = 1;
4465 /* compare word or long to an unsigned literal on the right.*/
4470 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4473 break; /* handled above */
4476 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4478 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4479 genSkipz2(&rFalseIfx,0);
4483 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4485 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4488 if(rFalseIfx.condition)
4489 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4491 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4494 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4495 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4497 rFalseIfx.condition ^= 1;
4498 genSkipc(&rFalseIfx);
4501 pic16_emitpLabel(truelbl->key);
4503 if(ifx) ifx->generated = 1;
4509 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4510 i = (lit >> (size*8)) & 0xff;
4512 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4513 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4516 i = (lit >> (size*8)) & 0xff;
4519 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4521 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4523 /* this byte of the lit is zero,
4524 *if it's not the last then OR in the variable */
4526 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4531 pic16_emitpLabel(lbl->key);
4533 rFalseIfx.condition ^= 1;
4534 genSkipc(&rFalseIfx);
4538 pic16_emitpLabel(truelbl->key);
4539 if(ifx) ifx->generated = 1;
4543 /* Compare two variables */
4545 DEBUGpic16_emitcode(";sign","%d",sign);
4549 /* Sigh. thus sucks... */
4551 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4552 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4553 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4554 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4555 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4556 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
4558 /* Signed char comparison */
4559 /* Special thanks to Nikolai Golovchenko for this snippet */
4560 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4561 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4562 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4563 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4564 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4565 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4567 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4568 genSkipc(&rFalseIfx);
4570 if(ifx) ifx->generated = 1;
4576 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4577 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4581 /* The rest of the bytes of a multi-byte compare */
4585 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4588 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4589 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4594 pic16_emitpLabel(lbl->key);
4596 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4597 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4598 (AOP_TYPE(result) == AOP_REG)) {
4599 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4600 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4602 genSkipc(&rFalseIfx);
4604 //genSkipc(&rFalseIfx);
4605 if(ifx) ifx->generated = 1;
4612 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4613 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4614 pic16_outBitC(result);
4616 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4617 /* if the result is used in the next
4618 ifx conditional branch then generate
4619 code a little differently */
4621 genIfxJump (ifx,"c");
4623 pic16_outBitC(result);
4624 /* leave the result in acc */
4629 /*-----------------------------------------------------------------*/
4630 /* genCmpGt :- greater than comparison */
4631 /*-----------------------------------------------------------------*/
4632 static void genCmpGt (iCode *ic, iCode *ifx)
4634 operand *left, *right, *result;
4635 sym_link *letype , *retype;
4638 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4640 right= IC_RIGHT(ic);
4641 result = IC_RESULT(ic);
4643 letype = getSpec(operandType(left));
4644 retype =getSpec(operandType(right));
4645 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4646 /* assign the amsops */
4647 pic16_aopOp (left,ic,FALSE);
4648 pic16_aopOp (right,ic,FALSE);
4649 pic16_aopOp (result,ic,TRUE);
4651 genCmp(right, left, result, ifx, sign);
4653 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4654 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4655 pic16_freeAsmop(result,NULL,ic,TRUE);
4658 /*-----------------------------------------------------------------*/
4659 /* genCmpLt - less than comparisons */
4660 /*-----------------------------------------------------------------*/
4661 static void genCmpLt (iCode *ic, iCode *ifx)
4663 operand *left, *right, *result;
4664 sym_link *letype , *retype;
4667 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4669 right= IC_RIGHT(ic);
4670 result = IC_RESULT(ic);
4672 letype = getSpec(operandType(left));
4673 retype =getSpec(operandType(right));
4674 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4676 /* assign the amsops */
4677 pic16_aopOp (left,ic,FALSE);
4678 pic16_aopOp (right,ic,FALSE);
4679 pic16_aopOp (result,ic,TRUE);
4681 genCmp(left, right, result, ifx, sign);
4683 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4684 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4685 pic16_freeAsmop(result,NULL,ic,TRUE);
4688 /*-----------------------------------------------------------------*/
4689 /* genc16bit2lit - compare a 16 bit value to a literal */
4690 /*-----------------------------------------------------------------*/
4691 static void genc16bit2lit(operand *op, int lit, int offset)
4695 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4696 if( (lit&0xff) == 0)
4701 switch( BYTEofLONG(lit,i)) {
4703 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4706 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4709 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4712 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4713 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4718 switch( BYTEofLONG(lit,i)) {
4720 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4724 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4728 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4731 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4733 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4739 /*-----------------------------------------------------------------*/
4740 /* gencjneshort - compare and jump if not equal */
4741 /*-----------------------------------------------------------------*/
4742 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4744 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4746 int res_offset = 0; /* the result may be a different size then left or right */
4747 int res_size = AOP_SIZE(result);
4751 unsigned long lit = 0L;
4752 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4753 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4755 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4756 resolveIfx(&rIfx,ifx);
4757 lbl = newiTempLabel(NULL);
4760 /* if the left side is a literal or
4761 if the right is in a pointer register and left
4763 if ((AOP_TYPE(left) == AOP_LIT) ||
4764 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4769 if(AOP_TYPE(right) == AOP_LIT)
4770 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4772 /* if the right side is a literal then anything goes */
4773 if (AOP_TYPE(right) == AOP_LIT &&
4774 AOP_TYPE(left) != AOP_DIR ) {
4777 genc16bit2lit(left, lit, 0);
4779 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4784 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4785 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4787 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4791 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4793 if(res_offset < res_size-1)
4801 /* if the right side is in a register or in direct space or
4802 if the left is a pointer register & right is not */
4803 else if (AOP_TYPE(right) == AOP_REG ||
4804 AOP_TYPE(right) == AOP_DIR ||
4805 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4806 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4807 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4808 int lbl_key = lbl->key;
4811 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4812 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4814 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4815 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4816 __FUNCTION__,__LINE__);
4820 /* switch(size) { */
4822 /* genc16bit2lit(left, lit, 0); */
4824 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4829 if((AOP_TYPE(left) == AOP_DIR) &&
4830 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4832 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4833 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4835 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4837 switch (lit & 0xff) {
4839 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4842 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4843 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4844 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4848 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4849 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4850 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4851 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4855 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4856 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4861 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4864 if(AOP_TYPE(result) == AOP_CRY) {
4865 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4870 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4872 /* fix me. probably need to check result size too */
4873 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4878 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4879 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4886 if(res_offset < res_size-1)
4891 } else if(AOP_TYPE(right) == AOP_REG &&
4892 AOP_TYPE(left) != AOP_DIR){
4895 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4896 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4897 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4902 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4904 if(res_offset < res_size-1)
4909 /* right is a pointer reg need both a & b */
4911 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4913 pic16_emitcode("mov","b,%s",l);
4914 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4915 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4920 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4922 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4924 pic16_emitpLabel(lbl->key);
4926 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4933 /*-----------------------------------------------------------------*/
4934 /* gencjne - compare and jump if not equal */
4935 /*-----------------------------------------------------------------*/
4936 static void gencjne(operand *left, operand *right, iCode *ifx)
4938 symbol *tlbl = newiTempLabel(NULL);
4940 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4941 gencjneshort(left, right, lbl);
4943 pic16_emitcode("mov","a,%s",one);
4944 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4945 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4946 pic16_emitcode("clr","a");
4947 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4949 pic16_emitpLabel(lbl->key);
4950 pic16_emitpLabel(tlbl->key);
4955 /*-----------------------------------------------------------------*/
4956 /* genCmpEq - generates code for equal to */
4957 /*-----------------------------------------------------------------*/
4958 static void genCmpEq (iCode *ic, iCode *ifx)
4960 operand *left, *right, *result;
4961 unsigned long lit = 0L;
4964 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4967 DEBUGpic16_emitcode ("; ifx is non-null","");
4969 DEBUGpic16_emitcode ("; ifx is null","");
4971 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4972 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4973 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4975 size = max(AOP_SIZE(left),AOP_SIZE(right));
4977 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4979 /* if literal, literal on the right or
4980 if the right is in a pointer register and left
4982 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4983 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4984 operand *tmp = right ;
4990 if(ifx && !AOP_SIZE(result)){
4992 /* if they are both bit variables */
4993 if (AOP_TYPE(left) == AOP_CRY &&
4994 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4995 if(AOP_TYPE(right) == AOP_LIT){
4996 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4998 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4999 pic16_emitcode("cpl","c");
5000 } else if(lit == 1L) {
5001 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5003 pic16_emitcode("clr","c");
5005 /* AOP_TYPE(right) == AOP_CRY */
5007 symbol *lbl = newiTempLabel(NULL);
5008 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5009 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5010 pic16_emitcode("cpl","c");
5011 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5013 /* if true label then we jump if condition
5015 tlbl = newiTempLabel(NULL);
5016 if ( IC_TRUE(ifx) ) {
5017 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5018 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5020 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5021 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5023 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5026 /* left and right are both bit variables, result is carry */
5029 resolveIfx(&rIfx,ifx);
5031 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5032 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5033 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5034 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5039 /* They're not both bit variables. Is the right a literal? */
5040 if(AOP_TYPE(right) == AOP_LIT) {
5041 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5046 switch(lit & 0xff) {
5048 if ( IC_TRUE(ifx) ) {
5049 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5051 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5053 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5054 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5058 if ( IC_TRUE(ifx) ) {
5059 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5061 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5063 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5064 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5068 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5070 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5075 /* end of size == 1 */
5079 genc16bit2lit(left,lit,offset);
5082 /* end of size == 2 */
5087 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5088 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5089 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5090 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5094 /* search for patterns that can be optimized */
5096 genc16bit2lit(left,lit,0);
5099 genSkipz(ifx,IC_TRUE(ifx) == NULL);
5101 genc16bit2lit(left,lit,2);
5103 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5104 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5117 } else if(AOP_TYPE(right) == AOP_CRY ) {
5118 /* we know the left is not a bit, but that the right is */
5119 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5120 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5121 pic16_popGet(AOP(right),offset));
5122 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5124 /* if the two are equal, then W will be 0 and the Z bit is set
5125 * we could test Z now, or go ahead and check the high order bytes if
5126 * the variable we're comparing is larger than a byte. */
5129 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5131 if ( IC_TRUE(ifx) ) {
5133 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5134 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5137 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5138 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5142 /* They're both variables that are larger than bits */
5145 tlbl = newiTempLabel(NULL);
5148 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5149 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5151 if ( IC_TRUE(ifx) ) {
5155 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5157 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5158 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5162 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5165 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5166 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5171 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5173 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5174 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5178 if(s>1 && IC_TRUE(ifx)) {
5179 pic16_emitpLabel(tlbl->key);
5180 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5184 /* mark the icode as generated */
5189 /* if they are both bit variables */
5190 if (AOP_TYPE(left) == AOP_CRY &&
5191 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5192 if(AOP_TYPE(right) == AOP_LIT){
5193 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5195 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5196 pic16_emitcode("cpl","c");
5197 } else if(lit == 1L) {
5198 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5200 pic16_emitcode("clr","c");
5202 /* AOP_TYPE(right) == AOP_CRY */
5204 symbol *lbl = newiTempLabel(NULL);
5205 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5206 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5207 pic16_emitcode("cpl","c");
5208 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5211 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5212 pic16_outBitC(result);
5216 genIfxJump (ifx,"c");
5219 /* if the result is used in an arithmetic operation
5220 then put the result in place */
5221 pic16_outBitC(result);
5224 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5225 gencjne(left,right,result,ifx);
5228 gencjne(left,right,newiTempLabel(NULL));
5230 if(IC_TRUE(ifx)->key)
5231 gencjne(left,right,IC_TRUE(ifx)->key);
5233 gencjne(left,right,IC_FALSE(ifx)->key);
5237 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5238 pic16_aopPut(AOP(result),"a",0);
5243 genIfxJump (ifx,"a");
5247 /* if the result is used in an arithmetic operation
5248 then put the result in place */
5250 if (AOP_TYPE(result) != AOP_CRY)
5251 pic16_outAcc(result);
5253 /* leave the result in acc */
5257 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5258 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5259 pic16_freeAsmop(result,NULL,ic,TRUE);
5262 /*-----------------------------------------------------------------*/
5263 /* ifxForOp - returns the icode containing the ifx for operand */
5264 /*-----------------------------------------------------------------*/
5265 static iCode *ifxForOp ( operand *op, iCode *ic )
5267 /* if true symbol then needs to be assigned */
5268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5269 if (IS_TRUE_SYMOP(op))
5272 /* if this has register type condition and
5273 the next instruction is ifx with the same operand
5274 and live to of the operand is upto the ifx only then */
5276 ic->next->op == IFX &&
5277 IC_COND(ic->next)->key == op->key &&
5278 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5282 ic->next->op == IFX &&
5283 IC_COND(ic->next)->key == op->key) {
5284 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5288 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5290 ic->next->op == IFX)
5291 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5294 ic->next->op == IFX &&
5295 IC_COND(ic->next)->key == op->key) {
5296 DEBUGpic16_emitcode ("; "," key is okay");
5297 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5298 OP_SYMBOL(op)->liveTo,
5305 /*-----------------------------------------------------------------*/
5306 /* genAndOp - for && operation */
5307 /*-----------------------------------------------------------------*/
5308 static void genAndOp (iCode *ic)
5310 operand *left,*right, *result;
5313 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5314 /* note here that && operations that are in an
5315 if statement are taken away by backPatchLabels
5316 only those used in arthmetic operations remain */
5317 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5318 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5319 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5321 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5323 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5324 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5325 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5327 /* if both are bit variables */
5328 /* if (AOP_TYPE(left) == AOP_CRY && */
5329 /* AOP_TYPE(right) == AOP_CRY ) { */
5330 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5331 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5332 /* pic16_outBitC(result); */
5334 /* tlbl = newiTempLabel(NULL); */
5335 /* pic16_toBoolean(left); */
5336 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5337 /* pic16_toBoolean(right); */
5338 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5339 /* pic16_outBitAcc(result); */
5342 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5343 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5344 pic16_freeAsmop(result,NULL,ic,TRUE);
5348 /*-----------------------------------------------------------------*/
5349 /* genOrOp - for || operation */
5350 /*-----------------------------------------------------------------*/
5353 modified this code, but it doesn't appear to ever get called
5356 static void genOrOp (iCode *ic)
5358 operand *left,*right, *result;
5361 /* note here that || operations that are in an
5362 if statement are taken away by backPatchLabels
5363 only those used in arthmetic operations remain */
5364 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5365 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5366 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5367 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5369 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5371 /* if both are bit variables */
5372 if (AOP_TYPE(left) == AOP_CRY &&
5373 AOP_TYPE(right) == AOP_CRY ) {
5374 pic16_emitcode("clrc","");
5375 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5376 AOP(left)->aopu.aop_dir,
5377 AOP(left)->aopu.aop_dir);
5378 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5379 AOP(right)->aopu.aop_dir,
5380 AOP(right)->aopu.aop_dir);
5381 pic16_emitcode("setc","");
5384 tlbl = newiTempLabel(NULL);
5385 pic16_toBoolean(left);
5387 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5388 pic16_toBoolean(right);
5389 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5391 pic16_outBitAcc(result);
5394 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5395 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5396 pic16_freeAsmop(result,NULL,ic,TRUE);
5399 /*-----------------------------------------------------------------*/
5400 /* isLiteralBit - test if lit == 2^n */
5401 /*-----------------------------------------------------------------*/
5402 static int isLiteralBit(unsigned long lit)
5404 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5405 0x100L,0x200L,0x400L,0x800L,
5406 0x1000L,0x2000L,0x4000L,0x8000L,
5407 0x10000L,0x20000L,0x40000L,0x80000L,
5408 0x100000L,0x200000L,0x400000L,0x800000L,
5409 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5410 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5413 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5414 for(idx = 0; idx < 32; idx++)
5420 /*-----------------------------------------------------------------*/
5421 /* continueIfTrue - */
5422 /*-----------------------------------------------------------------*/
5423 static void continueIfTrue (iCode *ic)
5425 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5427 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5431 /*-----------------------------------------------------------------*/
5433 /*-----------------------------------------------------------------*/
5434 static void jumpIfTrue (iCode *ic)
5436 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5438 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5442 /*-----------------------------------------------------------------*/
5443 /* jmpTrueOrFalse - */
5444 /*-----------------------------------------------------------------*/
5445 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5447 // ugly but optimized by peephole
5448 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5450 symbol *nlbl = newiTempLabel(NULL);
5451 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5452 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5453 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5454 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5457 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5458 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5463 /*-----------------------------------------------------------------*/
5464 /* genAnd - code for and */
5465 /*-----------------------------------------------------------------*/
5466 static void genAnd (iCode *ic, iCode *ifx)
5468 operand *left, *right, *result;
5470 unsigned long lit = 0L;
5475 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5476 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5477 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5478 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5480 resolveIfx(&rIfx,ifx);
5482 /* if left is a literal & right is not then exchange them */
5483 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5484 AOP_NEEDSACC(left)) {
5485 operand *tmp = right ;
5490 /* if result = right then exchange them */
5491 if(pic16_sameRegs(AOP(result),AOP(right))){
5492 operand *tmp = right ;
5497 /* if right is bit then exchange them */
5498 if (AOP_TYPE(right) == AOP_CRY &&
5499 AOP_TYPE(left) != AOP_CRY){
5500 operand *tmp = right ;
5504 if(AOP_TYPE(right) == AOP_LIT)
5505 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5507 size = AOP_SIZE(result);
5509 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5512 // result = bit & yy;
5513 if (AOP_TYPE(left) == AOP_CRY){
5514 // c = bit & literal;
5515 if(AOP_TYPE(right) == AOP_LIT){
5517 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5520 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5523 if(size && (AOP_TYPE(result) == AOP_CRY)){
5524 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5527 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5531 pic16_emitcode("clr","c");
5534 if (AOP_TYPE(right) == AOP_CRY){
5536 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5537 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5540 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5542 pic16_emitcode("rrc","a");
5543 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5549 pic16_outBitC(result);
5551 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5552 genIfxJump(ifx, "c");
5556 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5557 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5558 if((AOP_TYPE(right) == AOP_LIT) &&
5559 (AOP_TYPE(result) == AOP_CRY) &&
5560 (AOP_TYPE(left) != AOP_CRY)){
5561 int posbit = isLiteralBit(lit);
5565 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5568 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5574 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5575 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5577 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5578 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5581 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5582 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5583 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5590 symbol *tlbl = newiTempLabel(NULL);
5591 int sizel = AOP_SIZE(left);
5593 pic16_emitcode("setb","c");
5595 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5596 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5598 if((posbit = isLiteralBit(bytelit)) != 0)
5599 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5601 if(bytelit != 0x0FFL)
5602 pic16_emitcode("anl","a,%s",
5603 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5604 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5609 // bit = left & literal
5611 pic16_emitcode("clr","c");
5612 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5614 // if(left & literal)
5617 jmpTrueOrFalse(ifx, tlbl);
5621 pic16_outBitC(result);
5625 /* if left is same as result */
5626 if(pic16_sameRegs(AOP(result),AOP(left))){
5628 for(;size--; offset++,lit>>=8) {
5629 if(AOP_TYPE(right) == AOP_LIT){
5630 switch(lit & 0xff) {
5632 /* and'ing with 0 has clears the result */
5633 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5634 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5637 /* and'ing with 0xff is a nop when the result and left are the same */
5642 int p = my_powof2( (~lit) & 0xff );
5644 /* only one bit is set in the literal, so use a bcf instruction */
5645 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5646 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5649 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5650 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5651 if(know_W != (lit&0xff))
5652 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5654 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5659 if (AOP_TYPE(left) == AOP_ACC) {
5660 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5662 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5663 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5670 // left & result in different registers
5671 if(AOP_TYPE(result) == AOP_CRY){
5673 // if(size), result in bit
5674 // if(!size && ifx), conditional oper: if(left & right)
5675 symbol *tlbl = newiTempLabel(NULL);
5676 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5678 pic16_emitcode("setb","c");
5680 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5681 pic16_emitcode("anl","a,%s",
5682 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5683 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5688 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5689 pic16_outBitC(result);
5691 jmpTrueOrFalse(ifx, tlbl);
5693 for(;(size--);offset++) {
5695 // result = left & right
5696 if(AOP_TYPE(right) == AOP_LIT){
5697 int t = (lit >> (offset*8)) & 0x0FFL;
5700 pic16_emitcode("clrf","%s",
5701 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5702 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5705 pic16_emitcode("movf","%s,w",
5706 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5707 pic16_emitcode("movwf","%s",
5708 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5709 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5710 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5713 pic16_emitcode("movlw","0x%x",t);
5714 pic16_emitcode("andwf","%s,w",
5715 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5716 pic16_emitcode("movwf","%s",
5717 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5719 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5720 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5721 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5726 if (AOP_TYPE(left) == AOP_ACC) {
5727 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5728 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5730 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5731 pic16_emitcode("andwf","%s,w",
5732 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5733 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5734 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5736 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5737 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5743 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5744 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5745 pic16_freeAsmop(result,NULL,ic,TRUE);
5748 /*-----------------------------------------------------------------*/
5749 /* genOr - code for or */
5750 /*-----------------------------------------------------------------*/
5751 static void genOr (iCode *ic, iCode *ifx)
5753 operand *left, *right, *result;
5755 unsigned long lit = 0L;
5757 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5759 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5760 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5761 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5763 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5765 /* if left is a literal & right is not then exchange them */
5766 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5767 AOP_NEEDSACC(left)) {
5768 operand *tmp = right ;
5773 /* if result = right then exchange them */
5774 if(pic16_sameRegs(AOP(result),AOP(right))){
5775 operand *tmp = right ;
5780 /* if right is bit then exchange them */
5781 if (AOP_TYPE(right) == AOP_CRY &&
5782 AOP_TYPE(left) != AOP_CRY){
5783 operand *tmp = right ;
5788 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5790 if(AOP_TYPE(right) == AOP_LIT)
5791 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5793 size = AOP_SIZE(result);
5797 if (AOP_TYPE(left) == AOP_CRY){
5798 if(AOP_TYPE(right) == AOP_LIT){
5799 // c = bit & literal;
5801 // lit != 0 => result = 1
5802 if(AOP_TYPE(result) == AOP_CRY){
5804 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5805 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5806 // AOP(result)->aopu.aop_dir,
5807 // AOP(result)->aopu.aop_dir);
5809 continueIfTrue(ifx);
5813 // lit == 0 => result = left
5814 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5816 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5819 if (AOP_TYPE(right) == AOP_CRY){
5820 if(pic16_sameRegs(AOP(result),AOP(left))){
5822 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5823 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5824 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5826 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5827 AOP(result)->aopu.aop_dir,
5828 AOP(result)->aopu.aop_dir);
5829 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5830 AOP(right)->aopu.aop_dir,
5831 AOP(right)->aopu.aop_dir);
5832 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5833 AOP(result)->aopu.aop_dir,
5834 AOP(result)->aopu.aop_dir);
5836 if( AOP_TYPE(result) == AOP_ACC) {
5837 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5838 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5839 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5840 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5844 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5845 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5846 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5847 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5849 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5850 AOP(result)->aopu.aop_dir,
5851 AOP(result)->aopu.aop_dir);
5852 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5853 AOP(right)->aopu.aop_dir,
5854 AOP(right)->aopu.aop_dir);
5855 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5856 AOP(left)->aopu.aop_dir,
5857 AOP(left)->aopu.aop_dir);
5858 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5859 AOP(result)->aopu.aop_dir,
5860 AOP(result)->aopu.aop_dir);
5865 symbol *tlbl = newiTempLabel(NULL);
5866 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5869 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5870 if( AOP_TYPE(right) == AOP_ACC) {
5871 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5873 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5874 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5879 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5880 pic16_emitcode(";XXX setb","c");
5881 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5882 AOP(left)->aopu.aop_dir,tlbl->key+100);
5883 pic16_toBoolean(right);
5884 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5885 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5886 jmpTrueOrFalse(ifx, tlbl);
5890 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5897 pic16_outBitC(result);
5899 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5900 genIfxJump(ifx, "c");
5904 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5905 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5906 if((AOP_TYPE(right) == AOP_LIT) &&
5907 (AOP_TYPE(result) == AOP_CRY) &&
5908 (AOP_TYPE(left) != AOP_CRY)){
5910 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5913 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5915 continueIfTrue(ifx);
5918 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5919 // lit = 0, result = boolean(left)
5921 pic16_emitcode(";XXX setb","c");
5922 pic16_toBoolean(right);
5924 symbol *tlbl = newiTempLabel(NULL);
5925 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5927 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5929 genIfxJump (ifx,"a");
5933 pic16_outBitC(result);
5937 /* if left is same as result */
5938 if(pic16_sameRegs(AOP(result),AOP(left))){
5940 for(;size--; offset++,lit>>=8) {
5941 if(AOP_TYPE(right) == AOP_LIT){
5942 if((lit & 0xff) == 0)
5943 /* or'ing with 0 has no effect */
5946 int p = my_powof2(lit & 0xff);
5948 /* only one bit is set in the literal, so use a bsf instruction */
5949 pic16_emitpcode(POC_BSF,
5950 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5952 if(know_W != (lit & 0xff))
5953 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5954 know_W = lit & 0xff;
5955 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5960 if (AOP_TYPE(left) == AOP_ACC) {
5961 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5962 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5964 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5965 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5967 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5968 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5974 // left & result in different registers
5975 if(AOP_TYPE(result) == AOP_CRY){
5977 // if(size), result in bit
5978 // if(!size && ifx), conditional oper: if(left | right)
5979 symbol *tlbl = newiTempLabel(NULL);
5980 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5981 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5985 pic16_emitcode(";XXX setb","c");
5987 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5988 pic16_emitcode(";XXX orl","a,%s",
5989 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5990 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5995 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5996 pic16_outBitC(result);
5998 jmpTrueOrFalse(ifx, tlbl);
5999 } else for(;(size--);offset++){
6001 // result = left & right
6002 if(AOP_TYPE(right) == AOP_LIT){
6003 int t = (lit >> (offset*8)) & 0x0FFL;
6006 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6007 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6009 pic16_emitcode("movf","%s,w",
6010 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6011 pic16_emitcode("movwf","%s",
6012 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6015 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6016 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6017 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6019 pic16_emitcode("movlw","0x%x",t);
6020 pic16_emitcode("iorwf","%s,w",
6021 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6022 pic16_emitcode("movwf","%s",
6023 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6029 // faster than result <- left, anl result,right
6030 // and better if result is SFR
6031 if (AOP_TYPE(left) == AOP_ACC) {
6032 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6033 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6035 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6036 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6038 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6039 pic16_emitcode("iorwf","%s,w",
6040 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6042 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6043 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6048 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6049 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6050 pic16_freeAsmop(result,NULL,ic,TRUE);
6053 /*-----------------------------------------------------------------*/
6054 /* genXor - code for xclusive or */
6055 /*-----------------------------------------------------------------*/
6056 static void genXor (iCode *ic, iCode *ifx)
6058 operand *left, *right, *result;
6060 unsigned long lit = 0L;
6062 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6064 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6065 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6066 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6068 /* if left is a literal & right is not ||
6069 if left needs acc & right does not */
6070 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6071 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6072 operand *tmp = right ;
6077 /* if result = right then exchange them */
6078 if(pic16_sameRegs(AOP(result),AOP(right))){
6079 operand *tmp = right ;
6084 /* if right is bit then exchange them */
6085 if (AOP_TYPE(right) == AOP_CRY &&
6086 AOP_TYPE(left) != AOP_CRY){
6087 operand *tmp = right ;
6091 if(AOP_TYPE(right) == AOP_LIT)
6092 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6094 size = AOP_SIZE(result);
6098 if (AOP_TYPE(left) == AOP_CRY){
6099 if(AOP_TYPE(right) == AOP_LIT){
6100 // c = bit & literal;
6102 // lit>>1 != 0 => result = 1
6103 if(AOP_TYPE(result) == AOP_CRY){
6105 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6106 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6108 continueIfTrue(ifx);
6111 pic16_emitcode("setb","c");
6115 // lit == 0, result = left
6116 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6118 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6120 // lit == 1, result = not(left)
6121 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6122 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6123 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6124 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6127 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6128 pic16_emitcode("cpl","c");
6135 symbol *tlbl = newiTempLabel(NULL);
6136 if (AOP_TYPE(right) == AOP_CRY){
6138 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6141 int sizer = AOP_SIZE(right);
6143 // if val>>1 != 0, result = 1
6144 pic16_emitcode("setb","c");
6146 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6148 // test the msb of the lsb
6149 pic16_emitcode("anl","a,#0xfe");
6150 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6154 pic16_emitcode("rrc","a");
6156 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6157 pic16_emitcode("cpl","c");
6158 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6163 pic16_outBitC(result);
6165 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6166 genIfxJump(ifx, "c");
6170 if(pic16_sameRegs(AOP(result),AOP(left))){
6171 /* if left is same as result */
6172 for(;size--; offset++) {
6173 if(AOP_TYPE(right) == AOP_LIT){
6174 int t = (lit >> (offset*8)) & 0x0FFL;
6178 if (IS_AOP_PREG(left)) {
6179 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6180 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6181 pic16_aopPut(AOP(result),"a",offset);
6183 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6184 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6185 pic16_emitcode("xrl","%s,%s",
6186 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6187 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6190 if (AOP_TYPE(left) == AOP_ACC)
6191 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6193 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6194 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6196 if (IS_AOP_PREG(left)) {
6197 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6198 pic16_aopPut(AOP(result),"a",offset);
6200 pic16_emitcode("xrl","%s,a",
6201 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6207 // left & result in different registers
6208 if(AOP_TYPE(result) == AOP_CRY){
6210 // if(size), result in bit
6211 // if(!size && ifx), conditional oper: if(left ^ right)
6212 symbol *tlbl = newiTempLabel(NULL);
6213 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6215 pic16_emitcode("setb","c");
6217 if((AOP_TYPE(right) == AOP_LIT) &&
6218 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6219 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6221 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6222 pic16_emitcode("xrl","a,%s",
6223 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6225 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6230 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6231 pic16_outBitC(result);
6233 jmpTrueOrFalse(ifx, tlbl);
6234 } else for(;(size--);offset++){
6236 // result = left & right
6237 if(AOP_TYPE(right) == AOP_LIT){
6238 int t = (lit >> (offset*8)) & 0x0FFL;
6241 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6242 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6243 pic16_emitcode("movf","%s,w",
6244 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6245 pic16_emitcode("movwf","%s",
6246 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6249 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6250 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6251 pic16_emitcode("comf","%s,w",
6252 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6253 pic16_emitcode("movwf","%s",
6254 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6257 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6258 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6259 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6260 pic16_emitcode("movlw","0x%x",t);
6261 pic16_emitcode("xorwf","%s,w",
6262 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6263 pic16_emitcode("movwf","%s",
6264 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6270 // faster than result <- left, anl result,right
6271 // and better if result is SFR
6272 if (AOP_TYPE(left) == AOP_ACC) {
6273 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6274 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6276 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6277 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6278 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6279 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6281 if ( AOP_TYPE(result) != AOP_ACC){
6282 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6283 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6289 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6290 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6291 pic16_freeAsmop(result,NULL,ic,TRUE);
6294 /*-----------------------------------------------------------------*/
6295 /* genInline - write the inline code out */
6296 /*-----------------------------------------------------------------*/
6297 static void genInline (iCode *ic)
6299 char *buffer, *bp, *bp1;
6301 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6303 _G.inLine += (!options.asmpeep);
6305 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6306 strcpy(buffer,IC_INLINE(ic));
6308 /* emit each line as a code */
6314 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6315 // inline directly, no process
6322 pic16_emitcode(bp1,"");
6328 if ((bp1 != bp) && *bp1)
6329 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); //pic16_AssembleLine(bp1, 0));
6333 _G.inLine -= (!options.asmpeep);
6336 /*-----------------------------------------------------------------*/
6337 /* genRRC - rotate right with carry */
6338 /*-----------------------------------------------------------------*/
6339 static void genRRC (iCode *ic)
6341 operand *left , *result ;
6342 int size, offset = 0, same;
6344 /* rotate right with carry */
6346 result=IC_RESULT(ic);
6347 pic16_aopOp (left,ic,FALSE);
6348 pic16_aopOp (result,ic,FALSE);
6350 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6352 same = pic16_sameRegs(AOP(result),AOP(left));
6354 size = AOP_SIZE(result);
6356 /* get the lsb and put it into the carry */
6357 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6364 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6366 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6367 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6373 pic16_freeAsmop(left,NULL,ic,TRUE);
6374 pic16_freeAsmop(result,NULL,ic,TRUE);
6377 /*-----------------------------------------------------------------*/
6378 /* genRLC - generate code for rotate left with carry */
6379 /*-----------------------------------------------------------------*/
6380 static void genRLC (iCode *ic)
6382 operand *left , *result ;
6383 int size, offset = 0;
6386 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6387 /* rotate right with carry */
6389 result=IC_RESULT(ic);
6390 pic16_aopOp (left,ic,FALSE);
6391 pic16_aopOp (result,ic,FALSE);
6393 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6395 same = pic16_sameRegs(AOP(result),AOP(left));
6397 /* move it to the result */
6398 size = AOP_SIZE(result);
6400 /* get the msb and put it into the carry */
6401 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6408 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6410 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6411 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6418 pic16_freeAsmop(left,NULL,ic,TRUE);
6419 pic16_freeAsmop(result,NULL,ic,TRUE);
6422 /*-----------------------------------------------------------------*/
6423 /* genGetHbit - generates code get highest order bit */
6424 /*-----------------------------------------------------------------*/
6425 static void genGetHbit (iCode *ic)
6427 operand *left, *result;
6429 result=IC_RESULT(ic);
6430 pic16_aopOp (left,ic,FALSE);
6431 pic16_aopOp (result,ic,FALSE);
6433 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6434 /* get the highest order byte into a */
6435 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6436 if(AOP_TYPE(result) == AOP_CRY){
6437 pic16_emitcode("rlc","a");
6438 pic16_outBitC(result);
6441 pic16_emitcode("rl","a");
6442 pic16_emitcode("anl","a,#0x01");
6443 pic16_outAcc(result);
6447 pic16_freeAsmop(left,NULL,ic,TRUE);
6448 pic16_freeAsmop(result,NULL,ic,TRUE);
6451 /*-----------------------------------------------------------------*/
6452 /* AccRol - rotate left accumulator by known count */
6453 /*-----------------------------------------------------------------*/
6454 static void AccRol (int shCount)
6456 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6457 shCount &= 0x0007; // shCount : 0..7
6462 pic16_emitcode("rl","a");
6465 pic16_emitcode("rl","a");
6466 pic16_emitcode("rl","a");
6469 pic16_emitcode("swap","a");
6470 pic16_emitcode("rr","a");
6473 pic16_emitcode("swap","a");
6476 pic16_emitcode("swap","a");
6477 pic16_emitcode("rl","a");
6480 pic16_emitcode("rr","a");
6481 pic16_emitcode("rr","a");
6484 pic16_emitcode("rr","a");
6489 /*-----------------------------------------------------------------*/
6490 /* AccLsh - left shift accumulator by known count */
6491 /*-----------------------------------------------------------------*/
6492 static void AccLsh (int shCount)
6494 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6497 pic16_emitcode("add","a,acc");
6500 pic16_emitcode("add","a,acc");
6501 pic16_emitcode("add","a,acc");
6503 /* rotate left accumulator */
6505 /* and kill the lower order bits */
6506 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6511 /*-----------------------------------------------------------------*/
6512 /* AccRsh - right shift accumulator by known count */
6513 /*-----------------------------------------------------------------*/
6514 static void AccRsh (int shCount)
6516 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6520 pic16_emitcode("rrc","a");
6522 /* rotate right accumulator */
6523 AccRol(8 - shCount);
6524 /* and kill the higher order bits */
6525 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6531 /*-----------------------------------------------------------------*/
6532 /* AccSRsh - signed right shift accumulator by known count */
6533 /*-----------------------------------------------------------------*/
6534 static void AccSRsh (int shCount)
6537 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6540 pic16_emitcode("mov","c,acc.7");
6541 pic16_emitcode("rrc","a");
6542 } else if(shCount == 2){
6543 pic16_emitcode("mov","c,acc.7");
6544 pic16_emitcode("rrc","a");
6545 pic16_emitcode("mov","c,acc.7");
6546 pic16_emitcode("rrc","a");
6548 tlbl = newiTempLabel(NULL);
6549 /* rotate right accumulator */
6550 AccRol(8 - shCount);
6551 /* and kill the higher order bits */
6552 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6553 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6554 pic16_emitcode("orl","a,#0x%02x",
6555 (unsigned char)~SRMask[shCount]);
6556 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6561 /*-----------------------------------------------------------------*/
6562 /* shiftR1Left2Result - shift right one byte from left to result */
6563 /*-----------------------------------------------------------------*/
6564 static void shiftR1Left2ResultSigned (operand *left, int offl,
6565 operand *result, int offr,
6570 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6572 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6576 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6578 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6580 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6581 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6587 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6589 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6591 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6592 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6594 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6595 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6601 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6603 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6604 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6607 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6608 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6609 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6611 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6612 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6614 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6618 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6619 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6620 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6621 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6622 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6626 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6628 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6629 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6631 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6632 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6633 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6634 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6635 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6640 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6641 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6642 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6643 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6644 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6645 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6647 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6648 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6649 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6650 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6651 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6657 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6658 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6659 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6660 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6662 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6663 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6664 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6672 /*-----------------------------------------------------------------*/
6673 /* shiftR1Left2Result - shift right one byte from left to result */
6674 /*-----------------------------------------------------------------*/
6675 static void shiftR1Left2Result (operand *left, int offl,
6676 operand *result, int offr,
6677 int shCount, int sign)
6681 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6683 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6685 /* Copy the msb into the carry if signed. */
6687 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6697 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6699 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6700 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6706 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6708 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6709 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6712 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6717 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6719 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6720 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6723 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6724 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6725 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6726 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6730 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6731 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6732 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6736 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6737 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6738 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6740 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6745 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6746 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6747 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6748 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6749 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6754 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6755 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6756 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6765 /*-----------------------------------------------------------------*/
6766 /* shiftL1Left2Result - shift left one byte from left to result */
6767 /*-----------------------------------------------------------------*/
6768 static void shiftL1Left2Result (operand *left, int offl,
6769 operand *result, int offr, int shCount)
6774 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6776 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6777 DEBUGpic16_emitcode ("; ***","same = %d",same);
6778 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6780 /* shift left accumulator */
6781 //AccLsh(shCount); // don't comment out just yet...
6782 // pic16_aopPut(AOP(result),"a",offr);
6786 /* Shift left 1 bit position */
6787 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6789 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6791 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6792 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6796 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6797 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6798 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6799 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6802 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6803 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6804 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6805 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6806 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6809 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6810 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6811 pic16_emitpcode(POC_MOVWF,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));
6817 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6820 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6821 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6822 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6823 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6824 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6827 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6828 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6829 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6833 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6838 /*-----------------------------------------------------------------*/
6839 /* movLeft2Result - move byte from left to result */
6840 /*-----------------------------------------------------------------*/
6841 static void movLeft2Result (operand *left, int offl,
6842 operand *result, int offr)
6845 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6846 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6847 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6849 if (*l == '@' && (IS_AOP_PREG(result))) {
6850 pic16_emitcode("mov","a,%s",l);
6851 pic16_aopPut(AOP(result),"a",offr);
6853 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6854 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6859 /*-----------------------------------------------------------------*/
6860 /* shiftL2Left2Result - shift left two bytes from left to result */
6861 /*-----------------------------------------------------------------*/
6862 static void shiftL2Left2Result (operand *left, int offl,
6863 operand *result, int offr, int shCount)
6867 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6869 if(pic16_sameRegs(AOP(result), AOP(left))) {
6877 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6878 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6879 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6883 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6884 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6890 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6891 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6892 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6893 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6894 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6895 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6896 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6898 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6899 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6903 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6904 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6905 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6906 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6907 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6908 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6909 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6910 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6911 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6912 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6915 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6916 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6917 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6918 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6919 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6929 /* note, use a mov/add for the shift since the mov has a
6930 chance of getting optimized out */
6931 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6932 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6933 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6934 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6935 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6939 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6940 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6946 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6947 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6948 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6949 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6950 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6951 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6952 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6953 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6957 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6958 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6962 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6963 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6964 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6965 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6967 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6968 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6969 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6970 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6971 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6972 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6973 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6974 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6977 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6978 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6979 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6980 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6981 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6986 /*-----------------------------------------------------------------*/
6987 /* shiftR2Left2Result - shift right two bytes from left to result */
6988 /*-----------------------------------------------------------------*/
6989 static void shiftR2Left2Result (operand *left, int offl,
6990 operand *result, int offr,
6991 int shCount, int sign)
6995 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6996 same = pic16_sameRegs(AOP(result), AOP(left));
6998 if(same && ((offl + MSB16) == offr)){
7000 /* don't crash result[offr] */
7001 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
7002 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
7005 movLeft2Result(left,offl, result, offr);
7006 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
7009 /* a:x >> shCount (x = lsb(result))*/
7012 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
7014 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
7023 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7028 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7029 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7031 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7032 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7033 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7034 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7039 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7042 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7043 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7050 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7051 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7052 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7054 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7055 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7056 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7057 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7059 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7060 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7061 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7063 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7064 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7065 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7066 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7067 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7071 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7072 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7076 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7077 pic16_emitpcode(POC_BTFSC,
7078 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7079 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7087 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7088 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7090 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7091 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7092 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7093 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7095 pic16_emitpcode(POC_BTFSC,
7096 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7097 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7099 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7100 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7101 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7102 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7104 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7105 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7106 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7107 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7108 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7109 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7110 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7111 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7113 pic16_emitpcode(POC_BTFSC,
7114 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7115 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7117 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7118 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7125 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7126 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7127 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7128 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7131 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7133 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7138 /*-----------------------------------------------------------------*/
7139 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7140 /*-----------------------------------------------------------------*/
7141 static void shiftLLeftOrResult (operand *left, int offl,
7142 operand *result, int offr, int shCount)
7144 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7145 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
7146 /* shift left accumulator */
7148 /* or with result */
7149 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
7150 /* back to result */
7151 pic16_aopPut(AOP(result),"a",offr);
7154 /*-----------------------------------------------------------------*/
7155 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7156 /*-----------------------------------------------------------------*/
7157 static void shiftRLeftOrResult (operand *left, int offl,
7158 operand *result, int offr, int shCount)
7160 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7161 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
7162 /* shift right accumulator */
7164 /* or with result */
7165 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
7166 /* back to result */
7167 pic16_aopPut(AOP(result),"a",offr);
7170 /*-----------------------------------------------------------------*/
7171 /* genlshOne - left shift a one byte quantity by known count */
7172 /*-----------------------------------------------------------------*/
7173 static void genlshOne (operand *result, operand *left, int shCount)
7175 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7176 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7179 /*-----------------------------------------------------------------*/
7180 /* genlshTwo - left shift two bytes by known amount != 0 */
7181 /*-----------------------------------------------------------------*/
7182 static void genlshTwo (operand *result,operand *left, int shCount)
7186 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7187 size = pic16_getDataSize(result);
7189 /* if shCount >= 8 */
7195 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7197 movLeft2Result(left, LSB, result, MSB16);
7199 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7202 /* 1 <= shCount <= 7 */
7205 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7207 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7211 /*-----------------------------------------------------------------*/
7212 /* shiftLLong - shift left one long from left to result */
7213 /* offl = LSB or MSB16 */
7214 /*-----------------------------------------------------------------*/
7215 static void shiftLLong (operand *left, operand *result, int offr )
7218 int size = AOP_SIZE(result);
7220 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7221 if(size >= LSB+offr){
7222 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7224 pic16_emitcode("add","a,acc");
7225 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7226 size >= MSB16+offr && offr != LSB )
7227 pic16_emitcode("xch","a,%s",
7228 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7230 pic16_aopPut(AOP(result),"a",LSB+offr);
7233 if(size >= MSB16+offr){
7234 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7235 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7238 pic16_emitcode("rlc","a");
7239 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7240 size >= MSB24+offr && offr != LSB)
7241 pic16_emitcode("xch","a,%s",
7242 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7244 pic16_aopPut(AOP(result),"a",MSB16+offr);
7247 if(size >= MSB24+offr){
7248 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7249 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7252 pic16_emitcode("rlc","a");
7253 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7254 size >= MSB32+offr && offr != LSB )
7255 pic16_emitcode("xch","a,%s",
7256 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7258 pic16_aopPut(AOP(result),"a",MSB24+offr);
7261 if(size > MSB32+offr){
7262 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7263 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7266 pic16_emitcode("rlc","a");
7267 pic16_aopPut(AOP(result),"a",MSB32+offr);
7270 pic16_aopPut(AOP(result),zero,LSB);
7273 /*-----------------------------------------------------------------*/
7274 /* genlshFour - shift four byte by a known amount != 0 */
7275 /*-----------------------------------------------------------------*/
7276 static void genlshFour (operand *result, operand *left, int shCount)
7280 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7281 size = AOP_SIZE(result);
7283 /* if shifting more that 3 bytes */
7284 if (shCount >= 24 ) {
7287 /* lowest order of left goes to the highest
7288 order of the destination */
7289 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7291 movLeft2Result(left, LSB, result, MSB32);
7292 pic16_aopPut(AOP(result),zero,LSB);
7293 pic16_aopPut(AOP(result),zero,MSB16);
7294 pic16_aopPut(AOP(result),zero,MSB32);
7298 /* more than two bytes */
7299 else if ( shCount >= 16 ) {
7300 /* lower order two bytes goes to higher order two bytes */
7302 /* if some more remaining */
7304 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7306 movLeft2Result(left, MSB16, result, MSB32);
7307 movLeft2Result(left, LSB, result, MSB24);
7309 pic16_aopPut(AOP(result),zero,MSB16);
7310 pic16_aopPut(AOP(result),zero,LSB);
7314 /* if more than 1 byte */
7315 else if ( shCount >= 8 ) {
7316 /* lower order three bytes goes to higher order three bytes */
7320 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7322 movLeft2Result(left, LSB, result, MSB16);
7324 else{ /* size = 4 */
7326 movLeft2Result(left, MSB24, result, MSB32);
7327 movLeft2Result(left, MSB16, result, MSB24);
7328 movLeft2Result(left, LSB, result, MSB16);
7329 pic16_aopPut(AOP(result),zero,LSB);
7331 else if(shCount == 1)
7332 shiftLLong(left, result, MSB16);
7334 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7335 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7336 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7337 pic16_aopPut(AOP(result),zero,LSB);
7342 /* 1 <= shCount <= 7 */
7343 else if(shCount <= 2){
7344 shiftLLong(left, result, LSB);
7346 shiftLLong(result, result, LSB);
7348 /* 3 <= shCount <= 7, optimize */
7350 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7351 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7352 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7356 /*-----------------------------------------------------------------*/
7357 /* genLeftShiftLiteral - left shifting by known count */
7358 /*-----------------------------------------------------------------*/
7359 static void genLeftShiftLiteral (operand *left,
7364 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7367 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7368 pic16_freeAsmop(right,NULL,ic,TRUE);
7370 pic16_aopOp(left,ic,FALSE);
7371 pic16_aopOp(result,ic,FALSE);
7373 size = getSize(operandType(result));
7376 pic16_emitcode("; shift left ","result %d, left %d",size,
7380 /* I suppose that the left size >= result size */
7383 movLeft2Result(left, size, result, size);
7387 else if(shCount >= (size * 8))
7389 pic16_aopPut(AOP(result),zero,size);
7393 genlshOne (result,left,shCount);
7398 genlshTwo (result,left,shCount);
7402 genlshFour (result,left,shCount);
7406 pic16_freeAsmop(left,NULL,ic,TRUE);
7407 pic16_freeAsmop(result,NULL,ic,TRUE);
7410 /*-----------------------------------------------------------------*
7411 * genMultiAsm - repeat assembly instruction for size of register.
7412 * if endian == 1, then the high byte (i.e base address + size of
7413 * register) is used first else the low byte is used first;
7414 *-----------------------------------------------------------------*/
7415 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7420 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7433 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7438 /*-----------------------------------------------------------------*/
7439 /* genLeftShift - generates code for left shifting */
7440 /*-----------------------------------------------------------------*/
7441 static void genLeftShift (iCode *ic)
7443 operand *left,*right, *result;
7446 symbol *tlbl , *tlbl1;
7449 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7451 right = IC_RIGHT(ic);
7453 result = IC_RESULT(ic);
7455 pic16_aopOp(right,ic,FALSE);
7457 /* if the shift count is known then do it
7458 as efficiently as possible */
7459 if (AOP_TYPE(right) == AOP_LIT) {
7460 genLeftShiftLiteral (left,right,result,ic);
7464 /* shift count is unknown then we have to form
7465 a loop get the loop count in B : Note: we take
7466 only the lower order byte since shifting
7467 more that 32 bits make no sense anyway, ( the
7468 largest size of an object can be only 32 bits ) */
7471 pic16_aopOp(left,ic,FALSE);
7472 pic16_aopOp(result,ic,FALSE);
7474 /* now move the left to the result if they are not the
7476 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7477 AOP_SIZE(result) > 1) {
7479 size = AOP_SIZE(result);
7482 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7483 if (*l == '@' && (IS_AOP_PREG(result))) {
7485 pic16_emitcode("mov","a,%s",l);
7486 pic16_aopPut(AOP(result),"a",offset);
7488 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7489 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7490 //pic16_aopPut(AOP(result),l,offset);
7496 size = AOP_SIZE(result);
7498 /* if it is only one byte then */
7500 if(optimized_for_speed) {
7501 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7502 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7503 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7504 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7505 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7506 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7507 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7508 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7509 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7510 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7511 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7512 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7515 tlbl = newiTempLabel(NULL);
7516 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7517 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7518 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7521 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7522 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7523 pic16_emitpLabel(tlbl->key);
7524 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7525 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7527 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7532 if (pic16_sameRegs(AOP(left),AOP(result))) {
7534 tlbl = newiTempLabel(NULL);
7535 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7536 genMultiAsm(POC_RRCF, result, size,1);
7537 pic16_emitpLabel(tlbl->key);
7538 genMultiAsm(POC_RLCF, result, size,0);
7539 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7541 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7545 //tlbl = newiTempLabel(NULL);
7547 //tlbl1 = newiTempLabel(NULL);
7549 //reAdjustPreg(AOP(result));
7551 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7552 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7553 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7555 //pic16_emitcode("add","a,acc");
7556 //pic16_aopPut(AOP(result),"a",offset++);
7558 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7560 // pic16_emitcode("rlc","a");
7561 // pic16_aopPut(AOP(result),"a",offset++);
7563 //reAdjustPreg(AOP(result));
7565 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7566 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7569 tlbl = newiTempLabel(NULL);
7570 tlbl1= newiTempLabel(NULL);
7572 size = AOP_SIZE(result);
7575 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7577 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7579 /* offset should be 0, 1 or 3 */
7580 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7582 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7584 pic16_emitpcode(POC_MOVWF, pctemp);
7587 pic16_emitpLabel(tlbl->key);
7590 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7592 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7594 pic16_emitpcode(POC_DECFSZ, pctemp);
7595 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7596 pic16_emitpLabel(tlbl1->key);
7598 pic16_popReleaseTempReg(pctemp);
7602 pic16_freeAsmop (right,NULL,ic,TRUE);
7603 pic16_freeAsmop(left,NULL,ic,TRUE);
7604 pic16_freeAsmop(result,NULL,ic,TRUE);
7607 /*-----------------------------------------------------------------*/
7608 /* genrshOne - right shift a one byte quantity by known count */
7609 /*-----------------------------------------------------------------*/
7610 static void genrshOne (operand *result, operand *left,
7611 int shCount, int sign)
7613 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7614 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7617 /*-----------------------------------------------------------------*/
7618 /* genrshTwo - right shift two bytes by known amount != 0 */
7619 /*-----------------------------------------------------------------*/
7620 static void genrshTwo (operand *result,operand *left,
7621 int shCount, int sign)
7623 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7624 /* if shCount >= 8 */
7628 shiftR1Left2Result(left, MSB16, result, LSB,
7631 movLeft2Result(left, MSB16, result, LSB);
7633 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7636 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7637 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7641 /* 1 <= shCount <= 7 */
7643 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7646 /*-----------------------------------------------------------------*/
7647 /* shiftRLong - shift right one long from left to result */
7648 /* offl = LSB or MSB16 */
7649 /*-----------------------------------------------------------------*/
7650 static void shiftRLong (operand *left, int offl,
7651 operand *result, int sign)
7653 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7655 pic16_emitcode("clr","c");
7656 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7658 pic16_emitcode("mov","c,acc.7");
7659 pic16_emitcode("rrc","a");
7660 pic16_aopPut(AOP(result),"a",MSB32-offl);
7662 /* add sign of "a" */
7663 pic16_addSign(result, MSB32, sign);
7665 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7666 pic16_emitcode("rrc","a");
7667 pic16_aopPut(AOP(result),"a",MSB24-offl);
7669 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7670 pic16_emitcode("rrc","a");
7671 pic16_aopPut(AOP(result),"a",MSB16-offl);
7674 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7675 pic16_emitcode("rrc","a");
7676 pic16_aopPut(AOP(result),"a",LSB);
7680 /*-----------------------------------------------------------------*/
7681 /* genrshFour - shift four byte by a known amount != 0 */
7682 /*-----------------------------------------------------------------*/
7683 static void genrshFour (operand *result, operand *left,
7684 int shCount, int sign)
7686 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7687 /* if shifting more that 3 bytes */
7688 if(shCount >= 24 ) {
7691 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7693 movLeft2Result(left, MSB32, result, LSB);
7695 pic16_addSign(result, MSB16, sign);
7697 else if(shCount >= 16){
7700 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7702 movLeft2Result(left, MSB24, result, LSB);
7703 movLeft2Result(left, MSB32, result, MSB16);
7705 pic16_addSign(result, MSB24, sign);
7707 else if(shCount >= 8){
7710 shiftRLong(left, MSB16, result, sign);
7711 else if(shCount == 0){
7712 movLeft2Result(left, MSB16, result, LSB);
7713 movLeft2Result(left, MSB24, result, MSB16);
7714 movLeft2Result(left, MSB32, result, MSB24);
7715 pic16_addSign(result, MSB32, sign);
7718 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7719 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7720 /* the last shift is signed */
7721 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7722 pic16_addSign(result, MSB32, sign);
7725 else{ /* 1 <= shCount <= 7 */
7727 shiftRLong(left, LSB, result, sign);
7729 shiftRLong(result, LSB, result, sign);
7732 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7733 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7734 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7739 /*-----------------------------------------------------------------*/
7740 /* genRightShiftLiteral - right shifting by known count */
7741 /*-----------------------------------------------------------------*/
7742 static void genRightShiftLiteral (operand *left,
7748 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7751 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7752 pic16_freeAsmop(right,NULL,ic,TRUE);
7754 pic16_aopOp(left,ic,FALSE);
7755 pic16_aopOp(result,ic,FALSE);
7758 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7762 lsize = pic16_getDataSize(left);
7763 res_size = pic16_getDataSize(result);
7764 /* test the LEFT size !!! */
7766 /* I suppose that the left size >= result size */
7769 movLeft2Result(left, lsize, result, res_size);
7772 else if(shCount >= (lsize * 8)){
7775 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7777 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7778 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7783 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7784 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7785 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7787 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7792 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7799 genrshOne (result,left,shCount,sign);
7803 genrshTwo (result,left,shCount,sign);
7807 genrshFour (result,left,shCount,sign);
7815 pic16_freeAsmop(left,NULL,ic,TRUE);
7816 pic16_freeAsmop(result,NULL,ic,TRUE);
7819 /*-----------------------------------------------------------------*/
7820 /* genSignedRightShift - right shift of signed number */
7821 /*-----------------------------------------------------------------*/
7822 static void genSignedRightShift (iCode *ic)
7824 operand *right, *left, *result;
7827 symbol *tlbl, *tlbl1 ;
7830 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7832 /* we do it the hard way put the shift count in b
7833 and loop thru preserving the sign */
7834 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7836 right = IC_RIGHT(ic);
7838 result = IC_RESULT(ic);
7840 pic16_aopOp(right,ic,FALSE);
7841 pic16_aopOp(left,ic,FALSE);
7842 pic16_aopOp(result,ic,FALSE);
7845 if ( AOP_TYPE(right) == AOP_LIT) {
7846 genRightShiftLiteral (left,right,result,ic,1);
7849 /* shift count is unknown then we have to form
7850 a loop get the loop count in B : Note: we take
7851 only the lower order byte since shifting
7852 more that 32 bits make no sense anyway, ( the
7853 largest size of an object can be only 32 bits ) */
7855 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7856 //pic16_emitcode("inc","b");
7857 //pic16_freeAsmop (right,NULL,ic,TRUE);
7858 //pic16_aopOp(left,ic,FALSE);
7859 //pic16_aopOp(result,ic,FALSE);
7861 /* now move the left to the result if they are not the
7863 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7864 AOP_SIZE(result) > 1) {
7866 size = AOP_SIZE(result);
7870 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7871 if (*l == '@' && IS_AOP_PREG(result)) {
7873 pic16_emitcode("mov","a,%s",l);
7874 pic16_aopPut(AOP(result),"a",offset);
7876 pic16_aopPut(AOP(result),l,offset);
7878 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7879 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7885 /* mov the highest order bit to OVR */
7886 tlbl = newiTempLabel(NULL);
7887 tlbl1= newiTempLabel(NULL);
7889 size = AOP_SIZE(result);
7892 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7894 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7896 /* offset should be 0, 1 or 3 */
7897 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7899 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7901 pic16_emitpcode(POC_MOVWF, pctemp);
7904 pic16_emitpLabel(tlbl->key);
7906 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7907 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7910 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7913 pic16_emitpcode(POC_DECFSZ, pctemp);
7914 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7915 pic16_emitpLabel(tlbl1->key);
7917 pic16_popReleaseTempReg(pctemp);
7919 size = AOP_SIZE(result);
7921 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7922 pic16_emitcode("rlc","a");
7923 pic16_emitcode("mov","ov,c");
7924 /* if it is only one byte then */
7926 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7928 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7929 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7930 pic16_emitcode("mov","c,ov");
7931 pic16_emitcode("rrc","a");
7932 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7933 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7934 pic16_aopPut(AOP(result),"a",0);
7938 reAdjustPreg(AOP(result));
7939 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7940 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7941 pic16_emitcode("mov","c,ov");
7943 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7945 pic16_emitcode("rrc","a");
7946 pic16_aopPut(AOP(result),"a",offset--);
7948 reAdjustPreg(AOP(result));
7949 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7950 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7955 pic16_freeAsmop(left,NULL,ic,TRUE);
7956 pic16_freeAsmop(result,NULL,ic,TRUE);
7957 pic16_freeAsmop(right,NULL,ic,TRUE);
7960 /*-----------------------------------------------------------------*/
7961 /* genRightShift - generate code for right shifting */
7962 /*-----------------------------------------------------------------*/
7963 static void genRightShift (iCode *ic)
7965 operand *right, *left, *result;
7969 symbol *tlbl, *tlbl1 ;
7971 /* if signed then we do it the hard way preserve the
7972 sign bit moving it inwards */
7973 retype = getSpec(operandType(IC_RESULT(ic)));
7974 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7976 if (!SPEC_USIGN(retype)) {
7977 genSignedRightShift (ic);
7981 /* signed & unsigned types are treated the same : i.e. the
7982 signed is NOT propagated inwards : quoting from the
7983 ANSI - standard : "for E1 >> E2, is equivalent to division
7984 by 2**E2 if unsigned or if it has a non-negative value,
7985 otherwise the result is implementation defined ", MY definition
7986 is that the sign does not get propagated */
7988 right = IC_RIGHT(ic);
7990 result = IC_RESULT(ic);
7992 pic16_aopOp(right,ic,FALSE);
7994 /* if the shift count is known then do it
7995 as efficiently as possible */
7996 if (AOP_TYPE(right) == AOP_LIT) {
7997 genRightShiftLiteral (left,right,result,ic, 0);
8001 /* shift count is unknown then we have to form
8002 a loop get the loop count in B : Note: we take
8003 only the lower order byte since shifting
8004 more that 32 bits make no sense anyway, ( the
8005 largest size of an object can be only 32 bits ) */
8007 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8008 pic16_emitcode("inc","b");
8009 pic16_aopOp(left,ic,FALSE);
8010 pic16_aopOp(result,ic,FALSE);
8012 /* now move the left to the result if they are not the
8014 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8015 AOP_SIZE(result) > 1) {
8017 size = AOP_SIZE(result);
8020 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8021 if (*l == '@' && IS_AOP_PREG(result)) {
8023 pic16_emitcode("mov","a,%s",l);
8024 pic16_aopPut(AOP(result),"a",offset);
8026 pic16_aopPut(AOP(result),l,offset);
8031 tlbl = newiTempLabel(NULL);
8032 tlbl1= newiTempLabel(NULL);
8033 size = AOP_SIZE(result);
8036 /* if it is only one byte then */
8039 tlbl = newiTempLabel(NULL);
8040 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8041 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8042 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8045 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8046 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8047 pic16_emitpLabel(tlbl->key);
8048 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8049 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8051 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8056 reAdjustPreg(AOP(result));
8057 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8058 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8061 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8063 pic16_emitcode("rrc","a");
8064 pic16_aopPut(AOP(result),"a",offset--);
8066 reAdjustPreg(AOP(result));
8068 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8069 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8072 pic16_freeAsmop(left,NULL,ic,TRUE);
8073 pic16_freeAsmop (right,NULL,ic,TRUE);
8074 pic16_freeAsmop(result,NULL,ic,TRUE);
8077 /*-----------------------------------------------------------------*/
8078 /* genUnpackBits - generates code for unpacking bits */
8079 /*-----------------------------------------------------------------*/
8080 static void genUnpackBits (operand *result, char *rname, int ptype)
8087 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8088 etype = getSpec(operandType(result));
8090 /* read the first byte */
8095 pic16_emitcode("mov","a,@%s",rname);
8099 pic16_emitcode("movx","a,@%s",rname);
8103 pic16_emitcode("movx","a,@dptr");
8107 pic16_emitcode("clr","a");
8108 pic16_emitcode("movc","a","@a+dptr");
8112 pic16_emitcode("lcall","__gptrget");
8116 /* if we have bitdisplacement then it fits */
8117 /* into this byte completely or if length is */
8118 /* less than a byte */
8119 if ((shCnt = SPEC_BSTR(etype)) ||
8120 (SPEC_BLEN(etype) <= 8)) {
8122 /* shift right acc */
8125 pic16_emitcode("anl","a,#0x%02x",
8126 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8127 pic16_aopPut(AOP(result),"a",offset);
8131 /* bit field did not fit in a byte */
8132 rlen = SPEC_BLEN(etype) - 8;
8133 pic16_aopPut(AOP(result),"a",offset++);
8140 pic16_emitcode("inc","%s",rname);
8141 pic16_emitcode("mov","a,@%s",rname);
8145 pic16_emitcode("inc","%s",rname);
8146 pic16_emitcode("movx","a,@%s",rname);
8150 pic16_emitcode("inc","dptr");
8151 pic16_emitcode("movx","a,@dptr");
8155 pic16_emitcode("clr","a");
8156 pic16_emitcode("inc","dptr");
8157 pic16_emitcode("movc","a","@a+dptr");
8161 pic16_emitcode("inc","dptr");
8162 pic16_emitcode("lcall","__gptrget");
8167 /* if we are done */
8171 pic16_aopPut(AOP(result),"a",offset++);
8176 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8177 pic16_aopPut(AOP(result),"a",offset);
8184 /*-----------------------------------------------------------------*/
8185 /* genDataPointerGet - generates code when ptr offset is known */
8186 /*-----------------------------------------------------------------*/
8187 static void genDataPointerGet (operand *left,
8191 int size , offset = 0;
8194 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8197 /* optimization - most of the time, left and result are the same
8198 * address, but different types. for the pic code, we could omit
8202 pic16_aopOp(result,ic,TRUE);
8204 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8206 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8208 size = AOP_SIZE(result);
8211 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8215 pic16_freeAsmop(left,NULL,ic,TRUE);
8216 pic16_freeAsmop(result,NULL,ic,TRUE);
8219 /*-----------------------------------------------------------------*/
8220 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8221 /*-----------------------------------------------------------------*/
8222 static void genNearPointerGet (operand *left,
8227 //regs *preg = NULL ;
8229 sym_link *rtype, *retype;
8230 sym_link *ltype = operandType(left);
8233 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8235 rtype = operandType(result);
8236 retype= getSpec(rtype);
8238 pic16_aopOp(left,ic,FALSE);
8240 /* if left is rematerialisable and
8241 result is not bit variable type and
8242 the left is pointer to data space i.e
8243 lower 128 bytes of space */
8244 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8245 !IS_BITVAR(retype) &&
8246 DCL_TYPE(ltype) == POINTER) {
8247 //genDataPointerGet (left,result,ic);
8251 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8253 /* if the value is already in a pointer register
8254 then don't need anything more */
8255 if (!AOP_INPREG(AOP(left))) {
8256 /* otherwise get a free pointer register */
8257 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8260 preg = getFreePtr(ic,&aop,FALSE);
8261 pic16_emitcode("mov","%s,%s",
8263 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8264 rname = preg->name ;
8268 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8270 pic16_aopOp (result,ic,FALSE);
8272 /* if bitfield then unpack the bits */
8273 if (IS_BITVAR(retype))
8274 genUnpackBits (result,rname,POINTER);
8276 /* we have can just get the values */
8277 int size = AOP_SIZE(result);
8280 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8282 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8283 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8285 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8286 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8288 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8292 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8294 pic16_emitcode("mov","a,@%s",rname);
8295 pic16_aopPut(AOP(result),"a",offset);
8297 sprintf(buffer,"@%s",rname);
8298 pic16_aopPut(AOP(result),buffer,offset);
8302 pic16_emitcode("inc","%s",rname);
8307 /* now some housekeeping stuff */
8309 /* we had to allocate for this iCode */
8310 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8311 pic16_freeAsmop(NULL,aop,ic,TRUE);
8313 /* we did not allocate which means left
8314 already in a pointer register, then
8315 if size > 0 && this could be used again
8316 we have to point it back to where it
8318 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8319 if (AOP_SIZE(result) > 1 &&
8320 !OP_SYMBOL(left)->remat &&
8321 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8323 int size = AOP_SIZE(result) - 1;
8325 pic16_emitcode("dec","%s",rname);
8330 pic16_freeAsmop(left,NULL,ic,TRUE);
8331 pic16_freeAsmop(result,NULL,ic,TRUE);
8335 /*-----------------------------------------------------------------*/
8336 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8337 /*-----------------------------------------------------------------*/
8338 static void genPagedPointerGet (operand *left,
8345 sym_link *rtype, *retype;
8347 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8349 rtype = operandType(result);
8350 retype= getSpec(rtype);
8352 pic16_aopOp(left,ic,FALSE);
8354 /* if the value is already in a pointer register
8355 then don't need anything more */
8356 if (!AOP_INPREG(AOP(left))) {
8357 /* otherwise get a free pointer register */
8359 preg = getFreePtr(ic,&aop,FALSE);
8360 pic16_emitcode("mov","%s,%s",
8362 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8363 rname = preg->name ;
8365 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8367 pic16_freeAsmop(left,NULL,ic,TRUE);
8368 pic16_aopOp (result,ic,FALSE);
8370 /* if bitfield then unpack the bits */
8371 if (IS_BITVAR(retype))
8372 genUnpackBits (result,rname,PPOINTER);
8374 /* we have can just get the values */
8375 int size = AOP_SIZE(result);
8380 pic16_emitcode("movx","a,@%s",rname);
8381 pic16_aopPut(AOP(result),"a",offset);
8386 pic16_emitcode("inc","%s",rname);
8390 /* now some housekeeping stuff */
8392 /* we had to allocate for this iCode */
8393 pic16_freeAsmop(NULL,aop,ic,TRUE);
8395 /* we did not allocate which means left
8396 already in a pointer register, then
8397 if size > 0 && this could be used again
8398 we have to point it back to where it
8400 if (AOP_SIZE(result) > 1 &&
8401 !OP_SYMBOL(left)->remat &&
8402 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8404 int size = AOP_SIZE(result) - 1;
8406 pic16_emitcode("dec","%s",rname);
8411 pic16_freeAsmop(result,NULL,ic,TRUE);
8416 /*-----------------------------------------------------------------*/
8417 /* genFarPointerGet - gget value from far space */
8418 /*-----------------------------------------------------------------*/
8419 static void genFarPointerGet (operand *left,
8420 operand *result, iCode *ic)
8423 sym_link *retype = getSpec(operandType(result));
8425 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8427 pic16_aopOp(left,ic,FALSE);
8429 /* if the operand is already in dptr
8430 then we do nothing else we move the value to dptr */
8431 if (AOP_TYPE(left) != AOP_STR) {
8432 /* if this is remateriazable */
8433 if (AOP_TYPE(left) == AOP_IMMD)
8434 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8435 else { /* we need to get it byte by byte */
8436 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8437 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8438 if (options.model == MODEL_FLAT24)
8440 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8444 /* so dptr know contains the address */
8445 pic16_freeAsmop(left,NULL,ic,TRUE);
8446 pic16_aopOp(result,ic,FALSE);
8448 /* if bit then unpack */
8449 if (IS_BITVAR(retype))
8450 genUnpackBits(result,"dptr",FPOINTER);
8452 size = AOP_SIZE(result);
8456 pic16_emitcode("movx","a,@dptr");
8457 pic16_aopPut(AOP(result),"a",offset++);
8459 pic16_emitcode("inc","dptr");
8463 pic16_freeAsmop(result,NULL,ic,TRUE);
8466 /*-----------------------------------------------------------------*/
8467 /* genCodePointerGet - get value from code space */
8468 /*-----------------------------------------------------------------*/
8469 static void genCodePointerGet (operand *left,
8470 operand *result, iCode *ic)
8473 sym_link *retype = getSpec(operandType(result));
8475 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8477 pic16_aopOp(left,ic,FALSE);
8479 /* if the operand is already in dptr
8480 then we do nothing else we move the value to dptr */
8481 if (AOP_TYPE(left) != AOP_STR) {
8482 /* if this is remateriazable */
8483 if (AOP_TYPE(left) == AOP_IMMD)
8484 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8485 else { /* we need to get it byte by byte */
8486 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8487 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8488 if (options.model == MODEL_FLAT24)
8490 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8494 /* so dptr know contains the address */
8495 pic16_freeAsmop(left,NULL,ic,TRUE);
8496 pic16_aopOp(result,ic,FALSE);
8498 /* if bit then unpack */
8499 if (IS_BITVAR(retype))
8500 genUnpackBits(result,"dptr",CPOINTER);
8502 size = AOP_SIZE(result);
8506 pic16_emitcode("clr","a");
8507 pic16_emitcode("movc","a,@a+dptr");
8508 pic16_aopPut(AOP(result),"a",offset++);
8510 pic16_emitcode("inc","dptr");
8514 pic16_freeAsmop(result,NULL,ic,TRUE);
8517 /*-----------------------------------------------------------------*/
8518 /* genGenPointerGet - gget value from generic pointer space */
8519 /*-----------------------------------------------------------------*/
8520 static void genGenPointerGet (operand *left,
8521 operand *result, iCode *ic)
8524 sym_link *retype = getSpec(operandType(result));
8526 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8527 pic16_aopOp(left,ic,FALSE);
8528 pic16_aopOp(result,ic,FALSE);
8531 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8533 /* if the operand is already in dptr
8534 then we do nothing else we move the value to dptr */
8535 // if (AOP_TYPE(left) != AOP_STR) {
8536 /* if this is remateriazable */
8537 if (AOP_TYPE(left) == AOP_IMMD) {
8538 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8539 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8541 else { /* we need to get it byte by byte */
8543 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8544 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8546 size = AOP_SIZE(result);
8550 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8551 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8553 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8558 /* so dptr know contains the address */
8560 /* if bit then unpack */
8561 //if (IS_BITVAR(retype))
8562 // genUnpackBits(result,"dptr",GPOINTER);
8565 pic16_freeAsmop(left,NULL,ic,TRUE);
8566 pic16_freeAsmop(result,NULL,ic,TRUE);
8570 /*-----------------------------------------------------------------*/
8571 /* genConstPointerGet - get value from const generic pointer space */
8572 /*-----------------------------------------------------------------*/
8573 static void genConstPointerGet (operand *left,
8574 operand *result, iCode *ic)
8576 //sym_link *retype = getSpec(operandType(result));
8577 symbol *albl = newiTempLabel(NULL);
8578 symbol *blbl = newiTempLabel(NULL);
8581 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8582 pic16_aopOp(left,ic,FALSE);
8583 pic16_aopOp(result,ic,FALSE);
8586 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8588 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8590 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8591 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8592 pic16_emitpLabel(albl->key);
8594 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8596 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
8597 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8598 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8599 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8600 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8602 pic16_emitpLabel(blbl->key);
8604 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8607 pic16_freeAsmop(left,NULL,ic,TRUE);
8608 pic16_freeAsmop(result,NULL,ic,TRUE);
8611 /*-----------------------------------------------------------------*/
8612 /* genPointerGet - generate code for pointer get */
8613 /*-----------------------------------------------------------------*/
8614 static void genPointerGet (iCode *ic)
8616 operand *left, *result ;
8617 sym_link *type, *etype;
8620 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8623 result = IC_RESULT(ic) ;
8625 /* depending on the type of pointer we need to
8626 move it to the correct pointer register */
8627 type = operandType(left);
8628 etype = getSpec(type);
8631 if (IS_PTR_CONST(type))
8633 if (IS_CODEPTR(type))
8635 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8637 /* if left is of type of pointer then it is simple */
8638 if (IS_PTR(type) && !IS_FUNC(type->next))
8639 p_type = DCL_TYPE(type);
8641 /* we have to go by the storage class */
8642 p_type = PTR_TYPE(SPEC_OCLS(etype));
8644 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8646 if (SPEC_OCLS(etype)->codesp ) {
8647 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8648 //p_type = CPOINTER ;
8651 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8652 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8653 /*p_type = FPOINTER ;*/
8655 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8656 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8657 /* p_type = PPOINTER; */
8659 if (SPEC_OCLS(etype) == idata )
8660 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8661 /* p_type = IPOINTER; */
8663 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8664 /* p_type = POINTER ; */
8667 /* now that we have the pointer type we assign
8668 the pointer values */
8673 genNearPointerGet (left,result,ic);
8677 genPagedPointerGet(left,result,ic);
8681 genFarPointerGet (left,result,ic);
8685 genConstPointerGet (left,result,ic);
8686 //pic16_emitcodePointerGet (left,result,ic);
8691 if (IS_PTR_CONST(type))
8692 genConstPointerGet (left,result,ic);
8695 genGenPointerGet (left,result,ic);
8701 /*-----------------------------------------------------------------*/
8702 /* genPackBits - generates code for packed bit storage */
8703 /*-----------------------------------------------------------------*/
8704 static void genPackBits (sym_link *etype ,
8706 char *rname, int p_type)
8714 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8715 blen = SPEC_BLEN(etype);
8716 bstr = SPEC_BSTR(etype);
8718 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8721 /* if the bit lenth is less than or */
8722 /* it exactly fits a byte then */
8723 if (SPEC_BLEN(etype) <= 8 ) {
8724 shCount = SPEC_BSTR(etype) ;
8726 /* shift left acc */
8729 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8734 pic16_emitcode ("mov","b,a");
8735 pic16_emitcode("mov","a,@%s",rname);
8739 pic16_emitcode ("mov","b,a");
8740 pic16_emitcode("movx","a,@dptr");
8744 pic16_emitcode ("push","b");
8745 pic16_emitcode ("push","acc");
8746 pic16_emitcode ("lcall","__gptrget");
8747 pic16_emitcode ("pop","b");
8751 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8752 ((unsigned char)(0xFF << (blen+bstr)) |
8753 (unsigned char)(0xFF >> (8-bstr)) ) );
8754 pic16_emitcode ("orl","a,b");
8755 if (p_type == GPOINTER)
8756 pic16_emitcode("pop","b");
8762 pic16_emitcode("mov","@%s,a",rname);
8766 pic16_emitcode("movx","@dptr,a");
8770 DEBUGpic16_emitcode(";lcall","__gptrput");
8775 if ( SPEC_BLEN(etype) <= 8 )
8778 pic16_emitcode("inc","%s",rname);
8779 rLen = SPEC_BLEN(etype) ;
8781 /* now generate for lengths greater than one byte */
8784 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8794 pic16_emitcode("mov","@%s,a",rname);
8796 pic16_emitcode("mov","@%s,%s",rname,l);
8801 pic16_emitcode("movx","@dptr,a");
8806 DEBUGpic16_emitcode(";lcall","__gptrput");
8809 pic16_emitcode ("inc","%s",rname);
8814 /* last last was not complete */
8816 /* save the byte & read byte */
8819 pic16_emitcode ("mov","b,a");
8820 pic16_emitcode("mov","a,@%s",rname);
8824 pic16_emitcode ("mov","b,a");
8825 pic16_emitcode("movx","a,@dptr");
8829 pic16_emitcode ("push","b");
8830 pic16_emitcode ("push","acc");
8831 pic16_emitcode ("lcall","__gptrget");
8832 pic16_emitcode ("pop","b");
8836 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8837 pic16_emitcode ("orl","a,b");
8840 if (p_type == GPOINTER)
8841 pic16_emitcode("pop","b");
8846 pic16_emitcode("mov","@%s,a",rname);
8850 pic16_emitcode("movx","@dptr,a");
8854 DEBUGpic16_emitcode(";lcall","__gptrput");
8858 /*-----------------------------------------------------------------*/
8859 /* genDataPointerSet - remat pointer to data space */
8860 /*-----------------------------------------------------------------*/
8861 static void genDataPointerSet(operand *right,
8865 int size, offset = 0 ;
8866 char *l, buffer[256];
8868 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8869 pic16_aopOp(right,ic,FALSE);
8871 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8872 size = AOP_SIZE(right);
8874 if ( AOP_TYPE(result) == AOP_PCODE) {
8875 fprintf(stderr,"genDataPointerSet %s, %d\n",
8876 AOP(result)->aopu.pcop->name,
8877 PCOI(AOP(result)->aopu.pcop)->offset);
8881 // tsd, was l+1 - the underline `_' prefix was being stripped
8884 sprintf(buffer,"(%s + %d)",l,offset);
8885 fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer);
8887 sprintf(buffer,"%s",l);
8889 if (AOP_TYPE(right) == AOP_LIT) {
8890 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8891 lit = lit >> (8*offset);
8893 pic16_emitcode("movlw","%d",lit);
8894 pic16_emitcode("movwf","%s",buffer);
8896 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8897 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
8898 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8901 pic16_emitcode("clrf","%s",buffer);
8902 //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer));
8903 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8906 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8907 pic16_emitcode("movwf","%s",buffer);
8909 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8910 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
8911 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8918 pic16_freeAsmop(right,NULL,ic,TRUE);
8919 pic16_freeAsmop(result,NULL,ic,TRUE);
8922 /*-----------------------------------------------------------------*/
8923 /* genNearPointerSet - pic16_emitcode for near pointer put */
8924 /*-----------------------------------------------------------------*/
8925 static void genNearPointerSet (operand *right,
8932 sym_link *ptype = operandType(result);
8935 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8936 retype= getSpec(operandType(right));
8938 pic16_aopOp(result,ic,FALSE);
8941 /* if the result is rematerializable &
8942 in data space & not a bit variable */
8943 //if (AOP_TYPE(result) == AOP_IMMD &&
8944 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8945 DCL_TYPE(ptype) == POINTER &&
8946 !IS_BITVAR(retype)) {
8947 genDataPointerSet (right,result,ic);
8948 pic16_freeAsmop(result,NULL,ic,TRUE);
8952 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8953 pic16_aopOp(right,ic,FALSE);
8954 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8956 /* if the value is already in a pointer register
8957 then don't need anything more */
8958 if (!AOP_INPREG(AOP(result))) {
8959 /* otherwise get a free pointer register */
8960 //aop = newAsmop(0);
8961 //preg = getFreePtr(ic,&aop,FALSE);
8962 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8963 //pic16_emitcode("mov","%s,%s",
8965 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8966 //rname = preg->name ;
8967 //pic16_emitcode("movwf","fsr0");
8968 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8969 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8970 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8971 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8975 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8978 /* if bitfield then unpack the bits */
8979 if (IS_BITVAR(retype)) {
8980 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8981 "The programmer is obviously confused");
8982 //genPackBits (retype,right,rname,POINTER);
8986 /* we have can just get the values */
8987 int size = AOP_SIZE(right);
8990 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8992 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8995 //pic16_emitcode("mov","@%s,a",rname);
8996 pic16_emitcode("movf","indf0,w ;1");
8999 if (AOP_TYPE(right) == AOP_LIT) {
9000 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9002 pic16_emitcode("movlw","%s",l);
9003 pic16_emitcode("movwf","indf0 ;2");
9005 pic16_emitcode("clrf","indf0");
9007 pic16_emitcode("movf","%s,w",l);
9008 pic16_emitcode("movwf","indf0 ;2");
9010 //pic16_emitcode("mov","@%s,%s",rname,l);
9013 pic16_emitcode("incf","fsr0,f ;3");
9014 //pic16_emitcode("inc","%s",rname);
9019 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9020 /* now some housekeeping stuff */
9022 /* we had to allocate for this iCode */
9023 pic16_freeAsmop(NULL,aop,ic,TRUE);
9025 /* we did not allocate which means left
9026 already in a pointer register, then
9027 if size > 0 && this could be used again
9028 we have to point it back to where it
9030 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9031 if (AOP_SIZE(right) > 1 &&
9032 !OP_SYMBOL(result)->remat &&
9033 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9035 int size = AOP_SIZE(right) - 1;
9037 pic16_emitcode("decf","fsr0,f");
9038 //pic16_emitcode("dec","%s",rname);
9042 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9045 pic16_freeAsmop(right,NULL,ic,TRUE);
9046 pic16_freeAsmop(result,NULL,ic,TRUE);
9049 /*-----------------------------------------------------------------*/
9050 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9051 /*-----------------------------------------------------------------*/
9052 static void genPagedPointerSet (operand *right,
9061 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9063 retype= getSpec(operandType(right));
9065 pic16_aopOp(result,ic,FALSE);
9067 /* if the value is already in a pointer register
9068 then don't need anything more */
9069 if (!AOP_INPREG(AOP(result))) {
9070 /* otherwise get a free pointer register */
9072 preg = getFreePtr(ic,&aop,FALSE);
9073 pic16_emitcode("mov","%s,%s",
9075 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9076 rname = preg->name ;
9078 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9080 pic16_freeAsmop(result,NULL,ic,TRUE);
9081 pic16_aopOp (right,ic,FALSE);
9083 /* if bitfield then unpack the bits */
9084 if (IS_BITVAR(retype))
9085 genPackBits (retype,right,rname,PPOINTER);
9087 /* we have can just get the values */
9088 int size = AOP_SIZE(right);
9092 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9095 pic16_emitcode("movx","@%s,a",rname);
9098 pic16_emitcode("inc","%s",rname);
9104 /* now some housekeeping stuff */
9106 /* we had to allocate for this iCode */
9107 pic16_freeAsmop(NULL,aop,ic,TRUE);
9109 /* we did not allocate which means left
9110 already in a pointer register, then
9111 if size > 0 && this could be used again
9112 we have to point it back to where it
9114 if (AOP_SIZE(right) > 1 &&
9115 !OP_SYMBOL(result)->remat &&
9116 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9118 int size = AOP_SIZE(right) - 1;
9120 pic16_emitcode("dec","%s",rname);
9125 pic16_freeAsmop(right,NULL,ic,TRUE);
9130 /*-----------------------------------------------------------------*/
9131 /* genFarPointerSet - set value from far space */
9132 /*-----------------------------------------------------------------*/
9133 static void genFarPointerSet (operand *right,
9134 operand *result, iCode *ic)
9137 sym_link *retype = getSpec(operandType(right));
9139 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9140 pic16_aopOp(result,ic,FALSE);
9142 /* if the operand is already in dptr
9143 then we do nothing else we move the value to dptr */
9144 if (AOP_TYPE(result) != AOP_STR) {
9145 /* if this is remateriazable */
9146 if (AOP_TYPE(result) == AOP_IMMD)
9147 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9148 else { /* we need to get it byte by byte */
9149 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9150 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9151 if (options.model == MODEL_FLAT24)
9153 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9157 /* so dptr know contains the address */
9158 pic16_freeAsmop(result,NULL,ic,TRUE);
9159 pic16_aopOp(right,ic,FALSE);
9161 /* if bit then unpack */
9162 if (IS_BITVAR(retype))
9163 genPackBits(retype,right,"dptr",FPOINTER);
9165 size = AOP_SIZE(right);
9169 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9171 pic16_emitcode("movx","@dptr,a");
9173 pic16_emitcode("inc","dptr");
9177 pic16_freeAsmop(right,NULL,ic,TRUE);
9180 /*-----------------------------------------------------------------*/
9181 /* genGenPointerSet - set value from generic pointer space */
9182 /*-----------------------------------------------------------------*/
9183 static void genGenPointerSet (operand *right,
9184 operand *result, iCode *ic)
9187 sym_link *retype = getSpec(operandType(right));
9189 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9191 pic16_aopOp(result,ic,FALSE);
9192 pic16_aopOp(right,ic,FALSE);
9193 size = AOP_SIZE(right);
9195 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9197 /* if the operand is already in dptr
9198 then we do nothing else we move the value to dptr */
9199 if (AOP_TYPE(result) != AOP_STR) {
9200 /* if this is remateriazable */
9201 if (AOP_TYPE(result) == AOP_IMMD) {
9202 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9203 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9205 else { /* we need to get it byte by byte */
9206 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9207 size = AOP_SIZE(right);
9210 /* hack hack! see if this the FSR. If so don't load W */
9211 if(AOP_TYPE(right) != AOP_ACC) {
9213 // pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(result), pic16_popCopyReg(&pic16_pc_fsr0), 0));
9215 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9216 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9218 if(AOP_SIZE(result) > 1) {
9219 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9220 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9221 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9226 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9228 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9229 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9233 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9234 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9237 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9244 if(aopIdx(AOP(result),0) != 4) {
9246 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9250 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9255 /* so dptr know contains the address */
9258 /* if bit then unpack */
9259 if (IS_BITVAR(retype))
9260 genPackBits(retype,right,"dptr",GPOINTER);
9262 size = AOP_SIZE(right);
9265 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9269 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9270 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9272 if (AOP_TYPE(right) == AOP_LIT)
9273 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9275 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9277 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9284 pic16_freeAsmop(right,NULL,ic,TRUE);
9285 pic16_freeAsmop(result,NULL,ic,TRUE);
9288 /*-----------------------------------------------------------------*/
9289 /* genPointerSet - stores the value into a pointer location */
9290 /*-----------------------------------------------------------------*/
9291 static void genPointerSet (iCode *ic)
9293 operand *right, *result ;
9294 sym_link *type, *etype;
9297 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9299 right = IC_RIGHT(ic);
9300 result = IC_RESULT(ic) ;
9302 /* depending on the type of pointer we need to
9303 move it to the correct pointer register */
9304 type = operandType(result);
9305 etype = getSpec(type);
9306 /* if left is of type of pointer then it is simple */
9307 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9308 p_type = DCL_TYPE(type);
9311 /* we have to go by the storage class */
9312 p_type = PTR_TYPE(SPEC_OCLS(etype));
9314 /* if (SPEC_OCLS(etype)->codesp ) { */
9315 /* p_type = CPOINTER ; */
9318 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9319 /* p_type = FPOINTER ; */
9321 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9322 /* p_type = PPOINTER ; */
9324 /* if (SPEC_OCLS(etype) == idata ) */
9325 /* p_type = IPOINTER ; */
9327 /* p_type = POINTER ; */
9330 /* now that we have the pointer type we assign
9331 the pointer values */
9336 genNearPointerSet (right,result,ic);
9340 genPagedPointerSet (right,result,ic);
9344 genFarPointerSet (right,result,ic);
9348 genGenPointerSet (right,result,ic);
9352 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9353 "genPointerSet: illegal pointer type");
9357 /*-----------------------------------------------------------------*/
9358 /* genIfx - generate code for Ifx statement */
9359 /*-----------------------------------------------------------------*/
9360 static void genIfx (iCode *ic, iCode *popIc)
9362 operand *cond = IC_COND(ic);
9365 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9367 pic16_aopOp(cond,ic,FALSE);
9369 /* get the value into acc */
9370 if (AOP_TYPE(cond) != AOP_CRY)
9371 pic16_toBoolean(cond);
9374 /* the result is now in the accumulator */
9375 pic16_freeAsmop(cond,NULL,ic,TRUE);
9377 /* if there was something to be popped then do it */
9381 /* if the condition is a bit variable */
9382 if (isbit && IS_ITEMP(cond) &&
9384 genIfxJump(ic,SPIL_LOC(cond)->rname);
9385 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9388 if (isbit && !IS_ITEMP(cond))
9389 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9397 /*-----------------------------------------------------------------*/
9398 /* genAddrOf - generates code for address of */
9399 /*-----------------------------------------------------------------*/
9401 static void genAddrOf (iCode *ic)
9403 operand *right, *result, *left;
9406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9409 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9411 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9412 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9413 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9415 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9417 size = AOP_SIZE(IC_RESULT(ic));
9422 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9423 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9428 pic16_freeAsmop(left,NULL,ic,FALSE);
9429 pic16_freeAsmop(result,NULL,ic,TRUE);
9433 #else /* new genAddrOf */
9435 static void genAddrOf (iCode *ic)
9437 operand *result, *left;
9439 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9440 pCodeOp *pcop0, *pcop1, *pcop2;
9442 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9444 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9445 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9447 sym = OP_SYMBOL( left );
9449 size = AOP_SIZE(IC_RESULT(ic));
9451 if(pic16_debug_verbose) {
9452 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
9453 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
9456 /* Assume that what we want the address of is in data space
9457 * since there is no stack on the PIC, yet! -- VR */
9459 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9462 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9465 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9469 pic16_emitpcode(POC_MOVLW, pcop0);
9470 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9471 pic16_emitpcode(POC_MOVLW, pcop1);
9472 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9473 pic16_emitpcode(POC_MOVLW, pcop2);
9474 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9477 pic16_emitpcode(POC_MOVLW, pcop0);
9478 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9479 pic16_emitpcode(POC_MOVLW, pcop1);
9480 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9482 pic16_emitpcode(POC_MOVLW, pcop0);
9483 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9486 pic16_freeAsmop(result,NULL,ic,TRUE);
9487 pic16_freeAsmop(left, NULL, ic, FALSE);
9490 #endif /* new genAddrOf */
9493 /*-----------------------------------------------------------------*/
9494 /* genFarFarAssign - assignment when both are in far space */
9495 /*-----------------------------------------------------------------*/
9496 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9498 int size = AOP_SIZE(right);
9501 /* first push the right side on to the stack */
9503 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9505 pic16_emitcode ("push","acc");
9508 pic16_freeAsmop(right,NULL,ic,FALSE);
9509 /* now assign DPTR to result */
9510 pic16_aopOp(result,ic,FALSE);
9511 size = AOP_SIZE(result);
9513 pic16_emitcode ("pop","acc");
9514 pic16_aopPut(AOP(result),"a",--offset);
9516 pic16_freeAsmop(result,NULL,ic,FALSE);
9521 /*-----------------------------------------------------------------*/
9522 /* genAssign - generate code for assignment */
9523 /*-----------------------------------------------------------------*/
9524 static void genAssign (iCode *ic)
9526 operand *result, *right;
9527 int size, offset,know_W;
9528 unsigned long lit = 0L;
9530 result = IC_RESULT(ic);
9531 right = IC_RIGHT(ic) ;
9533 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9535 /* if they are the same */
9536 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9539 pic16_aopOp(right,ic,FALSE);
9540 pic16_aopOp(result,ic,TRUE);
9542 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9544 /* if they are the same registers */
9545 if (pic16_sameRegs(AOP(right),AOP(result)))
9548 /* if the result is a bit */
9549 if (AOP_TYPE(result) == AOP_CRY) {
9550 /* if the right size is a literal then
9551 we know what the value is */
9552 if (AOP_TYPE(right) == AOP_LIT) {
9554 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9555 pic16_popGet(AOP(result),0));
9557 if (((int) operandLitValue(right)))
9558 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9559 AOP(result)->aopu.aop_dir,
9560 AOP(result)->aopu.aop_dir);
9562 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9563 AOP(result)->aopu.aop_dir,
9564 AOP(result)->aopu.aop_dir);
9568 /* the right is also a bit variable */
9569 if (AOP_TYPE(right) == AOP_CRY) {
9570 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9571 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9572 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9574 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9575 AOP(result)->aopu.aop_dir,
9576 AOP(result)->aopu.aop_dir);
9577 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9578 AOP(right)->aopu.aop_dir,
9579 AOP(right)->aopu.aop_dir);
9580 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9581 AOP(result)->aopu.aop_dir,
9582 AOP(result)->aopu.aop_dir);
9587 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9588 pic16_toBoolean(right);
9590 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9591 //pic16_aopPut(AOP(result),"a",0);
9595 /* bit variables done */
9597 size = AOP_SIZE(result);
9599 if(AOP_TYPE(right) == AOP_LIT)
9600 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9602 /* VR - What is this?! */
9603 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9604 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9605 if(aopIdx(AOP(result),0) == 4) {
9606 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9607 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9608 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9611 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9616 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9617 if(AOP_TYPE(right) == AOP_LIT) {
9619 if(know_W != (lit&0xff))
9620 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9622 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9624 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9628 } else if (AOP_TYPE(right) == AOP_CRY) {
9629 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9631 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9632 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9635 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9638 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9639 normally should work, but mind that the W register live range
9640 is not checked, so if the code generator assumes that the W
9641 is already loaded after such a pair, wrong code will be generated.
9643 Checking the live range is the next step.
9644 This is experimental code yet and has not been fully tested yet.
9645 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9646 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9648 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9650 /* This is the old code, which is assumed(?!) that works fine(!?) */
9652 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9653 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9662 pic16_freeAsmop (right,NULL,ic,FALSE);
9663 pic16_freeAsmop (result,NULL,ic,TRUE);
9666 /*-----------------------------------------------------------------*/
9667 /* genJumpTab - generates code for jump table */
9668 /*-----------------------------------------------------------------*/
9669 static void genJumpTab (iCode *ic)
9674 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9676 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9677 /* get the condition into accumulator */
9678 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9680 /* multiply by three */
9681 pic16_emitcode("add","a,acc");
9682 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9684 jtab = newiTempLabel(NULL);
9685 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9686 pic16_emitcode("jmp","@a+dptr");
9687 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9689 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9690 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9692 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9693 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9694 pic16_emitpLabel(jtab->key);
9696 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9698 /* now generate the jump labels */
9699 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9700 jtab = setNextItem(IC_JTLABELS(ic))) {
9701 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9702 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9708 /*-----------------------------------------------------------------*/
9709 /* genMixedOperation - gen code for operators between mixed types */
9710 /*-----------------------------------------------------------------*/
9712 TSD - Written for the PIC port - but this unfortunately is buggy.
9713 This routine is good in that it is able to efficiently promote
9714 types to different (larger) sizes. Unfortunately, the temporary
9715 variables that are optimized out by this routine are sometimes
9716 used in other places. So until I know how to really parse the
9717 iCode tree, I'm going to not be using this routine :(.
9719 static int genMixedOperation (iCode *ic)
9722 operand *result = IC_RESULT(ic);
9723 sym_link *ctype = operandType(IC_LEFT(ic));
9724 operand *right = IC_RIGHT(ic);
9730 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9732 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9738 nextright = IC_RIGHT(nextic);
9739 nextleft = IC_LEFT(nextic);
9740 nextresult = IC_RESULT(nextic);
9742 pic16_aopOp(right,ic,FALSE);
9743 pic16_aopOp(result,ic,FALSE);
9744 pic16_aopOp(nextright, nextic, FALSE);
9745 pic16_aopOp(nextleft, nextic, FALSE);
9746 pic16_aopOp(nextresult, nextic, FALSE);
9748 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9754 pic16_emitcode(";remove right +","");
9756 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9762 pic16_emitcode(";remove left +","");
9766 big = AOP_SIZE(nextleft);
9767 small = AOP_SIZE(nextright);
9769 switch(nextic->op) {
9772 pic16_emitcode(";optimize a +","");
9773 /* if unsigned or not an integral type */
9774 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9775 pic16_emitcode(";add a bit to something","");
9778 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9780 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9781 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9782 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9784 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9792 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9793 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9794 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9797 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9799 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9800 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9801 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9802 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9803 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9806 pic16_emitcode("rlf","known_zero,w");
9813 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9814 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9815 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9817 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9827 pic16_freeAsmop(right,NULL,ic,TRUE);
9828 pic16_freeAsmop(result,NULL,ic,TRUE);
9829 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9830 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9832 nextic->generated = 1;
9839 /*-----------------------------------------------------------------*/
9840 /* genCast - gen code for casting */
9841 /*-----------------------------------------------------------------*/
9842 static void genCast (iCode *ic)
9844 operand *result = IC_RESULT(ic);
9845 sym_link *ctype = operandType(IC_LEFT(ic));
9846 sym_link *rtype = operandType(IC_RIGHT(ic));
9847 operand *right = IC_RIGHT(ic);
9850 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9851 /* if they are equivalent then do nothing */
9852 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9855 pic16_aopOp(right,ic,FALSE) ;
9856 pic16_aopOp(result,ic,FALSE);
9858 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9860 /* if the result is a bit */
9861 if (AOP_TYPE(result) == AOP_CRY) {
9863 /* if the right size is a literal then
9864 * we know what the value is */
9865 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9867 if (AOP_TYPE(right) == AOP_LIT) {
9868 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9869 pic16_popGet(AOP(result),0));
9871 if (((int) operandLitValue(right)))
9872 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9873 AOP(result)->aopu.aop_dir,
9874 AOP(result)->aopu.aop_dir);
9876 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9877 AOP(result)->aopu.aop_dir,
9878 AOP(result)->aopu.aop_dir);
9882 /* the right is also a bit variable */
9883 if (AOP_TYPE(right) == AOP_CRY) {
9885 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9887 pic16_emitcode("clrc","");
9888 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9889 AOP(right)->aopu.aop_dir,
9890 AOP(right)->aopu.aop_dir);
9891 pic16_aopPut(AOP(result),"c",0);
9896 if (AOP_TYPE(right) == AOP_REG) {
9897 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9898 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9899 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9901 pic16_toBoolean(right);
9902 pic16_aopPut(AOP(result),"a",0);
9906 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9909 size = AOP_SIZE(result);
9911 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9913 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9914 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9915 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9918 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9923 /* if they are the same size : or less */
9924 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9926 /* if they are in the same place */
9927 if (pic16_sameRegs(AOP(right),AOP(result)))
9930 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9932 if (IS_PTR_CONST(rtype))
9934 if (IS_CODEPTR(rtype))
9936 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9939 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9941 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
9943 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9946 if(AOP_TYPE(right) == AOP_IMMD) {
9947 pCodeOp *pcop0, *pcop1, *pcop2;
9948 symbol *sym = OP_SYMBOL( right );
9950 size = AOP_SIZE(result);
9952 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9954 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9956 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
9959 pic16_emitpcode(POC_MOVLW, pcop0);
9960 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
9961 pic16_emitpcode(POC_MOVLW, pcop1);
9962 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
9963 pic16_emitpcode(POC_MOVLW, pcop2);
9964 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
9967 pic16_emitpcode(POC_MOVLW, pcop0);
9968 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9969 pic16_emitpcode(POC_MOVLW, pcop1);
9970 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9972 pic16_emitpcode(POC_MOVLW, pcop0);
9973 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9977 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9978 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9979 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9980 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9981 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9982 if(AOP_SIZE(result) <2)
9983 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9985 /* if they in different places then copy */
9986 size = AOP_SIZE(result);
9989 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9990 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9997 /* if the result is of type pointer */
9998 if (IS_PTR(ctype)) {
10000 sym_link *type = operandType(right);
10001 sym_link *etype = getSpec(type);
10003 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10005 /* pointer to generic pointer */
10006 if (IS_GENPTR(ctype)) {
10010 p_type = DCL_TYPE(type);
10012 /* we have to go by the storage class */
10013 p_type = PTR_TYPE(SPEC_OCLS(etype));
10015 /* if (SPEC_OCLS(etype)->codesp ) */
10016 /* p_type = CPOINTER ; */
10018 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10019 /* p_type = FPOINTER ; */
10021 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10022 /* p_type = PPOINTER; */
10024 /* if (SPEC_OCLS(etype) == idata ) */
10025 /* p_type = IPOINTER ; */
10027 /* p_type = POINTER ; */
10030 /* the first two bytes are known */
10031 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10032 size = GPTRSIZE - 1;
10035 if(offset < AOP_SIZE(right)) {
10036 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10037 if ((AOP_TYPE(right) == AOP_PCODE) &&
10038 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10039 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10040 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10042 pic16_aopPut(AOP(result),
10043 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10047 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10050 /* the last byte depending on type */
10054 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10057 pic16_emitcode(";BUG!? ","%d",__LINE__);
10061 pic16_emitcode(";BUG!? ","%d",__LINE__);
10065 pic16_emitcode(";BUG!? ","%d",__LINE__);
10070 /* this should never happen */
10071 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10072 "got unknown pointer type");
10075 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10079 /* just copy the pointers */
10080 size = AOP_SIZE(result);
10083 pic16_aopPut(AOP(result),
10084 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10093 /* so we now know that the size of destination is greater
10094 than the size of the source.
10095 Now, if the next iCode is an operator then we might be
10096 able to optimize the operation without performing a cast.
10098 if(genMixedOperation(ic))
10101 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10103 /* we move to result for the size of source */
10104 size = AOP_SIZE(right);
10107 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10108 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10112 /* now depending on the sign of the destination */
10113 size = AOP_SIZE(result) - AOP_SIZE(right);
10114 /* if unsigned or not an integral type */
10115 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
10117 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10119 /* we need to extend the sign :( */
10122 /* Save one instruction of casting char to int */
10123 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10124 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10125 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10127 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10130 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10132 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10134 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10137 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10142 pic16_freeAsmop(right,NULL,ic,TRUE);
10143 pic16_freeAsmop(result,NULL,ic,TRUE);
10147 /*-----------------------------------------------------------------*/
10148 /* genDjnz - generate decrement & jump if not zero instrucion */
10149 /*-----------------------------------------------------------------*/
10150 static int genDjnz (iCode *ic, iCode *ifx)
10152 symbol *lbl, *lbl1;
10153 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10158 /* if the if condition has a false label
10159 then we cannot save */
10163 /* if the minus is not of the form
10165 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10166 !IS_OP_LITERAL(IC_RIGHT(ic)))
10169 if (operandLitValue(IC_RIGHT(ic)) != 1)
10172 /* if the size of this greater than one then no
10174 if (getSize(operandType(IC_RESULT(ic))) > 1)
10177 /* otherwise we can save BIG */
10178 lbl = newiTempLabel(NULL);
10179 lbl1= newiTempLabel(NULL);
10181 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10183 if (IS_AOP_PREG(IC_RESULT(ic))) {
10184 pic16_emitcode("dec","%s",
10185 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10186 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10187 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10191 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10192 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10194 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10195 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10198 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10199 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10200 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10201 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10204 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10205 ifx->generated = 1;
10209 /*-----------------------------------------------------------------*/
10210 /* genReceive - generate code for a receive iCode */
10211 /*-----------------------------------------------------------------*/
10212 static void genReceive (iCode *ic)
10214 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10216 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10217 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10218 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10220 int size = getSize(operandType(IC_RESULT(ic)));
10221 int offset = pic16_fReturnSizePic - size;
10224 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10225 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10229 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10231 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10232 size = AOP_SIZE(IC_RESULT(ic));
10235 pic16_emitcode ("pop","acc");
10236 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10239 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10242 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10244 assignResultValue(IC_RESULT(ic));
10247 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10250 /*-----------------------------------------------------------------*/
10251 /* genDummyRead - generate code for dummy read of volatiles */
10252 /*-----------------------------------------------------------------*/
10254 genDummyRead (iCode * ic)
10256 pic16_emitcode ("; genDummyRead","");
10257 pic16_emitcode ("; not implemented","");
10262 /*-----------------------------------------------------------------*/
10263 /* genpic16Code - generate code for pic16 based controllers */
10264 /*-----------------------------------------------------------------*/
10266 * At this point, ralloc.c has gone through the iCode and attempted
10267 * to optimize in a way suitable for a PIC. Now we've got to generate
10268 * PIC instructions that correspond to the iCode.
10270 * Once the instructions are generated, we'll pass through both the
10271 * peep hole optimizer and the pCode optimizer.
10272 *-----------------------------------------------------------------*/
10274 void genpic16Code (iCode *lic)
10279 lineHead = lineCurr = NULL;
10281 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10282 pic16_addpBlock(pb);
10285 /* if debug information required */
10286 if (options.debug && currFunc) {
10288 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10290 if (IS_STATIC(currFunc->etype)) {
10291 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10292 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10294 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10295 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10304 for (ic = lic ; ic ; ic = ic->next ) {
10306 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10307 // DEBUGpic16_emitcode("; VR", "");
10308 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10309 if ( cln != ic->lineno ) {
10310 if ( options.debug ) {
10312 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10313 FileBaseName(ic->filename),ic->lineno,
10314 ic->level,ic->block);
10318 if(!options.noCcodeInAsm) {
10319 pic16_addpCode2pBlock(pb,
10320 pic16_newpCodeCSource(ic->lineno, ic->filename,
10321 printCLine(ic->filename, ic->lineno)));
10327 if(options.iCodeInAsm) {
10328 /* insert here code to print iCode as comment */
10331 /* if the result is marked as
10332 spilt and rematerializable or code for
10333 this has already been generated then
10335 if (resultRemat(ic) || ic->generated )
10338 /* depending on the operation */
10357 /* IPOP happens only when trying to restore a
10358 spilt live range, if there is an ifx statement
10359 following this pop then the if statement might
10360 be using some of the registers being popped which
10361 would destroy the contents of the register so
10362 we need to check for this condition and handle it */
10364 ic->next->op == IFX &&
10365 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10366 genIfx (ic->next,ic);
10384 genEndFunction (ic);
10400 pic16_genPlus (ic) ;
10404 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10405 pic16_genMinus (ic);
10421 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10425 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10432 /* note these two are xlated by algebraic equivalence
10433 during parsing SDCC.y */
10434 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10435 "got '>=' or '<=' shouldn't have come here");
10439 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10451 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10455 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10459 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10483 genRightShift (ic);
10486 case GET_VALUE_AT_ADDRESS:
10491 if (POINTER_SET(ic))
10518 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x\tSEND",ic->op, ic->op);
10520 addSet(&_G.sendSet,ic);
10523 case DUMMY_READ_VOLATILE:
10533 /* now we are ready to call the
10534 peep hole optimizer */
10535 if (!options.nopeep) {
10536 peepHole (&lineHead);
10538 /* now do the actual printing */
10539 printLine (lineHead,codeOutFile);
10542 DFPRINTF((stderr,"printing pBlock\n\n"));
10543 pic16_printpBlock(stdout,pb);