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 void pic16_genMult16X16_16(operand *, operand *, operand *);
53 void pic16_genMult32X32_32(operand *, operand *, operand *);
54 pCode *pic16_AssembleLine(char *line, int peeps);
55 extern void pic16_printpBlock(FILE *of, pBlock *pb);
56 static asmop *newAsmop (short type);
57 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
58 extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
59 static void mov2w (asmop *aop, int offset);
60 static int aopIdx (asmop *aop, int offset);
62 static int labelOffset=0;
63 extern int pic16_debug_verbose;
64 static int optimized_for_speed = 0;
70 /* max_key keeps track of the largest label number used in
71 a function. This is then used to adjust the label offset
72 for the next function.
75 static int GpsuedoStkPtr=0;
77 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
78 unsigned int pic16aopLiteral (value *val, int offset);
79 const char *pic16_AopType(short type);
80 static iCode *ifxForOp ( operand *op, iCode *ic );
82 void pic16_pushpCodeOp(pCodeOp *pcop);
83 void pic16_poppCodeOp(pCodeOp *pcop);
87 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
89 /* this is the down and dirty file with all kinds of
90 kludgy & hacky stuff. This is what it is all about
91 CODE GENERATION for a specific MCU . some of the
92 routines may be reusable, will have to see */
94 static char *zero = "#0x00";
95 static char *one = "#0x01";
96 static char *spname = "sp";
100 * Function return value policy (MSB-->LSB):
102 * 16 bits -> PRODL:WREG
103 * 24 bits -> PRODH:PRODL:WREG
104 * 32 bits -> FSR0L:PRODH:PRODL:WREG
105 * >32 bits -> on stack, and FSR0 points to the beginning
110 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
111 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
112 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
113 static char **fReturn = fReturnpic16;
115 static char *accUse[] = {"WREG"};
117 //static short rbank = -1;
130 /* Resolved ifx structure. This structure stores information
131 about an iCode ifx that makes it easier to generate code.
133 typedef struct resolvedIfx {
134 symbol *lbl; /* pointer to a label */
135 int condition; /* true or false ifx */
136 int generated; /* set true when the code associated with the ifx
140 extern int pic16_ptrRegReq ;
141 extern int pic16_nRegs;
142 extern FILE *codeOutFile;
143 static void saverbank (int, iCode *,bool);
145 static lineNode *lineHead = NULL;
146 static lineNode *lineCurr = NULL;
148 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
149 0xE0, 0xC0, 0x80, 0x00};
150 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
151 0x07, 0x03, 0x01, 0x00};
155 /*-----------------------------------------------------------------*/
156 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
157 /* exponent of 2 is returned, otherwise -1 is */
159 /* note that this is similar to the function `powof2' in SDCCsymt */
163 /*-----------------------------------------------------------------*/
164 static int my_powof2 (unsigned long num)
167 if( (num & (num-1)) == 0) {
180 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
182 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
184 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
185 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
186 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
187 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
188 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
189 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
190 ((result) ? AOP_SIZE(result) : 0));
193 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
196 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
198 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
199 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
200 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
201 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
202 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
203 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
207 void pic16_emitpcomment (char *fmt, ...)
210 char lb[INITIAL_INLINEASM];
216 vsprintf(lb+1,fmt,ap);
218 while (isspace(*lbp)) lbp++;
221 lineCurr = (lineCurr ?
222 connectLine(lineCurr,newLineNode(lb)) :
223 (lineHead = newLineNode(lb)));
224 lineCurr->isInline = _G.inLine;
225 lineCurr->isDebug = _G.debugLine;
227 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
230 // fprintf(stderr, "%s\n", lb);
233 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
236 char lb[INITIAL_INLINEASM];
239 if(!pic16_debug_verbose)
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
262 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
265 // fprintf(stderr, "%s\n", lb);
268 void pic16_emitpLabel(int key)
270 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
273 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
277 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
279 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
281 // fprintf(stderr, "%s\n", pcop->name);
284 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
287 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
293 #define pic16_emitcode DEBUGpic16_emitcode
295 /*-----------------------------------------------------------------*/
296 /* pic16_emitcode - writes the code into a file : for now it is simple */
297 /*-----------------------------------------------------------------*/
298 void pic16_emitcode (char *inst,char *fmt, ...)
301 char lb[INITIAL_INLINEASM];
308 sprintf(lb,"%s\t",inst);
310 sprintf(lb,"%s",inst);
311 vsprintf(lb+(strlen(lb)),fmt,ap);
315 while (isspace(*lbp)) lbp++;
318 lineCurr = (lineCurr ?
319 connectLine(lineCurr,newLineNode(lb)) :
320 (lineHead = newLineNode(lb)));
321 lineCurr->isInline = _G.inLine;
322 lineCurr->isDebug = _G.debugLine;
324 // VR fprintf(stderr, "lb = <%s>\n", lbp);
326 // if(pic16_debug_verbose)
327 // pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
334 /*-----------------------------------------------------------------*/
335 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
336 /*-----------------------------------------------------------------*/
337 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
339 bool r0iu = FALSE , r1iu = FALSE;
340 bool r0ou = FALSE , r1ou = FALSE;
342 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
344 /* the logic: if r0 & r1 used in the instruction
345 then we are in trouble otherwise */
347 /* first check if r0 & r1 are used by this
348 instruction, in which case we are in trouble */
349 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
350 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
355 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
356 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
358 /* if no usage of r0 then return it */
359 if (!r0iu && !r0ou) {
360 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
361 (*aopp)->type = AOP_R0;
363 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
366 /* if no usage of r1 then return it */
367 if (!r1iu && !r1ou) {
368 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
369 (*aopp)->type = AOP_R1;
371 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
374 /* now we know they both have usage */
375 /* if r0 not used in this instruction */
377 /* push it if not already pushed */
379 //pic16_emitcode ("push","%s",
380 // pic16_regWithIdx(R0_IDX)->dname);
384 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
385 (*aopp)->type = AOP_R0;
387 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
390 /* if r1 not used then */
393 /* push it if not already pushed */
395 //pic16_emitcode ("push","%s",
396 // pic16_regWithIdx(R1_IDX)->dname);
400 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
401 (*aopp)->type = AOP_R1;
402 return pic16_regWithIdx(R1_IDX);
406 /* I said end of world but not quite end of world yet */
407 /* if this is a result then we can push it on the stack*/
409 (*aopp)->type = AOP_STK;
413 /* other wise this is true end of the world */
414 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
415 "getFreePtr should never reach here");
419 /*-----------------------------------------------------------------*/
420 /* newAsmop - creates a new asmOp */
421 /*-----------------------------------------------------------------*/
422 static asmop *newAsmop (short type)
426 aop = Safe_calloc(1,sizeof(asmop));
431 static void genSetDPTR(int n)
435 pic16_emitcode(";", "Select standard DPTR");
436 pic16_emitcode("mov", "dps, #0x00");
440 pic16_emitcode(";", "Select alternate DPTR");
441 pic16_emitcode("mov", "dps, #0x01");
445 /*-----------------------------------------------------------------*/
446 /* resolveIfx - converts an iCode ifx into a form more useful for */
447 /* generating code */
448 /*-----------------------------------------------------------------*/
449 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
452 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
458 resIfx->condition = 1; /* assume that the ifx is true */
459 resIfx->generated = 0; /* indicate that the ifx has not been used */
462 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
465 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
466 __FUNCTION__,__LINE__,resIfx->lbl->key);
471 resIfx->lbl = IC_TRUE(ifx);
473 resIfx->lbl = IC_FALSE(ifx);
474 resIfx->condition = 0;
478 DEBUGpic16_emitcode("; ***","ifx true is non-null");
480 DEBUGpic16_emitcode("; ***","ifx false is non-null");
484 DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
488 /*-----------------------------------------------------------------*/
489 /* pointerCode - returns the code for a pointer type */
490 /*-----------------------------------------------------------------*/
491 static int pointerCode (sym_link *etype)
494 return PTR_TYPE(SPEC_OCLS(etype));
498 /*-----------------------------------------------------------------*/
499 /* aopForSym - for a true symbol */
500 /*-----------------------------------------------------------------*/
501 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
504 memmap *space= SPEC_OCLS(sym->etype);
506 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
507 /* if already has one */
509 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
513 /* if symbol was initially placed onStack then we must re-place it
514 * to direct memory, since pic16 does not have a specific stack */
517 SPEC_OCLS( sym->etype ) = data;
523 /* assign depending on the storage class */
524 /* if it is on the stack or indirectly addressable */
525 /* space we need to assign either r0 or r1 to it */
526 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
528 DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
529 __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
531 sym->aop = aop = newAsmop(0);
532 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
533 aop->size = getSize(sym->type);
535 /* now assign the address of the variable to
536 the pointer register */
537 if (aop->type != AOP_STK) {
541 pic16_emitcode("push","acc");
543 pic16_emitcode("mov","a,_bp");
544 pic16_emitcode("add","a,#0x%02x",
546 ((char)(sym->stack - _G.nRegsSaved )) :
547 ((char)sym->stack)) & 0xff);
548 pic16_emitcode("mov","%s,a",
549 aop->aopu.aop_ptr->name);
552 pic16_emitcode("pop","acc");
554 pic16_emitcode("mov","%s,#%s",
555 aop->aopu.aop_ptr->name,
557 aop->paged = space->paged;
559 aop->aopu.aop_stk = sym->stack;
564 if (sym->onStack && options.stack10bit)
566 /* It's on the 10 bit stack, which is located in
570 //DEBUGpic16_emitcode(";","%d",__LINE__);
573 pic16_emitcode("push","acc");
575 pic16_emitcode("mov","a,_bp");
576 pic16_emitcode("add","a,#0x%02x",
578 ((char)(sym->stack - _G.nRegsSaved )) :
579 ((char)sym->stack)) & 0xff);
582 pic16_emitcode ("mov","dpx1,#0x40");
583 pic16_emitcode ("mov","dph1,#0x00");
584 pic16_emitcode ("mov","dpl1, a");
588 pic16_emitcode("pop","acc");
590 sym->aop = aop = newAsmop(AOP_DPTR2);
591 aop->size = getSize(sym->type);
595 //DEBUGpic16_emitcode(";","%d",__LINE__);
596 /* if in bit space */
597 if (IN_BITSPACE(space)) {
598 sym->aop = aop = newAsmop (AOP_CRY);
599 aop->aopu.aop_dir = sym->rname ;
600 aop->size = getSize(sym->type);
601 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
604 /* if it is in direct space */
605 if (IN_DIRSPACE(space)) {
606 sym->aop = aop = newAsmop (AOP_DIR);
607 aop->aopu.aop_dir = sym->rname ;
608 aop->size = getSize(sym->type);
609 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
610 pic16_allocDirReg( IC_LEFT(ic) );
615 /* special case for a function */
616 if (IS_FUNC(sym->type)) {
617 sym->aop = aop = newAsmop(AOP_IMMD);
618 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
619 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
620 strcpy(aop->aopu.aop_immd,sym->rname);
621 aop->size = FPTRSIZE;
622 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
628 /* only remaining is far space */
629 /* in which case DPTR gets the address */
630 sym->aop = aop = newAsmop(AOP_PCODE);
632 /* change the next if to 1 to revert to good old immediate code */
633 if(IN_CODESPACE(space)) {
634 aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
635 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
636 PCOI(aop->aopu.pcop)->index = 0;
638 /* try to allocate via direct register */
639 aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset); // Patch 8
640 // aop->size = getSize( sym->type );
643 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
644 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
647 if(!pic16_allocDirReg (IC_LEFT(ic)))
651 if(IN_DIRSPACE( space ))
653 else if(IN_CODESPACE( space ))
654 aop->size = FPTRSIZE;
655 else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) );
656 else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) );
661 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
663 /* if it is in code space */
664 if (IN_CODESPACE(space))
670 /*-----------------------------------------------------------------*/
671 /* aopForRemat - rematerialzes an object */
672 /*-----------------------------------------------------------------*/
673 static asmop *aopForRemat (operand *op) // x symbol *sym)
675 symbol *sym = OP_SYMBOL(op);
676 iCode *ic = NULL, *oldic;
677 asmop *aop = newAsmop(AOP_PCODE);
683 ic = sym->rematiCode;
685 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
687 if(IS_OP_POINTER(op)) {
688 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
694 // pic16_emitpcomment("ic: %s\n", printILine(ic));
697 val += (int) operandLitValue(IC_RIGHT(ic));
698 } else if (ic->op == '-') {
699 val -= (int) operandLitValue(IC_RIGHT(ic));
703 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
706 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
708 if(!op->isaddr)viaimmd++; else viaimmd=0;
710 /* set the following if to 1 to revert to good old immediate code */
711 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))
714 pic16_emitpcomment("%s:%d immediate", __FILE__, __LINE__);
716 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val);
719 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
721 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
724 PCOI(aop->aopu.pcop)->index = val;
726 pic16_emitpcomment("%s:%d dir", __FILE__, __LINE__);
728 aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, getSize( OP_SYMBOL( IC_LEFT(ic))->type), val);
729 // aop->size = AOP_SIZE( IC_LEFT(ic) );
733 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
734 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
736 val, IS_PTR_CONST(operandType(op)));
738 val, IS_CODEPTR(operandType(op)));
741 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
743 pic16_allocDirReg (IC_LEFT(ic));
745 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) ))
751 static int aopIdx (asmop *aop, int offset)
756 if(aop->type != AOP_REG)
759 return aop->aopu.aop_reg[offset]->rIdx;
762 /*-----------------------------------------------------------------*/
763 /* regsInCommon - two operands have some registers in common */
764 /*-----------------------------------------------------------------*/
765 static bool regsInCommon (operand *op1, operand *op2)
770 /* if they have registers in common */
771 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
774 sym1 = OP_SYMBOL(op1);
775 sym2 = OP_SYMBOL(op2);
777 if (sym1->nRegs == 0 || sym2->nRegs == 0)
780 for (i = 0 ; i < sym1->nRegs ; i++) {
785 for (j = 0 ; j < sym2->nRegs ;j++ ) {
789 if (sym2->regs[j] == sym1->regs[i])
797 /*-----------------------------------------------------------------*/
798 /* operandsEqu - equivalent */
799 /*-----------------------------------------------------------------*/
800 static bool operandsEqu ( operand *op1, operand *op2)
804 /* if they not symbols */
805 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
808 sym1 = OP_SYMBOL(op1);
809 sym2 = OP_SYMBOL(op2);
811 /* if both are itemps & one is spilt
812 and the other is not then false */
813 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
814 sym1->isspilt != sym2->isspilt )
817 /* if they are the same */
821 if (strcmp(sym1->rname,sym2->rname) == 0)
825 /* if left is a tmp & right is not */
829 (sym1->usl.spillLoc == sym2))
836 (sym2->usl.spillLoc == sym1))
842 /*-----------------------------------------------------------------*/
843 /* pic16_sameRegs - two asmops have the same registers */
844 /*-----------------------------------------------------------------*/
845 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
852 if (aop1->type != AOP_REG ||
853 aop2->type != AOP_REG )
856 if (aop1->size != aop2->size )
859 for (i = 0 ; i < aop1->size ; i++ )
860 if (aop1->aopu.aop_reg[i] !=
861 aop2->aopu.aop_reg[i] )
867 /*-----------------------------------------------------------------*/
868 /* pic16_aopOp - allocates an asmop for an operand : */
869 /*-----------------------------------------------------------------*/
870 void pic16_aopOp (operand *op, iCode *ic, bool result)
879 // DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__);
881 /* if this a literal */
882 if (IS_OP_LITERAL(op)) {
883 op->aop = aop = newAsmop(AOP_LIT);
884 aop->aopu.aop_lit = op->operand.valOperand;
885 aop->size = getSize(operandType(op));
890 sym_link *type = operandType(op);
892 if(IS_PTR_CONST(type))
896 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
899 /* if already has a asmop then continue */
903 /* if the underlying symbol has a aop */
904 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
905 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
906 op->aop = OP_SYMBOL(op)->aop;
910 /* if this is a true symbol */
911 if (IS_TRUE_SYMOP(op)) {
912 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
913 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
917 /* this is a temporary : this has
923 e) can be a return use only */
927 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
928 /* if the type is a conditional */
929 if (sym->regType == REG_CND) {
930 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
935 /* if it is spilt then two situations
937 b) has a spill location */
938 if (sym->isspilt || sym->nRegs == 0) {
940 DEBUGpic16_emitcode(";","%d",__LINE__);
941 /* rematerialize it NOW */
944 sym->aop = op->aop = aop =
946 aop->size = getSize(sym->type);
947 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
954 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
955 aop->size = getSize(sym->type);
956 for ( i = 0 ; i < 1 ; i++ ) {
957 aop->aopu.aop_str[i] = accUse[i];
958 // aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset);
960 fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name);
961 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
969 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
970 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
971 //pic16_allocDirReg (IC_LEFT(ic));
972 aop->size = getSize(sym->type);
977 aop = op->aop = sym->aop = newAsmop(AOP_STR);
978 aop->size = getSize(sym->type);
979 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
980 aop->aopu.aop_str[i] = fReturn[i];
982 DEBUGpic16_emitcode(";","%d",__LINE__);
986 /* else spill location */
987 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
988 /* force a new aop if sizes differ */
989 sym->usl.spillLoc->aop = NULL;
991 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
992 __FUNCTION__,__LINE__,
993 sym->usl.spillLoc->rname,
994 sym->rname, sym->usl.spillLoc->offset);
996 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
997 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
998 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
1000 sym->usl.spillLoc->offset);
1001 aop->size = getSize(sym->type);
1007 sym_link *type = operandType(op);
1009 if(IS_PTR_CONST(type))
1011 if(IS_CODEPTR(type))
1013 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
1016 /* must be in a register */
1017 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
1018 sym->aop = op->aop = aop = newAsmop(AOP_REG);
1019 aop->size = sym->nRegs;
1020 for ( i = 0 ; i < sym->nRegs ;i++)
1021 aop->aopu.aop_reg[i] = sym->regs[i];
1024 /*-----------------------------------------------------------------*/
1025 /* pic16_freeAsmop - free up the asmop given to an operand */
1026 /*----------------------------------------------------------------*/
1027 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
1044 /* depending on the asmop type only three cases need work AOP_RO
1045 , AOP_R1 && AOP_STK */
1047 switch (aop->type) {
1051 pic16_emitcode ("pop","ar0");
1055 bitVectUnSetBit(ic->rUsed,R0_IDX);
1061 pic16_emitcode ("pop","ar1");
1065 bitVectUnSetBit(ic->rUsed,R1_IDX);
1071 int stk = aop->aopu.aop_stk + aop->size;
1072 bitVectUnSetBit(ic->rUsed,R0_IDX);
1073 bitVectUnSetBit(ic->rUsed,R1_IDX);
1075 getFreePtr(ic,&aop,FALSE);
1077 if (options.stack10bit)
1079 /* I'm not sure what to do here yet... */
1082 "*** Warning: probably generating bad code for "
1083 "10 bit stack mode.\n");
1087 pic16_emitcode ("mov","a,_bp");
1088 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
1089 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
1091 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
1095 pic16_emitcode("pop","acc");
1096 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
1098 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1101 pic16_freeAsmop(op,NULL,ic,TRUE);
1103 pic16_emitcode("pop","ar0");
1108 pic16_emitcode("pop","ar1");
1116 /* all other cases just dealloc */
1120 OP_SYMBOL(op)->aop = NULL;
1121 /* if the symbol has a spill */
1123 SPIL_LOC(op)->aop = NULL;
1128 /*-----------------------------------------------------------------*/
1129 /* pic16_aopGet - for fetching value of the aop */
1130 /*-----------------------------------------------------------------*/
1131 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1136 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1138 /* offset is greater than size then zero */
1139 if (offset > (aop->size - 1) &&
1140 aop->type != AOP_LIT)
1143 /* depending on type */
1144 switch (aop->type) {
1148 DEBUGpic16_emitcode(";","%d",__LINE__);
1149 /* if we need to increment it */
1150 while (offset > aop->coff) {
1151 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1155 while (offset < aop->coff) {
1156 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1160 aop->coff = offset ;
1162 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1163 return (dname ? "acc" : "a");
1165 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1166 rs = Safe_calloc(1,strlen(s)+1);
1172 DEBUGpic16_emitcode(";","%d",__LINE__);
1173 if (aop->type == AOP_DPTR2)
1178 while (offset > aop->coff) {
1179 pic16_emitcode ("inc","dptr");
1183 while (offset < aop->coff) {
1184 pic16_emitcode("lcall","__decdptr");
1190 pic16_emitcode("clr","a");
1191 pic16_emitcode("movc","a,@a+dptr");
1194 pic16_emitcode("movx","a,@dptr");
1197 if (aop->type == AOP_DPTR2)
1202 return (dname ? "acc" : "a");
1207 sprintf (s,"%s",aop->aopu.aop_immd);
1210 sprintf(s,"(%s >> %d)",
1215 aop->aopu.aop_immd);
1216 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1217 rs = Safe_calloc(1,strlen(s)+1);
1223 sprintf(s,"(%s + %d)",
1226 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1228 sprintf(s,"%s",aop->aopu.aop_dir);
1229 rs = Safe_calloc(1,strlen(s)+1);
1235 // return aop->aopu.aop_reg[offset]->dname;
1237 return aop->aopu.aop_reg[offset]->name;
1240 //pic16_emitcode(";","%d",__LINE__);
1241 return aop->aopu.aop_dir;
1244 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1245 // fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__);
1247 return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug";
1250 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1251 rs = Safe_calloc(1,strlen(s)+1);
1256 aop->coff = offset ;
1257 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1260 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1262 return aop->aopu.aop_str[offset];
1266 pCodeOp *pcop = aop->aopu.pcop;
1267 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1269 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1270 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1271 sprintf(s,"%s", pcop->name);
1273 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1276 rs = Safe_calloc(1,strlen(s)+1);
1282 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1283 "aopget got unsupported aop->type");
1288 /*-----------------------------------------------------------------*/
1289 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1290 /*-----------------------------------------------------------------*/
1291 pCodeOp *pic16_popGetTempReg(void)
1296 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1301 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1302 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1303 PCOR(pcop)->r->wasUsed=1;
1304 PCOR(pcop)->r->isFree=0;
1306 /* push value on stack */
1307 pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
1315 /*-----------------------------------------------------------------*/
1316 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1317 /*-----------------------------------------------------------------*/
1318 void pic16_popReleaseTempReg(pCodeOp *pcop)
1320 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1322 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1323 PCOR(pcop)->r->isFree = 1;
1325 pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
1328 /*-----------------------------------------------------------------*/
1329 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1330 /*-----------------------------------------------------------------*/
1331 pCodeOp *pic16_popGetLabel(unsigned int key)
1334 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1339 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1342 /*-----------------------------------------------------------------*/
1343 /* pic16_popCopyReg - copy a pcode operator */
1344 /*-----------------------------------------------------------------*/
1345 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1349 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1350 pcor->pcop.type = pc->pcop.type;
1352 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1353 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1355 pcor->pcop.name = NULL;
1358 pcor->rIdx = pc->rIdx;
1361 // DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1366 /*-----------------------------------------------------------------*/
1367 /* pic16_popGetLit - asm operator to pcode operator conversion */
1368 /*-----------------------------------------------------------------*/
1369 pCodeOp *pic16_popGetLit(unsigned int lit)
1371 return pic16_newpCodeOpLit(lit);
1374 /*-----------------------------------------------------------------*/
1375 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1376 /*-----------------------------------------------------------------*/
1377 pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
1379 return pic16_newpCodeOpLit2(lit, arg2);
1383 /*-----------------------------------------------------------------*/
1384 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1385 /*-----------------------------------------------------------------*/
1386 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1388 return pic16_newpCodeOpImmd(name, offset,index, 0);
1392 /*-----------------------------------------------------------------*/
1393 /* pic16_popGet - asm operator to pcode operator conversion */
1394 /*-----------------------------------------------------------------*/
1395 pCodeOp *pic16_popGetWithString(char *str)
1401 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1405 pcop = pic16_newpCodeOp(str,PO_STR);
1410 /*-----------------------------------------------------------------*/
1411 /* pic16_popRegFromString - */
1412 /*-----------------------------------------------------------------*/
1413 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1416 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1417 pcop->type = PO_DIR;
1419 DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14
1420 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1425 pcop->name = Safe_calloc(1,strlen(str)+1);
1426 strcpy(pcop->name,str);
1428 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1430 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1431 if(PCOR(pcop)->r == NULL) {
1432 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1433 // __FUNCTION__, __LINE__, str, size, offset);
1434 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1436 //fprintf(stderr, "allocating new register -> %s\n", str);
1438 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset);
1440 // DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset);
1442 PCOR(pcop)->instance = offset;
1447 static pCodeOp *pic16_popRegFromIdx(int rIdx)
1451 // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
1453 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1454 PCOR(pcop)->rIdx = rIdx;
1455 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1456 PCOR(pcop)->r->isFree = 0;
1457 PCOR(pcop)->r->wasUsed = 1;
1459 pcop->type = PCOR(pcop)->r->pc_type;
1464 /*---------------------------------------------------------------------------------*/
1465 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1467 /*---------------------------------------------------------------------------------*/
1468 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1473 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1475 /* comment the following check, so errors to throw up */
1476 // if(!pcop2)return NULL;
1478 temp = pic16_popGet(aop_dst, offset);
1479 pcop2->pcop2 = temp;
1486 /*--------------------------------------------------------------------------------.-*/
1487 /* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */
1488 /* VR 030601 , adapted by Hans Dorn */
1489 /*--------------------------------------------------------------------------------.-*/
1490 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
1494 pcop2 = (pCodeOpReg2 *)src;
1502 /*---------------------------------------------------------------------------------*/
1503 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */
1504 /* movff instruction */
1505 /*---------------------------------------------------------------------------------*/
1506 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
1511 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1512 pcop2->pcop2 = pic16_popCopyReg(dst);
1514 /* the pCodeOp may be already allocated */
1515 pcop2 = (pCodeOpReg2 *)(src);
1516 pcop2->pcop2 = (pCodeOp *)(dst);
1523 /*-----------------------------------------------------------------*/
1524 /* pic16_popGet - asm operator to pcode operator conversion */
1525 /*-----------------------------------------------------------------*/
1526 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1528 //char *s = buffer ;
1532 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1533 /* offset is greater than
1536 // if (offset > (aop->size - 1) &&
1537 // aop->type != AOP_LIT)
1538 // return NULL; //zero;
1540 /* depending on type */
1541 switch (aop->type) {
1547 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1548 fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
1555 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1556 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1560 int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx;
1562 fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]);
1564 DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__);
1566 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1567 PCOR(pcop)->rIdx = rIdx;
1568 PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx);
1569 PCOR(pcop)->r->wasUsed=1;
1570 PCOR(pcop)->r->isFree=0;
1572 PCOR(pcop)->instance = offset;
1573 pcop->type = PCOR(pcop)->r->pc_type;
1574 // rs = aop->aopu.aop_reg[offset]->name;
1575 // DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs);
1579 // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset);
1580 // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1586 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1587 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1591 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1593 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1595 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1596 PCOR(pcop)->rIdx = rIdx;
1597 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1598 PCOR(pcop)->r->wasUsed=1;
1599 PCOR(pcop)->r->isFree=0;
1601 PCOR(pcop)->instance = offset;
1602 pcop->type = PCOR(pcop)->r->pc_type;
1603 rs = aop->aopu.aop_reg[offset]->name;
1604 DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1609 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1611 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1612 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1613 //if(PCOR(pcop)->r == NULL)
1614 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1618 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1619 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1622 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1623 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1626 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1627 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1628 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1629 pcop->type = PCOR(pcop)->r->pc_type;
1630 pcop->name = PCOR(pcop)->r->name;
1636 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop),
1638 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset);
1639 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1641 switch( aop->aopu.pcop->type ) {
1642 case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8
1643 case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break;
1645 assert( 0 ); /* should never reach here */;
1648 PCOI(pcop)->offset = offset;
1653 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1654 "pic16_popGet got unsupported aop->type");
1657 /*-----------------------------------------------------------------*/
1658 /* pic16_aopPut - puts a string for a aop */
1659 /*-----------------------------------------------------------------*/
1660 void pic16_aopPut (asmop *aop, char *s, int offset)
1665 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1667 if (aop->size && offset > ( aop->size - 1)) {
1668 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1669 "pic16_aopPut got offset > aop->size");
1673 /* will assign value to value */
1674 /* depending on where it is ofcourse */
1675 switch (aop->type) {
1678 sprintf(d,"(%s + %d)",
1679 aop->aopu.aop_dir,offset);
1680 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1683 sprintf(d,"%s",aop->aopu.aop_dir);
1686 DEBUGpic16_emitcode(";","%d",__LINE__);
1688 pic16_emitcode("movf","%s,w",s);
1689 pic16_emitcode("movwf","%s",d);
1692 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1693 if(offset >= aop->size) {
1694 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1697 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1700 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1707 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1708 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1711 strcmp(s,"r0") == 0 ||
1712 strcmp(s,"r1") == 0 ||
1713 strcmp(s,"r2") == 0 ||
1714 strcmp(s,"r3") == 0 ||
1715 strcmp(s,"r4") == 0 ||
1716 strcmp(s,"r5") == 0 ||
1717 strcmp(s,"r6") == 0 ||
1718 strcmp(s,"r7") == 0 )
1719 pic16_emitcode("mov","%s,%s ; %d",
1720 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1724 if(strcmp(s,"W")==0 )
1725 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1727 pic16_emitcode("movwf","%s",
1728 aop->aopu.aop_reg[offset]->name);
1730 if(strcmp(s,zero)==0) {
1731 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1733 } else if(strcmp(s,"W")==0) {
1734 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1735 pcop->type = PO_GPR_REGISTER;
1737 PCOR(pcop)->rIdx = -1;
1738 PCOR(pcop)->r = NULL;
1740 DEBUGpic16_emitcode(";","%d",__LINE__);
1741 pcop->name = Safe_strdup(s);
1742 pic16_emitpcode(POC_MOVFW,pcop);
1743 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1744 } else if(strcmp(s,one)==0) {
1745 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1746 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1748 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1756 if (aop->type == AOP_DPTR2)
1762 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1763 "pic16_aopPut writting to code space");
1767 while (offset > aop->coff) {
1769 pic16_emitcode ("inc","dptr");
1772 while (offset < aop->coff) {
1774 pic16_emitcode("lcall","__decdptr");
1779 /* if not in accumulater */
1782 pic16_emitcode ("movx","@dptr,a");
1784 if (aop->type == AOP_DPTR2)
1792 while (offset > aop->coff) {
1794 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1796 while (offset < aop->coff) {
1798 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1804 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1809 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1811 if (strcmp(s,"r0") == 0 ||
1812 strcmp(s,"r1") == 0 ||
1813 strcmp(s,"r2") == 0 ||
1814 strcmp(s,"r3") == 0 ||
1815 strcmp(s,"r4") == 0 ||
1816 strcmp(s,"r5") == 0 ||
1817 strcmp(s,"r6") == 0 ||
1818 strcmp(s,"r7") == 0 ) {
1820 sprintf(buffer,"a%s",s);
1821 pic16_emitcode("mov","@%s,%s",
1822 aop->aopu.aop_ptr->name,buffer);
1824 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1829 if (strcmp(s,"a") == 0)
1830 pic16_emitcode("push","acc");
1832 pic16_emitcode("push","%s",s);
1837 /* if bit variable */
1838 if (!aop->aopu.aop_dir) {
1839 pic16_emitcode("clr","a");
1840 pic16_emitcode("rlc","a");
1843 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1846 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1849 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1851 lbl = newiTempLabel(NULL);
1853 if (strcmp(s,"a")) {
1856 pic16_emitcode("clr","c");
1857 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1858 pic16_emitcode("cpl","c");
1859 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1860 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1867 if (strcmp(aop->aopu.aop_str[offset],s))
1868 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1873 if (!offset && (strcmp(s,"acc") == 0))
1876 if (strcmp(aop->aopu.aop_str[offset],s))
1877 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1881 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1882 "pic16_aopPut got unsupported aop->type");
1888 /*-----------------------------------------------------------------*/
1889 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1890 /*-----------------------------------------------------------------*/
1891 static void mov2w (asmop *aop, int offset)
1897 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1899 if ( aop->type == AOP_PCODE ||
1900 aop->type == AOP_LIT )
1901 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1903 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1908 /* push pcop into stack */
1909 void pic16_pushpCodeOp(pCodeOp *pcop)
1911 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1912 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
1915 /* pop pcop from stack */
1916 void pic16_poppCodeOp(pCodeOp *pcop)
1918 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop));
1922 /*-----------------------------------------------------------------*/
1923 /* pushw - pushes wreg to stack */
1924 /*-----------------------------------------------------------------*/
1927 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1928 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1932 /*-----------------------------------------------------------------*/
1933 /* pushaop - pushes aop to stack */
1934 /*-----------------------------------------------------------------*/
1935 void pushaop(asmop *aop, int offset)
1937 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1938 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
1941 /*-----------------------------------------------------------------*/
1942 /* popaop - pops aop from stack */
1943 /*-----------------------------------------------------------------*/
1944 void popaop(asmop *aop, int offset)
1946 DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__);
1947 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
1950 void popaopidx(asmop *aop, int offset, int index)
1954 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1956 if(STACK_MODEL_LARGE)ofs++;
1958 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1959 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
1962 /*-----------------------------------------------------------------*/
1963 /* reAdjustPreg - points a register back to where it should */
1964 /*-----------------------------------------------------------------*/
1965 static void reAdjustPreg (asmop *aop)
1969 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1971 if ((size = aop->size) <= 1)
1974 switch (aop->type) {
1978 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1982 if (aop->type == AOP_DPTR2)
1988 pic16_emitcode("lcall","__decdptr");
1991 if (aop->type == AOP_DPTR2)
2003 /*-----------------------------------------------------------------*/
2004 /* opIsGptr: returns non-zero if the passed operand is */
2005 /* a generic pointer type. */
2006 /*-----------------------------------------------------------------*/
2007 static int opIsGptr(operand *op)
2009 sym_link *type = operandType(op);
2011 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2012 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
2020 /*-----------------------------------------------------------------*/
2021 /* pic16_getDataSize - get the operand data size */
2022 /*-----------------------------------------------------------------*/
2023 int pic16_getDataSize(operand *op)
2025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2028 return AOP_SIZE(op);
2030 // tsd- in the pic port, the genptr size is 1, so this code here
2031 // fails. ( in the 8051 port, the size was 4).
2034 size = AOP_SIZE(op);
2035 if (size == GPTRSIZE)
2037 sym_link *type = operandType(op);
2038 if (IS_GENPTR(type))
2040 /* generic pointer; arithmetic operations
2041 * should ignore the high byte (pointer type).
2044 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2051 /*-----------------------------------------------------------------*/
2052 /* pic16_outAcc - output Acc */
2053 /*-----------------------------------------------------------------*/
2054 void pic16_outAcc(operand *result)
2057 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
2058 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
2061 size = pic16_getDataSize(result);
2063 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
2066 /* unsigned or positive */
2068 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
2073 /*-----------------------------------------------------------------*/
2074 /* pic16_outBitC - output a bit C */
2075 /*-----------------------------------------------------------------*/
2076 void pic16_outBitC(operand *result)
2079 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2080 /* if the result is bit */
2081 if (AOP_TYPE(result) == AOP_CRY)
2082 pic16_aopPut(AOP(result),"c",0);
2084 pic16_emitcode("clr","a ; %d", __LINE__);
2085 pic16_emitcode("rlc","a");
2086 pic16_outAcc(result);
2090 /*-----------------------------------------------------------------*/
2091 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
2092 /*-----------------------------------------------------------------*/
2093 void pic16_toBoolean(operand *oper)
2095 int size = AOP_SIZE(oper) - 1;
2098 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2100 if ( AOP_TYPE(oper) != AOP_ACC) {
2101 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
2104 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
2109 #if !defined(GEN_Not)
2110 /*-----------------------------------------------------------------*/
2111 /* genNot - generate code for ! operation */
2112 /*-----------------------------------------------------------------*/
2113 static void pic16_genNot (iCode *ic)
2118 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2119 /* assign asmOps to operand & result */
2120 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2121 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2123 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
2124 /* if in bit space then a special case */
2125 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
2126 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
2127 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2128 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2130 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2131 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
2132 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2137 size = AOP_SIZE(IC_LEFT(ic));
2139 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
2140 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
2141 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
2144 pic16_toBoolean(IC_LEFT(ic));
2146 tlbl = newiTempLabel(NULL);
2147 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
2148 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
2149 pic16_outBitC(IC_RESULT(ic));
2152 /* release the aops */
2153 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2154 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2159 #if !defined(GEN_Cpl)
2160 /*-----------------------------------------------------------------*/
2161 /* genCpl - generate code for complement */
2162 /*-----------------------------------------------------------------*/
2163 static void pic16_genCpl (iCode *ic)
2169 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2170 /* assign asmOps to operand & result */
2171 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
2172 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
2174 /* if both are in bit space then
2176 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2177 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2179 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
2180 pic16_emitcode("cpl","c");
2181 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
2185 size = AOP_SIZE(IC_RESULT(ic));
2188 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
2190 pic16_emitcode("cpl","a");
2191 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
2193 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
2194 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
2196 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
2197 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
2205 /* release the aops */
2206 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2207 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2211 /*-----------------------------------------------------------------*/
2212 /* genUminusFloat - unary minus for floating points */
2213 /*-----------------------------------------------------------------*/
2214 static void genUminusFloat(operand *op,operand *result)
2216 int size ,offset =0 ;
2219 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2220 /* for this we just need to flip the
2221 first it then copy the rest in place */
2222 size = AOP_SIZE(op) - 1;
2223 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2227 pic16_emitcode("cpl","acc.7");
2228 pic16_aopPut(AOP(result),"a",3);
2231 pic16_aopPut(AOP(result),
2232 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2238 /*-----------------------------------------------------------------*/
2239 /* genUminus - unary minus code generation */
2240 /*-----------------------------------------------------------------*/
2241 static void genUminus (iCode *ic)
2244 sym_link *optype, *rtype;
2247 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2249 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2250 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2252 /* if both in bit space then special
2254 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2255 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2257 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2258 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2259 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2264 optype = operandType(IC_LEFT(ic));
2265 rtype = operandType(IC_RESULT(ic));
2267 /* if float then do float stuff */
2268 if (IS_FLOAT(optype)) {
2269 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2273 /* otherwise subtract from zero by taking the 2's complement */
2274 size = AOP_SIZE(IC_LEFT(ic));
2276 for(i=0; i<size; i++) {
2277 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2278 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2280 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2281 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2285 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2286 for(i=1; i<size; i++) {
2288 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2292 /* release the aops */
2293 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2294 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2297 /*-----------------------------------------------------------------*/
2298 /* saveRegisters - will look for a call and save the registers */
2299 /*-----------------------------------------------------------------*/
2300 static void saveRegisters(iCode *lic)
2307 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2309 for (ic = lic ; ic ; ic = ic->next)
2310 if (ic->op == CALL || ic->op == PCALL)
2314 fprintf(stderr,"found parameter push with no function call\n");
2318 /* if the registers have been saved already then
2320 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2323 /* find the registers in use at this time
2324 and push them away to safety */
2325 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2329 if (options.useXstack) {
2330 if (bitVectBitValue(rsave,R0_IDX))
2331 pic16_emitcode("mov","b,r0");
2332 pic16_emitcode("mov","r0,%s",spname);
2333 for (i = 0 ; i < pic16_nRegs ; i++) {
2334 if (bitVectBitValue(rsave,i)) {
2336 pic16_emitcode("mov","a,b");
2338 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2339 pic16_emitcode("movx","@r0,a");
2340 pic16_emitcode("inc","r0");
2343 pic16_emitcode("mov","%s,r0",spname);
2344 if (bitVectBitValue(rsave,R0_IDX))
2345 pic16_emitcode("mov","r0,b");
2347 //for (i = 0 ; i < pic16_nRegs ; i++) {
2348 // if (bitVectBitValue(rsave,i))
2349 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2352 dtype = operandType(IC_LEFT(ic));
2353 if (currFunc && dtype &&
2354 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2355 IFFUNC_ISISR(currFunc->type) &&
2358 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2361 /*-----------------------------------------------------------------*/
2362 /* unsaveRegisters - pop the pushed registers */
2363 /*-----------------------------------------------------------------*/
2364 static void unsaveRegisters (iCode *ic)
2369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2370 /* find the registers in use at this time
2371 and push them away to safety */
2372 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2375 if (options.useXstack) {
2376 pic16_emitcode("mov","r0,%s",spname);
2377 for (i = pic16_nRegs ; i >= 0 ; i--) {
2378 if (bitVectBitValue(rsave,i)) {
2379 pic16_emitcode("dec","r0");
2380 pic16_emitcode("movx","a,@r0");
2382 pic16_emitcode("mov","b,a");
2384 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2388 pic16_emitcode("mov","%s,r0",spname);
2389 if (bitVectBitValue(rsave,R0_IDX))
2390 pic16_emitcode("mov","r0,b");
2392 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2393 // if (bitVectBitValue(rsave,i))
2394 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2400 /*-----------------------------------------------------------------*/
2402 /*-----------------------------------------------------------------*/
2403 static void pushSide(operand * oper, int size)
2406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2408 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2409 if (AOP_TYPE(oper) != AOP_REG &&
2410 AOP_TYPE(oper) != AOP_DIR &&
2412 pic16_emitcode("mov","a,%s",l);
2413 pic16_emitcode("push","acc");
2415 pic16_emitcode("push","%s",l);
2420 void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src)
2422 // (AOP(left)->aopu.pcop->type == PO_DIR)?
2424 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
2425 pic16_emitpcode(POC_MOVFW, src);
2426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset));
2428 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
2429 src, pic16_popGet(AOP(op), offset)));
2434 /*-----------------------------------------------------------------*/
2435 /* assignResultValue - assign results to oper, rescall==1 is */
2436 /* called from genCall() or genPCall() */
2437 /*-----------------------------------------------------------------*/
2438 static void assignResultValue(operand * oper, int rescall)
2440 int size = AOP_SIZE(oper);
2442 DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14
2443 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2446 /* assign result from a call/pcall function() */
2448 /* function results are stored in a special order,
2449 * see top of file with Function return policy, or manual */
2452 /* 8-bits, result in WREG */
2453 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0));
2456 /* 16-bits, result in PRODL:WREG */
2457 pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl));
2461 /* 24-bits, result in PRODH:PRODL:WREG */
2462 pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14
2466 /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */
2467 pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14
2470 /* >32-bits, result on stack, and FSR0 points to beginning.
2471 * Fix stack when done */
2474 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2475 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2477 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2482 pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) ));
2483 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2484 if(STACK_MODEL_LARGE) {
2486 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2490 if(!GpsuedoStkPtr) {
2491 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2492 /* The last byte in the assignment is in W */
2494 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2499 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2500 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2502 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2508 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2510 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2520 /*-----------------------------------------------------------------*/
2521 /* genIpush - genrate code for pushing this gets a little complex */
2522 /*-----------------------------------------------------------------*/
2523 static void genIpush (iCode *ic)
2526 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2528 int size, offset = 0 ;
2532 /* if this is not a parm push : ie. it is spill push
2533 and spill push is always done on the local stack */
2534 if (!ic->parmPush) {
2536 /* and the item is spilt then do nothing */
2537 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2540 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2541 size = AOP_SIZE(IC_LEFT(ic));
2542 /* push it on the stack */
2544 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2549 pic16_emitcode("push","%s",l);
2554 /* this is a paramter push: in this case we call
2555 the routine to find the call and save those
2556 registers that need to be saved */
2559 /* then do the push */
2560 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2563 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2564 size = AOP_SIZE(IC_LEFT(ic));
2567 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2568 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2569 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2571 pic16_emitcode("mov","a,%s",l);
2572 pic16_emitcode("push","acc");
2574 pic16_emitcode("push","%s",l);
2577 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2581 /*-----------------------------------------------------------------*/
2582 /* genIpop - recover the registers: can happen only for spilling */
2583 /*-----------------------------------------------------------------*/
2584 static void genIpop (iCode *ic)
2586 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2591 /* if the temp was not pushed then */
2592 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2595 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2596 size = AOP_SIZE(IC_LEFT(ic));
2599 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2602 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2606 /*-----------------------------------------------------------------*/
2607 /* unsaverbank - restores the resgister bank from stack */
2608 /*-----------------------------------------------------------------*/
2609 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2611 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2617 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2619 if (options.useXstack) {
2621 r = getFreePtr(ic,&aop,FALSE);
2624 pic16_emitcode("mov","%s,_spx",r->name);
2625 pic16_emitcode("movx","a,@%s",r->name);
2626 pic16_emitcode("mov","psw,a");
2627 pic16_emitcode("dec","%s",r->name);
2630 pic16_emitcode ("pop","psw");
2633 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2634 if (options.useXstack) {
2635 pic16_emitcode("movx","a,@%s",r->name);
2636 //pic16_emitcode("mov","(%s+%d),a",
2637 // regspic16[i].base,8*bank+regspic16[i].offset);
2638 pic16_emitcode("dec","%s",r->name);
2641 pic16_emitcode("pop",""); //"(%s+%d)",
2642 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2645 if (options.useXstack) {
2647 pic16_emitcode("mov","_spx,%s",r->name);
2648 pic16_freeAsmop(NULL,aop,ic,TRUE);
2654 /*-----------------------------------------------------------------*/
2655 /* saverbank - saves an entire register bank on the stack */
2656 /*-----------------------------------------------------------------*/
2657 static void saverbank (int bank, iCode *ic, bool pushPsw)
2659 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2665 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2666 if (options.useXstack) {
2669 r = getFreePtr(ic,&aop,FALSE);
2670 pic16_emitcode("mov","%s,_spx",r->name);
2674 for (i = 0 ; i < pic16_nRegs ;i++) {
2675 if (options.useXstack) {
2676 pic16_emitcode("inc","%s",r->name);
2677 //pic16_emitcode("mov","a,(%s+%d)",
2678 // regspic16[i].base,8*bank+regspic16[i].offset);
2679 pic16_emitcode("movx","@%s,a",r->name);
2681 pic16_emitcode("push","");// "(%s+%d)",
2682 //regspic16[i].base,8*bank+regspic16[i].offset);
2686 if (options.useXstack) {
2687 pic16_emitcode("mov","a,psw");
2688 pic16_emitcode("movx","@%s,a",r->name);
2689 pic16_emitcode("inc","%s",r->name);
2690 pic16_emitcode("mov","_spx,%s",r->name);
2691 pic16_freeAsmop (NULL,aop,ic,TRUE);
2694 pic16_emitcode("push","psw");
2696 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2704 /*-----------------------------------------------------------------*/
2705 /* genCall - generates a call statement */
2706 /*-----------------------------------------------------------------*/
2707 static void genCall (iCode *ic)
2712 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2714 /* if caller saves & we have not saved then */
2718 /* if we are calling a function that is not using
2719 * the same register bank then we need to save the
2720 * destination registers on the stack */
2721 dtype = operandType(IC_LEFT(ic));
2722 if (currFunc && dtype &&
2723 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2724 IFFUNC_ISISR(currFunc->type) &&
2727 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2729 /* if send set is not empty the assign */
2733 /* For the Pic port, there is no data stack.
2734 * So parameters passed to functions are stored
2735 * in registers. (The pCode optimizer will get
2736 * rid of most of these :). */
2738 int psuedoStkPtr=-1;
2739 int firstTimeThruLoop = 1;
2741 _G.sendSet = reverseSet(_G.sendSet);
2743 /* First figure how many parameters are getting passed */
2744 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2745 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2746 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2747 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2750 stackParms = psuedoStkPtr;
2752 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2753 int size, offset = 0;
2755 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2756 size = AOP_SIZE(IC_LEFT(sic));
2759 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2760 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2761 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2763 if(!firstTimeThruLoop) {
2764 /* If this is not the first time we've been through the loop
2765 * then we need to save the parameter in a temporary
2766 * register. The last byte of the last parameter is
2770 --psuedoStkPtr; // sanity check
2773 firstTimeThruLoop=0;
2775 mov2w (AOP(IC_LEFT(sic)), offset);
2778 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2784 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2785 OP_SYMBOL(IC_LEFT(ic))->rname :
2786 OP_SYMBOL(IC_LEFT(ic))->name));
2789 /* if we need assign a result value */
2790 if ((IS_ITEMP(IC_RESULT(ic)) &&
2791 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2792 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2793 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2796 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2799 assignResultValue(IC_RESULT(ic), 1);
2801 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2802 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2804 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2808 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2809 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2810 if(STACK_MODEL_LARGE) {
2812 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2816 /* adjust the stack for parameters if required */
2817 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2819 if (ic->parmBytes) {
2822 if (ic->parmBytes > 3) {
2823 pic16_emitcode("mov","a,%s",spname);
2824 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2825 pic16_emitcode("mov","%s,a",spname);
2827 for ( i = 0 ; i < ic->parmBytes ;i++)
2828 pic16_emitcode("dec","%s",spname);
2832 /* if register bank was saved then pop them */
2834 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2836 /* if we hade saved some registers then unsave them */
2837 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2838 unsaveRegisters (ic);
2844 /*-----------------------------------------------------------------*/ // patch 14
2845 /* genPcall - generates a call by pointer statement */
2846 /*-----------------------------------------------------------------*/
2848 // new version, created from genCall
2850 static void genPcall (iCode *ic)
2854 symbol *retlbl = newiTempLabel(NULL);
2855 pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key);
2857 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2859 /* if caller saves & we have not saved then */
2863 /* if we are calling a function that is not using
2864 * the same register bank then we need to save the
2865 * destination registers on the stack */
2866 dtype = operandType(IC_LEFT(ic));
2867 if (currFunc && dtype &&
2868 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2869 IFFUNC_ISISR(currFunc->type) &&
2872 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2874 /* if send set is not empty the assign */
2878 /* For the Pic port, there is no data stack.
2879 * So parameters passed to functions are stored
2880 * in registers. (The pCode optimizer will get
2881 * rid of most of these :). */
2883 int psuedoStkPtr=-1;
2884 int firstTimeThruLoop = 1;
2886 _G.sendSet = reverseSet(_G.sendSet);
2888 /* First figure how many parameters are getting passed */
2889 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2890 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2891 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2892 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2895 stackParms = psuedoStkPtr;
2897 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2898 int size, offset = 0;
2900 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2901 size = AOP_SIZE(IC_LEFT(sic));
2904 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2905 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2906 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2908 if(!firstTimeThruLoop) {
2909 /* If this is not the first time we've been through the loop
2910 * then we need to save the parameter in a temporary
2911 * register. The last byte of the last parameter is
2915 --psuedoStkPtr; // sanity check
2918 firstTimeThruLoop=0;
2920 mov2w (AOP(IC_LEFT(sic)), offset);
2923 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2928 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2930 // push return address
2931 // push $ on return stack, then replace with retlbl
2933 // Note: retlbl is supplied as dummy operand to PUSH
2934 // This has the nice side effect of keeping the label from being optimized out :o)
2935 pic16_emitpcode(POC_PUSH, pic16_popGetLabel(retlbl->key));
2937 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0));
2938 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl));
2939 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0));
2940 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
2941 pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
2942 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
2944 /* make the call by writing the pointer into pc */
2945 // FIXME Disabled writes to PCLATU because of gpsim problems
2947 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
2950 "WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\
2951 Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__);
2954 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
2955 // note: MOVFF to PCL not allowed
2956 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
2957 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
2959 /* return address is here: (X) */
2960 pic16_emitpLabel(retlbl->key);
2962 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2965 /* if we need assign a result value */
2966 if ((IS_ITEMP(IC_RESULT(ic)) &&
2967 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2968 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2969 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2972 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2975 assignResultValue(IC_RESULT(ic), 1);
2977 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2978 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2980 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2984 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2985 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2986 if(STACK_MODEL_LARGE) {
2988 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2992 /* adjust the stack for parameters if required */
2993 // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
2995 if (ic->parmBytes) {
2998 if (ic->parmBytes > 3) {
2999 pic16_emitcode("mov","a,%s",spname);
3000 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3001 pic16_emitcode("mov","%s,a",spname);
3003 for ( i = 0 ; i < ic->parmBytes ;i++)
3004 pic16_emitcode("dec","%s",spname);
3007 /* if register bank was saved then pop them */
3009 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3011 /* if we hade saved some registers then unsave them */
3012 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
3013 unsaveRegisters (ic);
3018 // old version, kept for reference
3020 /*-----------------------------------------------------------------*/
3021 /* genPcall - generates a call by pointer statement */
3022 /*-----------------------------------------------------------------*/
3023 static void genPcall (iCode *ic)
3026 symbol *rlbl = newiTempLabel(NULL);
3029 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3030 /* if caller saves & we have not saved then */
3034 /* if we are calling a function that is not using
3035 the same register bank then we need to save the
3036 destination registers on the stack */
3037 dtype = operandType(IC_LEFT(ic));
3038 if (currFunc && dtype &&
3039 IFFUNC_ISISR(currFunc->type) &&
3040 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3041 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
3044 /* push the return address on to the stack */
3045 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
3046 pic16_emitcode("push","acc");
3047 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
3048 pic16_emitcode("push","acc");
3050 if (options.model == MODEL_FLAT24)
3052 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
3053 pic16_emitcode("push","acc");
3056 /* now push the calling address */
3057 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3059 pushSide(IC_LEFT(ic), FPTRSIZE);
3061 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
3063 /* if send set is not empty the assign */
3067 for (sic = setFirstItem(_G.sendSet) ; sic ;
3068 sic = setNextItem(_G.sendSet)) {
3069 int size, offset = 0;
3070 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
3071 size = AOP_SIZE(IC_LEFT(sic));
3073 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
3075 if (strcmp(l,fReturn[offset]))
3076 pic16_emitcode("mov","%s,%s",
3081 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
3086 pic16_emitcode("ret","");
3087 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
3090 /* if we need assign a result value */
3091 if ((IS_ITEMP(IC_RESULT(ic)) &&
3092 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
3093 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
3094 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
3097 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
3100 assignResultValue(IC_RESULT(ic), 1);
3102 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
3105 /* adjust the stack for parameters if
3107 if (ic->parmBytes) {
3109 if (ic->parmBytes > 3) {
3110 pic16_emitcode("mov","a,%s",spname);
3111 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
3112 pic16_emitcode("mov","%s,a",spname);
3114 for ( i = 0 ; i < ic->parmBytes ;i++)
3115 pic16_emitcode("dec","%s",spname);
3119 /* if register bank was saved then unsave them */
3120 if (currFunc && dtype &&
3121 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
3122 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
3124 /* if we hade saved some registers then
3127 unsaveRegisters (ic);
3133 /*-----------------------------------------------------------------*/
3134 /* resultRemat - result is rematerializable */
3135 /*-----------------------------------------------------------------*/
3136 static int resultRemat (iCode *ic)
3138 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3139 if (SKIP_IC(ic) || ic->op == IFX)
3142 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
3143 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
3144 if (sym->remat && !POINTER_SET(ic))
3151 #if defined(__BORLANDC__) || defined(_MSC_VER)
3152 #define STRCASECMP stricmp
3154 #define STRCASECMP strcasecmp
3158 /*-----------------------------------------------------------------*/
3159 /* inExcludeList - return 1 if the string is in exclude Reg list */
3160 /*-----------------------------------------------------------------*/
3161 static bool inExcludeList(char *s)
3163 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
3166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3167 if (options.excludeRegs[i] &&
3168 STRCASECMP(options.excludeRegs[i],"none") == 0)
3171 for ( i = 0 ; options.excludeRegs[i]; i++) {
3172 if (options.excludeRegs[i] &&
3173 STRCASECMP(s,options.excludeRegs[i]) == 0)
3180 /*-----------------------------------------------------------------*/
3181 /* genFunction - generated code for function entry */
3182 /*-----------------------------------------------------------------*/
3183 static void genFunction (iCode *ic)
3188 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
3190 labelOffset += (max_key+4);
3195 ftype = operandType(IC_LEFT(ic));
3196 sym = OP_SYMBOL(IC_LEFT(ic));
3198 if(IFFUNC_ISISR(sym->type /*ftype*/)) {
3199 /* create an absolute section at the interrupt vector:
3200 * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
3208 sym = OP_SYMBOL( IC_LEFT(ic));
3210 if(interrupts[i]->name
3211 && !STRCASECMP(interrupts[i]->name, sym->name)) {
3218 fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
3219 __FILE__, __LINE__, sym->name);
3222 _G.interruptvector = found;
3225 sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
3226 asym = newSymbol(asymname, 0);
3228 apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
3229 pic16_addpBlock( apb );
3231 pic16_addpCode2pBlock(apb,
3232 pic16_newpCodeCharP(";-----------------------------------------"));
3235 pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
3237 pic16_addpCode2pBlock(apb,
3238 pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
3240 /* mark the end of this tiny function */
3241 pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
3246 abSym = Safe_calloc(1, sizeof(absSym));
3247 abSym->name = Safe_strdup( asymname );
3249 switch( _G.interruptvector ) {
3250 case 0: abSym->address = 0x000000; break;
3251 case 1: abSym->address = 0x000008; break;
3252 case 2: abSym->address = 0x000018; break;
3255 addSet(&absSymSet, abSym);
3260 /* create the function header */
3261 pic16_emitcode(";","-----------------------------------------");
3262 pic16_emitcode(";"," function %s",sym->name);
3263 pic16_emitcode(";","-----------------------------------------");
3265 pic16_emitcode("","%s:",sym->rname);
3266 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
3272 for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
3273 if(!strcmp(ab->name, sym->name)) {
3274 pic16_pBlockConvert2Absolute(pb);
3281 if(IFFUNC_ISNAKED(ftype)) {
3282 DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
3286 /* if critical function then turn interrupts off */
3287 if (IFFUNC_ISCRITICAL(ftype))
3288 pic16_emitcode("clr","ea");
3290 /* if this is an interrupt service routine then
3291 * save acc, b, dpl, dph */
3292 if (IFFUNC_ISISR(sym->type)) {
3294 /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
3295 if(!(_G.interruptvector == 1)) {
3297 /* do not save WREG,STATUS,BSR for high priority interrupts
3298 * because they are stored in the hardware shadow registers already */
3300 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3301 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3302 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3305 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3306 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3307 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
3308 pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3310 // pic16_pBlockConvert2ISR(pb);
3312 /* if any registers used */
3313 if (sym->regsUsed) {
3314 /* save the registers used */
3315 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3316 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3317 if (bitVectBitValue(sym->regsUsed,i)) {
3318 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3319 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3320 // pic16_regWithIdx(i)->name);
3322 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3328 /* emit code to setup stack frame if user enabled,
3329 * and function is not main() */
3331 // fprintf(stderr, "function name: %s\n", sym->name);
3332 if(strcmp(sym->name, "main")) {
3333 if(/*!options.ommitFramePtr || */sym->regsUsed) {
3334 /* setup the stack frame */
3335 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
3336 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
3337 if(STACK_MODEL_LARGE)
3338 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
3342 /* if callee-save to be used for this function
3343 * then save the registers being used in this function */
3344 // if (IFFUNC_CALLEESAVES(sym->type))
3348 // fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
3350 // pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3352 /* if any registers used */
3353 if (sym->regsUsed) {
3354 /* save the registers used */
3355 DEBUGpic16_emitcode("; **", "Saving used registers in stack");
3356 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
3357 if (bitVectBitValue(sym->regsUsed,i)) {
3359 // fprintf(stderr, "%s:%d function %s uses register %s\n",
3360 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3361 // pic16_regWithIdx(i)->name);
3363 pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
3365 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3366 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
3367 // &pic16_pc_postdec1, 0));
3379 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
3381 if (options.useXstack) {
3382 pic16_emitcode("mov","r0,%s",spname);
3383 pic16_emitcode("mov","a,_bp");
3384 pic16_emitcode("movx","@r0,a");
3385 pic16_emitcode("inc","%s",spname);
3387 /* set up the stack */
3388 pic16_emitcode ("push","_bp"); /* save the callers stack */
3390 pic16_emitcode ("mov","_bp,%s",spname);
3393 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
3395 /* adjust the stack for the function */
3400 werror(W_STACK_OVERFLOW,sym->name);
3402 if (i > 3 && sym->recvSize < 4) {
3403 pic16_emitcode ("mov","a,sp");
3404 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
3405 pic16_emitcode ("mov","sp,a");
3408 pic16_emitcode("inc","sp");
3412 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
3414 pic16_emitcode ("mov","a,_spx");
3415 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
3416 pic16_emitcode ("mov","_spx,a");
3421 /*-----------------------------------------------------------------*/
3422 /* genEndFunction - generates epilogue for functions */
3423 /*-----------------------------------------------------------------*/
3424 static void genEndFunction (iCode *ic)
3426 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
3428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3430 if(IFFUNC_ISNAKED(sym->type)) {
3431 DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
3436 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
3438 pic16_emitcode ("mov","%s,_bp",spname);
3442 /* if use external stack but some variables were
3443 added to the local stack then decrement the
3445 if (options.useXstack && sym->stack) {
3446 pic16_emitcode("mov","a,sp");
3447 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
3448 pic16_emitcode("mov","sp,a");
3453 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
3454 if (options.useXstack) {
3455 pic16_emitcode("mov","r0,%s",spname);
3456 pic16_emitcode("movx","a,@r0");
3457 pic16_emitcode("mov","_bp,a");
3458 pic16_emitcode("dec","%s",spname);
3462 pic16_emitcode ("pop","_bp");
3467 if (IFFUNC_ISISR(sym->type)) {
3468 /* now we need to restore the registers */
3469 /* if any registers used */
3470 if (sym->regsUsed) {
3473 /* restore registers used */
3474 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3475 for ( i = sym->regsUsed->size; i >= 0; i--) {
3476 if (bitVectBitValue(sym->regsUsed,i)) {
3478 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3479 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3480 // pic16_regWithIdx(i)->name);
3482 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3484 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3485 // &pic16_pc_preinc1,
3486 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3492 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
3493 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
3494 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
3495 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
3497 if(!(_G.interruptvector == 1)) {
3498 /* do not restore interrupt vector for WREG,STATUS,BSR
3499 * for high priority interrupt, see genFunction */
3501 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
3502 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
3503 pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
3506 _G.interruptvector = 0; /* sanity check */
3508 // pic16_pBlockConvert2ISR(pb);
3511 /* if debug then send end of function */
3512 /* if (options.debug && currFunc) */
3515 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3516 FileBaseName(ic->filename),currFunc->lastLine,
3517 ic->level,ic->block);
3518 if (IS_STATIC(currFunc->etype))
3519 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3521 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3525 pic16_emitpcodeNULLop(POC_RETFIE);
3527 if (IFFUNC_ISCRITICAL(sym->type))
3528 pic16_emitcode("setb","ea");
3531 // pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
3533 /* if any registers used */
3534 if (sym->regsUsed) {
3536 /* save the registers used */
3537 DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
3538 for ( i = sym->regsUsed->size; i >= 0; i--) {
3539 if (bitVectBitValue(sym->regsUsed,i)) {
3541 // fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
3542 // __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
3543 // pic16_regWithIdx(i)->name);
3545 pic16_poppCodeOp( pic16_popRegFromIdx(i) );
3547 // pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
3548 // &pic16_pc_preinc1,
3549 // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
3556 pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
3557 /* if debug then send end of function */
3560 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3561 FileBaseName(ic->filename),currFunc->lastLine,
3562 ic->level,ic->block);
3563 if (IS_STATIC(currFunc->etype))
3564 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3566 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3570 /* insert code to restore stack frame, if user enabled it
3571 * and function is not main() */
3574 if(strcmp(sym->name, "main")) {
3575 if(/*!options.ommitFramePtr ||*/ sym->regsUsed) {
3576 /* restore stack frame */
3577 if(STACK_MODEL_LARGE)
3578 pic16_emitpcode(POC_MOVFF,
3579 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
3580 pic16_emitpcode(POC_MOVFF,
3581 pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
3585 pic16_emitcode ("return","");
3586 pic16_emitpcodeNULLop(POC_RETURN);
3588 /* Mark the end of a function */
3589 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3595 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
3597 // (AOP(left)->aopu.pcop->type == PO_DIR)?
3599 if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) {
3600 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12
3601 pic16_emitpcode(POC_MOVWF, dest);
3603 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3604 pic16_popGet(AOP(op), offset), dest));
3608 /*-----------------------------------------------------------------*/
3609 /* genRet - generate code for return statement */
3610 /*-----------------------------------------------------------------*/
3611 static void genRet (iCode *ic)
3616 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3617 /* if we have no return value then
3618 * just generate the "ret" */
3623 /* we have something to return then
3624 * move the return value into place */
3625 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
3626 size = AOP_SIZE(IC_LEFT(ic));
3630 pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
3631 // pic16_emitpcode(POC_MOVFF,
3632 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
3635 pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
3636 // pic16_emitpcode(POC_MOVFF,
3637 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
3640 pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
3641 // pic16_emitpcode(POC_MOVFF,
3642 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
3645 // pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12
3647 pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12
3648 // pic16_emitpcode(POC_MOVFF,
3649 // pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
3652 /* >32-bits, setup stack and FSR0 */
3654 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
3655 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
3657 pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) );
3659 // popaopidx(AOP(oper), size, GpseudoStkPtr);
3664 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3665 pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l)));
3667 if(STACK_MODEL_LARGE) {
3668 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
3669 pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h)));
3671 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) );
3676 /* old code, left here for reference -- VR */
3680 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3682 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE);
3683 pic16_emitpcomment("push %s",l);
3686 DEBUGpic16_emitcode(";", "%d", __LINE__);
3687 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE);
3688 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3690 if (strcmp(fReturn[offset],l)) {
3691 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD)
3692 || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3693 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3695 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3699 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
3709 if (strcmp(fReturn[pushed],"a"))
3710 pic16_emitcode("pop",fReturn[pushed]);
3712 pic16_emitcode("pop","acc");
3718 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3721 /* generate a jump to the return label
3722 * if the next is not the return statement */
3723 if (!(ic->next && ic->next->op == LABEL
3724 && IC_LABEL(ic->next) == returnLabel)) {
3726 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3727 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3731 /*-----------------------------------------------------------------*/
3732 /* genLabel - generates a label */
3733 /*-----------------------------------------------------------------*/
3734 static void genLabel (iCode *ic)
3738 /* special case never generate */
3739 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3740 if (IC_LABEL(ic) == entryLabel)
3743 pic16_emitpLabel(IC_LABEL(ic)->key);
3744 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3747 /*-----------------------------------------------------------------*/
3748 /* genGoto - generates a goto */
3749 /*-----------------------------------------------------------------*/
3751 static void genGoto (iCode *ic)
3753 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3754 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3758 /*-----------------------------------------------------------------*/
3759 /* genMultbits :- multiplication of bits */
3760 /*-----------------------------------------------------------------*/
3761 static void genMultbits (operand *left,
3765 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3767 if(!pic16_sameRegs(AOP(result),AOP(right)))
3768 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3770 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3771 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3772 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3777 /*-----------------------------------------------------------------*/
3778 /* genMultOneByte : 8 bit multiplication & division */
3779 /*-----------------------------------------------------------------*/
3780 static void genMultOneByte (operand *left,
3785 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3786 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3787 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3789 /* (if two literals, the value is computed before) */
3790 /* if one literal, literal on the right */
3791 if (AOP_TYPE(left) == AOP_LIT){
3797 /* size is already checked in genMult == 1 */
3798 // size = AOP_SIZE(result);
3800 if (AOP_TYPE(right) == AOP_LIT){
3801 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3802 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3803 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3804 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3806 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3807 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3808 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3809 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3812 pic16_genMult8X8_8 (left, right,result);
3816 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3817 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3818 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3819 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3821 if (SPEC_USIGN(opetype)){
3822 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3823 pic16_genUMult8X8_16 (left, right, result, NULL);
3826 /* for filling the MSBs */
3827 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3828 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3832 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3834 pic16_emitcode("mov","a,b");
3836 /* adjust the MSB if left or right neg */
3838 /* if one literal */
3839 if (AOP_TYPE(right) == AOP_LIT){
3840 pic16_emitcode("multiply ","right is a lit");
3841 /* AND literal negative */
3842 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3843 /* adjust MSB (c==0 after mul) */
3844 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3848 pic16_genSMult8X8_16 (left, right, result, NULL);
3852 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3854 pic16_emitcode("rlc","a");
3855 pic16_emitcode("subb","a,acc");
3863 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3864 //pic16_aopPut(AOP(result),"a",offset++);
3871 /*-----------------------------------------------------------------*/
3872 /* genMultOneWord : 16 bit multiplication */
3873 /*-----------------------------------------------------------------*/
3874 static void genMultOneWord (operand *left,
3879 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3880 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3881 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3883 /* (if two literals, the value is computed before)
3884 * if one literal, literal on the right */
3885 if (AOP_TYPE(left) == AOP_LIT){
3891 /* size is checked already == 2 */
3892 // size = AOP_SIZE(result);
3894 if (AOP_TYPE(right) == AOP_LIT) {
3895 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3896 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3897 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3898 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3900 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3901 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3902 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3903 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3906 pic16_genMult16X16_16(left, right,result);
3909 /*-----------------------------------------------------------------*/
3910 /* genMultOneLong : 32 bit multiplication */
3911 /*-----------------------------------------------------------------*/
3912 static void genMultOneLong (operand *left,
3917 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3918 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3919 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3921 /* (if two literals, the value is computed before)
3922 * if one literal, literal on the right */
3923 if (AOP_TYPE(left) == AOP_LIT){
3929 /* size is checked already == 4 */
3930 // size = AOP_SIZE(result);
3932 if (AOP_TYPE(right) == AOP_LIT) {
3933 pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s",
3934 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3935 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3936 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3938 pic16_emitpcomment("multiply variable :%s by variable %s and store in %s",
3939 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3940 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3941 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3944 pic16_genMult32X32_32(left, right,result);
3949 /*-----------------------------------------------------------------*/
3950 /* genMult - generates code for multiplication */
3951 /*-----------------------------------------------------------------*/
3952 static void genMult (iCode *ic)
3954 operand *left = IC_LEFT(ic);
3955 operand *right = IC_RIGHT(ic);
3956 operand *result= IC_RESULT(ic);
3958 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3959 /* assign the amsops */
3960 pic16_aopOp (left,ic,FALSE);
3961 pic16_aopOp (right,ic,FALSE);
3962 pic16_aopOp (result,ic,TRUE);
3964 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3966 /* special cases first *
3968 if (AOP_TYPE(left) == AOP_CRY
3969 && AOP_TYPE(right)== AOP_CRY) {
3970 genMultbits(left,right,result);
3974 /* if both are of size == 1 */
3975 if(AOP_SIZE(left) == 1
3976 && AOP_SIZE(right) == 1) {
3977 genMultOneByte(left,right,result);
3981 /* if both are of size == 2 */
3982 if(AOP_SIZE(left) == 2
3983 && AOP_SIZE(right) == 2) {
3984 genMultOneWord(left, right, result);
3988 /* if both are of size == 4 */
3989 if(AOP_SIZE(left) == 4
3990 && AOP_SIZE(right) == 4) {
3991 genMultOneLong(left, right, result);
3995 pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
3998 fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
3999 /* should have been converted to function call */
4003 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4004 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4005 pic16_freeAsmop(result,NULL,ic,TRUE);
4008 /*-----------------------------------------------------------------*/
4009 /* genDivbits :- division of bits */
4010 /*-----------------------------------------------------------------*/
4011 static void genDivbits (operand *left,
4018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4019 /* the result must be bit */
4020 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4021 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4025 pic16_emitcode("div","ab");
4026 pic16_emitcode("rrc","a");
4027 pic16_aopPut(AOP(result),"c",0);
4030 /*-----------------------------------------------------------------*/
4031 /* genDivOneByte : 8 bit division */
4032 /*-----------------------------------------------------------------*/
4033 static void genDivOneByte (operand *left,
4037 sym_link *opetype = operandType(result);
4042 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4043 size = AOP_SIZE(result) - 1;
4045 /* signed or unsigned */
4046 if (SPEC_USIGN(opetype)) {
4047 /* unsigned is easy */
4048 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4049 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4051 pic16_emitcode("div","ab");
4052 pic16_aopPut(AOP(result),"a",0);
4054 pic16_aopPut(AOP(result),zero,offset++);
4058 /* signed is a little bit more difficult */
4060 /* save the signs of the operands */
4061 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4063 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
4064 pic16_emitcode("push","acc"); /* save it on the stack */
4066 /* now sign adjust for both left & right */
4067 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4069 lbl = newiTempLabel(NULL);
4070 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4071 pic16_emitcode("cpl","a");
4072 pic16_emitcode("inc","a");
4073 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4074 pic16_emitcode("mov","b,a");
4076 /* sign adjust left side */
4077 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4080 lbl = newiTempLabel(NULL);
4081 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4082 pic16_emitcode("cpl","a");
4083 pic16_emitcode("inc","a");
4084 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4086 /* now the division */
4087 pic16_emitcode("div","ab");
4088 /* we are interested in the lower order
4090 pic16_emitcode("mov","b,a");
4091 lbl = newiTempLabel(NULL);
4092 pic16_emitcode("pop","acc");
4093 /* if there was an over flow we don't
4094 adjust the sign of the result */
4095 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4096 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4098 pic16_emitcode("clr","a");
4099 pic16_emitcode("subb","a,b");
4100 pic16_emitcode("mov","b,a");
4101 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4103 /* now we are done */
4104 pic16_aopPut(AOP(result),"b",0);
4106 pic16_emitcode("mov","c,b.7");
4107 pic16_emitcode("subb","a,acc");
4110 pic16_aopPut(AOP(result),"a",offset++);
4114 /*-----------------------------------------------------------------*/
4115 /* genDiv - generates code for division */
4116 /*-----------------------------------------------------------------*/
4117 static void genDiv (iCode *ic)
4119 operand *left = IC_LEFT(ic);
4120 operand *right = IC_RIGHT(ic);
4121 operand *result= IC_RESULT(ic);
4123 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4124 /* assign the amsops */
4125 pic16_aopOp (left,ic,FALSE);
4126 pic16_aopOp (right,ic,FALSE);
4127 pic16_aopOp (result,ic,TRUE);
4129 /* special cases first */
4131 if (AOP_TYPE(left) == AOP_CRY &&
4132 AOP_TYPE(right)== AOP_CRY) {
4133 genDivbits(left,right,result);
4137 /* if both are of size == 1 */
4138 if (AOP_SIZE(left) == 1 &&
4139 AOP_SIZE(right) == 1 ) {
4140 genDivOneByte(left,right,result);
4144 /* should have been converted to function call */
4147 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4148 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4149 pic16_freeAsmop(result,NULL,ic,TRUE);
4152 /*-----------------------------------------------------------------*/
4153 /* genModbits :- modulus of bits */
4154 /*-----------------------------------------------------------------*/
4155 static void genModbits (operand *left,
4162 /* the result must be bit */
4163 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4164 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4168 pic16_emitcode("div","ab");
4169 pic16_emitcode("mov","a,b");
4170 pic16_emitcode("rrc","a");
4171 pic16_aopPut(AOP(result),"c",0);
4174 /*-----------------------------------------------------------------*/
4175 /* genModOneByte : 8 bit modulus */
4176 /*-----------------------------------------------------------------*/
4177 static void genModOneByte (operand *left,
4181 sym_link *opetype = operandType(result);
4185 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4186 /* signed or unsigned */
4187 if (SPEC_USIGN(opetype)) {
4188 /* unsigned is easy */
4189 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
4190 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4192 pic16_emitcode("div","ab");
4193 pic16_aopPut(AOP(result),"b",0);
4197 /* signed is a little bit more difficult */
4199 /* save the signs of the operands */
4200 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4203 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
4204 pic16_emitcode("push","acc"); /* save it on the stack */
4206 /* now sign adjust for both left & right */
4207 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
4210 lbl = newiTempLabel(NULL);
4211 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4212 pic16_emitcode("cpl","a");
4213 pic16_emitcode("inc","a");
4214 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4215 pic16_emitcode("mov","b,a");
4217 /* sign adjust left side */
4218 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
4221 lbl = newiTempLabel(NULL);
4222 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4223 pic16_emitcode("cpl","a");
4224 pic16_emitcode("inc","a");
4225 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4227 /* now the multiplication */
4228 pic16_emitcode("div","ab");
4229 /* we are interested in the lower order
4231 lbl = newiTempLabel(NULL);
4232 pic16_emitcode("pop","acc");
4233 /* if there was an over flow we don't
4234 adjust the sign of the result */
4235 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
4236 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
4238 pic16_emitcode("clr","a");
4239 pic16_emitcode("subb","a,b");
4240 pic16_emitcode("mov","b,a");
4241 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4243 /* now we are done */
4244 pic16_aopPut(AOP(result),"b",0);
4248 /*-----------------------------------------------------------------*/
4249 /* genMod - generates code for division */
4250 /*-----------------------------------------------------------------*/
4251 static void genMod (iCode *ic)
4253 operand *left = IC_LEFT(ic);
4254 operand *right = IC_RIGHT(ic);
4255 operand *result= IC_RESULT(ic);
4257 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4258 /* assign the amsops */
4259 pic16_aopOp (left,ic,FALSE);
4260 pic16_aopOp (right,ic,FALSE);
4261 pic16_aopOp (result,ic,TRUE);
4263 /* special cases first */
4265 if (AOP_TYPE(left) == AOP_CRY &&
4266 AOP_TYPE(right)== AOP_CRY) {
4267 genModbits(left,right,result);
4271 /* if both are of size == 1 */
4272 if (AOP_SIZE(left) == 1 &&
4273 AOP_SIZE(right) == 1 ) {
4274 genModOneByte(left,right,result);
4278 /* should have been converted to function call */
4282 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4283 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4284 pic16_freeAsmop(result,NULL,ic,TRUE);
4287 /*-----------------------------------------------------------------*/
4288 /* genIfxJump :- will create a jump depending on the ifx */
4289 /*-----------------------------------------------------------------*/
4291 note: May need to add parameter to indicate when a variable is in bit space.
4293 static void genIfxJump (iCode *ic, char *jval)
4296 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4297 /* if true label then we jump if condition
4299 if ( IC_TRUE(ic) ) {
4301 if(strcmp(jval,"a") == 0)
4303 else if (strcmp(jval,"c") == 0)
4306 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4307 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
4310 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
4311 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
4315 /* false label is present */
4316 if(strcmp(jval,"a") == 0)
4318 else if (strcmp(jval,"c") == 0)
4321 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
4322 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
4325 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
4326 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
4331 /* mark the icode as generated */
4335 /*-----------------------------------------------------------------*/
4337 /*-----------------------------------------------------------------*/
4338 static void genSkip(iCode *ifx,int status_bit)
4340 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4344 if ( IC_TRUE(ifx) ) {
4345 switch(status_bit) {
4360 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4361 // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4365 switch(status_bit) {
4379 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4380 // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4386 /*-----------------------------------------------------------------*/
4388 /*-----------------------------------------------------------------*/
4389 static void genSkipc(resolvedIfx *rifx)
4391 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4401 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
4402 rifx->generated = 1;
4405 /*-----------------------------------------------------------------*/
4407 /*-----------------------------------------------------------------*/
4408 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
4410 DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx);
4415 if( (rifx->condition ^ invert_condition) & 1)
4420 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4421 rifx->generated = 1;
4425 /*-----------------------------------------------------------------*/
4427 /*-----------------------------------------------------------------*/
4428 static void genSkipz(iCode *ifx, int condition)
4439 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4441 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4444 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4446 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4451 /*-----------------------------------------------------------------*/
4453 /*-----------------------------------------------------------------*/
4454 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
4460 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4462 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
4465 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
4466 rifx->generated = 1;
4470 /*-----------------------------------------------------------------*/
4471 /* genChkZeroes :- greater or less than comparison */
4472 /* For each byte in a literal that is zero, inclusive or the */
4473 /* the corresponding byte in the operand with W */
4474 /* returns true if any of the bytes are zero */
4475 /*-----------------------------------------------------------------*/
4476 static int genChkZeroes(operand *op, int lit, int size)
4483 i = (lit >> (size*8)) & 0xff;
4487 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
4489 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
4498 /*-----------------------------------------------------------------*/
4499 /* genCmp :- greater or less than comparison */
4500 /*-----------------------------------------------------------------*/
4501 static void genCmp (operand *left,operand *right,
4502 operand *result, iCode *ifx, int sign)
4504 int size; //, offset = 0 ;
4505 unsigned long lit = 0L,i = 0;
4506 resolvedIfx rFalseIfx;
4507 // resolvedIfx rTrueIfx;
4509 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4512 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
4513 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
4517 resolveIfx(&rFalseIfx,ifx);
4518 truelbl = newiTempLabel(NULL);
4519 size = max(AOP_SIZE(left),AOP_SIZE(right));
4521 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4525 /* if literal is on the right then swap with left */
4526 if ((AOP_TYPE(right) == AOP_LIT)) {
4527 operand *tmp = right ;
4528 unsigned long mask = (0x100 << (8*(size-1))) - 1;
4529 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4532 lit = (lit - 1) & mask;
4535 rFalseIfx.condition ^= 1;
4538 } else if ((AOP_TYPE(left) == AOP_LIT)) {
4539 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
4543 //if(IC_TRUE(ifx) == NULL)
4544 /* if left & right are bit variables */
4545 if (AOP_TYPE(left) == AOP_CRY &&
4546 AOP_TYPE(right) == AOP_CRY ) {
4547 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
4548 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
4550 /* subtract right from left if at the
4551 end the carry flag is set then we know that
4552 left is greater than right */
4554 symbol *lbl = newiTempLabel(NULL);
4557 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
4558 __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset);
4562 if(AOP_TYPE(right) == AOP_LIT) {
4564 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4566 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
4573 genSkipCond(&rFalseIfx,left,size-1,7);
4575 /* no need to compare to 0...*/
4576 /* NOTE: this is a de-generate compare that most certainly
4577 * creates some dead code. */
4578 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4580 if(ifx) ifx->generated = 1;
4587 //i = (lit >> (size*8)) & 0xff;
4588 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4590 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4592 i = ((0-lit) & 0xff);
4595 /* lit is 0x7f, all signed chars are less than
4596 * this except for 0x7f itself */
4597 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4598 genSkipz2(&rFalseIfx,0);
4600 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4601 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
4602 genSkipc(&rFalseIfx);
4607 genSkipz2(&rFalseIfx,1);
4609 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
4610 genSkipc(&rFalseIfx);
4614 if(ifx) ifx->generated = 1;
4618 /* chars are out of the way. now do ints and longs */
4621 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4628 genSkipCond(&rFalseIfx,left,size,7);
4629 if(ifx) ifx->generated = 1;
4634 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4636 //rFalseIfx.condition ^= 1;
4637 //genSkipCond(&rFalseIfx,left,size,7);
4638 //rFalseIfx.condition ^= 1;
4640 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4641 if(rFalseIfx.condition)
4642 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4644 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4646 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4647 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4648 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4651 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4653 if(rFalseIfx.condition) {
4655 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4661 genSkipc(&rFalseIfx);
4662 pic16_emitpLabel(truelbl->key);
4663 if(ifx) ifx->generated = 1;
4670 if( (lit & 0xff) == 0) {
4671 /* lower byte is zero */
4672 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4673 i = ((lit >> 8) & 0xff) ^0x80;
4674 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4675 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4676 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4677 genSkipc(&rFalseIfx);
4680 if(ifx) ifx->generated = 1;
4685 /* Special cases for signed longs */
4686 if( (lit & 0xffffff) == 0) {
4687 /* lower byte is zero */
4688 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4689 i = ((lit >> 8*3) & 0xff) ^0x80;
4690 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4691 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4692 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4693 genSkipc(&rFalseIfx);
4696 if(ifx) ifx->generated = 1;
4704 if(lit & (0x80 << (size*8))) {
4705 /* lit is negative */
4706 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4708 //genSkipCond(&rFalseIfx,left,size,7);
4710 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4712 if(rFalseIfx.condition)
4713 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4715 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4719 /* lit is positive */
4720 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4721 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4722 if(rFalseIfx.condition)
4723 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4725 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4730 This works, but is only good for ints.
4731 It also requires a "known zero" register.
4732 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4733 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4734 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4735 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4736 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4737 genSkipc(&rFalseIfx);
4739 pic16_emitpLabel(truelbl->key);
4740 if(ifx) ifx->generated = 1;
4744 /* There are no more special cases, so perform a general compare */
4746 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4747 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4751 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4753 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4755 //rFalseIfx.condition ^= 1;
4756 genSkipc(&rFalseIfx);
4758 pic16_emitpLabel(truelbl->key);
4760 if(ifx) ifx->generated = 1;
4767 /* sign is out of the way. So now do an unsigned compare */
4768 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4771 /* General case - compare to an unsigned literal on the right.*/
4773 i = (lit >> (size*8)) & 0xff;
4774 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4775 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4777 i = (lit >> (size*8)) & 0xff;
4780 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4782 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4784 /* this byte of the lit is zero,
4785 *if it's not the last then OR in the variable */
4787 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4792 pic16_emitpLabel(lbl->key);
4793 // pic16_emitpLabel(truelbl->key);
4794 //if(emitFinalCheck)
4795 genSkipc(&rFalseIfx);
4797 pic16_emitpLabel(truelbl->key);
4799 if(ifx) ifx->generated = 1;
4806 if(AOP_TYPE(left) == AOP_LIT) {
4807 //symbol *lbl = newiTempLabel(NULL);
4809 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4812 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4815 if((lit == 0) && (sign == 0)){
4818 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4820 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4822 genSkipz2(&rFalseIfx,0);
4823 if(ifx) ifx->generated = 1;
4830 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4831 /* degenerate compare can never be true */
4832 if(rFalseIfx.condition == 0)
4833 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4835 if(ifx) ifx->generated = 1;
4840 /* signed comparisons to a literal byte */
4842 int lp1 = (lit+1) & 0xff;
4844 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4847 rFalseIfx.condition ^= 1;
4848 genSkipCond(&rFalseIfx,right,0,7);
4851 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4852 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4853 genSkipz2(&rFalseIfx,1);
4856 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4857 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4858 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4859 rFalseIfx.condition ^= 1;
4860 genSkipc(&rFalseIfx);
4864 /* unsigned comparisons to a literal byte */
4866 switch(lit & 0xff ) {
4868 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4869 genSkipz2(&rFalseIfx,0);
4872 rFalseIfx.condition ^= 1;
4873 genSkipCond(&rFalseIfx,right,0,7);
4877 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4878 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4879 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4880 rFalseIfx.condition ^= 1;
4881 if (AOP_TYPE(result) == AOP_CRY)
4882 genSkipc(&rFalseIfx);
4884 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4885 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4891 if(ifx) ifx->generated = 1;
4897 /* Size is greater than 1 */
4905 /* this means lit = 0xffffffff, or -1 */
4908 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4909 rFalseIfx.condition ^= 1;
4910 genSkipCond(&rFalseIfx,right,size,7);
4911 if(ifx) ifx->generated = 1;
4918 if(rFalseIfx.condition) {
4919 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4920 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4923 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4925 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4929 if(rFalseIfx.condition) {
4930 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4931 pic16_emitpLabel(truelbl->key);
4933 rFalseIfx.condition ^= 1;
4934 genSkipCond(&rFalseIfx,right,s,7);
4937 if(ifx) ifx->generated = 1;
4941 if((size == 1) && (0 == (lp1&0xff))) {
4942 /* lower byte of signed word is zero */
4943 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4944 i = ((lp1 >> 8) & 0xff) ^0x80;
4945 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4946 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4947 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4948 rFalseIfx.condition ^= 1;
4949 genSkipc(&rFalseIfx);
4952 if(ifx) ifx->generated = 1;
4956 if(lit & (0x80 << (size*8))) {
4957 /* Lit is less than zero */
4958 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4959 //rFalseIfx.condition ^= 1;
4960 //genSkipCond(&rFalseIfx,left,size,7);
4961 //rFalseIfx.condition ^= 1;
4962 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4963 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4965 if(rFalseIfx.condition)
4966 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4968 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4972 /* Lit is greater than or equal to zero */
4973 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4974 //rFalseIfx.condition ^= 1;
4975 //genSkipCond(&rFalseIfx,right,size,7);
4976 //rFalseIfx.condition ^= 1;
4978 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4979 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4981 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4982 if(rFalseIfx.condition)
4983 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4985 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4990 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4991 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4995 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4997 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4999 rFalseIfx.condition ^= 1;
5000 //rFalseIfx.condition = 1;
5001 genSkipc(&rFalseIfx);
5003 pic16_emitpLabel(truelbl->key);
5005 if(ifx) ifx->generated = 1;
5010 /* compare word or long to an unsigned literal on the right.*/
5015 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
5018 break; /* handled above */
5021 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5023 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5024 genSkipz2(&rFalseIfx,0);
5028 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5030 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5033 if(rFalseIfx.condition)
5034 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
5036 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
5039 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
5040 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
5042 rFalseIfx.condition ^= 1;
5043 genSkipc(&rFalseIfx);
5046 pic16_emitpLabel(truelbl->key);
5048 if(ifx) ifx->generated = 1;
5054 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
5055 i = (lit >> (size*8)) & 0xff;
5057 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5058 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5061 i = (lit >> (size*8)) & 0xff;
5064 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
5066 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
5068 /* this byte of the lit is zero,
5069 * if it's not the last then OR in the variable */
5071 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
5076 pic16_emitpLabel(lbl->key);
5078 rFalseIfx.condition ^= 1;
5080 genSkipc(&rFalseIfx);
5084 pic16_emitpLabel(truelbl->key);
5085 if(ifx) ifx->generated = 1;
5089 /* Compare two variables */
5091 DEBUGpic16_emitcode(";sign","%d",sign);
5095 /* Sigh. thus sucks... */
5097 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
5098 pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5099 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
5100 pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5101 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
5102 pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
5104 /* Signed char comparison */
5105 /* Special thanks to Nikolai Golovchenko for this snippet */
5106 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
5107 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
5108 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
5109 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
5110 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
5111 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
5113 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5114 genSkipc(&rFalseIfx);
5116 if(ifx) ifx->generated = 1;
5122 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5123 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5127 /* The rest of the bytes of a multi-byte compare */
5131 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
5134 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
5135 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
5140 pic16_emitpLabel(lbl->key);
5142 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5143 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
5144 (AOP_TYPE(result) == AOP_REG)) {
5145 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
5146 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
5148 genSkipc(&rFalseIfx);
5150 //genSkipc(&rFalseIfx);
5151 if(ifx) ifx->generated = 1;
5158 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5159 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5160 pic16_outBitC(result);
5162 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5163 /* if the result is used in the next
5164 ifx conditional branch then generate
5165 code a little differently */
5167 genIfxJump (ifx,"c");
5169 pic16_outBitC(result);
5170 /* leave the result in acc */
5175 /*-----------------------------------------------------------------*/
5176 /* genCmpGt :- greater than comparison */
5177 /*-----------------------------------------------------------------*/
5178 static void genCmpGt (iCode *ic, iCode *ifx)
5180 operand *left, *right, *result;
5181 sym_link *letype , *retype;
5184 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5186 right= IC_RIGHT(ic);
5187 result = IC_RESULT(ic);
5189 letype = getSpec(operandType(left));
5190 retype =getSpec(operandType(right));
5191 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5192 /* assign the amsops */
5193 pic16_aopOp (left,ic,FALSE);
5194 pic16_aopOp (right,ic,FALSE);
5195 pic16_aopOp (result,ic,TRUE);
5197 genCmp(right, left, result, ifx, sign);
5199 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5200 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5201 pic16_freeAsmop(result,NULL,ic,TRUE);
5204 /*-----------------------------------------------------------------*/
5205 /* genCmpLt - less than comparisons */
5206 /*-----------------------------------------------------------------*/
5207 static void genCmpLt (iCode *ic, iCode *ifx)
5209 operand *left, *right, *result;
5210 sym_link *letype , *retype;
5213 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5215 right= IC_RIGHT(ic);
5216 result = IC_RESULT(ic);
5218 letype = getSpec(operandType(left));
5219 retype =getSpec(operandType(right));
5220 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
5222 /* assign the amsops */
5223 pic16_aopOp (left,ic,FALSE);
5224 pic16_aopOp (right,ic,FALSE);
5225 pic16_aopOp (result,ic,TRUE);
5227 genCmp(left, right, result, ifx, sign);
5229 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5230 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5231 pic16_freeAsmop(result,NULL,ic,TRUE);
5234 /*-----------------------------------------------------------------*/
5235 /* genc16bit2lit - compare a 16 bit value to a literal */
5236 /*-----------------------------------------------------------------*/
5237 static void genc16bit2lit(operand *op, int lit, int offset)
5241 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
5242 if( (lit&0xff) == 0)
5247 switch( BYTEofLONG(lit,i)) {
5249 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5252 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5255 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5258 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
5259 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5264 switch( BYTEofLONG(lit,i)) {
5266 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
5270 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
5274 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
5277 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
5279 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
5285 /*-----------------------------------------------------------------*/
5286 /* gencjneshort - compare and jump if not equal */
5287 /*-----------------------------------------------------------------*/
5288 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
5290 int size = max(AOP_SIZE(left),AOP_SIZE(right));
5292 int res_offset = 0; /* the result may be a different size then left or right */
5293 int res_size = AOP_SIZE(result);
5295 symbol *lbl, *lbl_done;
5297 unsigned long lit = 0L;
5298 int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
5300 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5301 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5303 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
5304 resolveIfx(&rIfx,ifx);
5305 lbl = newiTempLabel(NULL);
5306 lbl_done = newiTempLabel(NULL);
5309 /* if the left side is a literal or
5310 if the right is in a pointer register and left
5312 if ((AOP_TYPE(left) == AOP_LIT) ||
5313 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5318 if(AOP_TYPE(right) == AOP_LIT)
5319 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5321 if ( regsInCommon(left, result) || regsInCommon(right, result) )
5322 preserve_result = 1;
5324 if(result && !preserve_result)
5327 for(i = 0; i < AOP_SIZE(result); i++)
5328 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5332 /* if the right side is a literal then anything goes */
5333 if (AOP_TYPE(right) == AOP_LIT &&
5334 AOP_TYPE(left) != AOP_DIR ) {
5337 genc16bit2lit(left, lit, 0);
5339 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5342 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5345 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5346 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5348 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5352 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5354 if(res_offset < res_size-1)
5362 /* if the right side is in a register or in direct space or
5363 if the left is a pointer register & right is not */
5364 else if (AOP_TYPE(right) == AOP_REG ||
5365 AOP_TYPE(right) == AOP_DIR ||
5366 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
5367 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
5368 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
5369 int lbl_key = lbl->key;
5372 // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
5373 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5375 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
5376 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
5377 __FUNCTION__,__LINE__);
5381 /* switch(size) { */
5383 /* genc16bit2lit(left, lit, 0); */
5385 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
5390 if((AOP_TYPE(left) == AOP_DIR) &&
5391 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
5393 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5394 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5396 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
5398 switch (lit & 0xff) {
5400 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5403 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5404 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5405 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
5409 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5410 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5411 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5412 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5416 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5417 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5422 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
5425 if(AOP_TYPE(result) == AOP_CRY) {
5426 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5431 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5433 /* fix me. probably need to check result size too */
5434 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
5439 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
5440 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
5447 if(res_offset < res_size-1)
5452 } else if(AOP_TYPE(right) == AOP_REG &&
5453 AOP_TYPE(left) != AOP_DIR){
5456 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5457 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5458 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
5463 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5465 if(res_offset < res_size-1)
5470 /* right is a pointer reg need both a & b */
5472 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
5474 pic16_emitcode("mov","b,%s",l);
5475 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5476 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
5481 if(result && preserve_result)
5484 for(i = 0; i < AOP_SIZE(result); i++)
5485 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5488 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
5490 if(result && preserve_result)
5491 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
5494 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5496 pic16_emitpLabel(lbl->key);
5498 if(result && preserve_result)
5501 for(i = 0; i < AOP_SIZE(result); i++)
5502 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
5504 pic16_emitpLabel(lbl_done->key);
5507 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5514 /*-----------------------------------------------------------------*/
5515 /* gencjne - compare and jump if not equal */
5516 /*-----------------------------------------------------------------*/
5517 static void gencjne(operand *left, operand *right, iCode *ifx)
5519 symbol *tlbl = newiTempLabel(NULL);
5521 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5522 gencjneshort(left, right, lbl);
5524 pic16_emitcode("mov","a,%s",one);
5525 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
5526 pic16_emitcode("","%05d_DS_:",lbl->key+100);
5527 pic16_emitcode("clr","a");
5528 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5530 pic16_emitpLabel(lbl->key);
5531 pic16_emitpLabel(tlbl->key);
5536 /*-----------------------------------------------------------------*/
5537 /* genCmpEq - generates code for equal to */
5538 /*-----------------------------------------------------------------*/
5539 static void genCmpEq (iCode *ic, iCode *ifx)
5541 operand *left, *right, *result;
5542 unsigned long lit = 0L;
5544 symbol *falselbl = newiTempLabel(NULL);
5547 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5550 DEBUGpic16_emitcode ("; ifx is non-null","");
5552 DEBUGpic16_emitcode ("; ifx is null","");
5554 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5555 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5556 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5558 size = max(AOP_SIZE(left),AOP_SIZE(right));
5560 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5562 /* if literal, literal on the right or
5563 if the right is in a pointer register and left
5565 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
5566 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
5567 operand *tmp = right ;
5573 if(ifx && !AOP_SIZE(result)){
5575 DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__);
5576 /* if they are both bit variables */
5577 if (AOP_TYPE(left) == AOP_CRY &&
5578 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5579 DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__);
5580 if(AOP_TYPE(right) == AOP_LIT){
5581 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5583 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5584 pic16_emitcode("cpl","c");
5585 } else if(lit == 1L) {
5586 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5588 pic16_emitcode("clr","c");
5590 /* AOP_TYPE(right) == AOP_CRY */
5592 symbol *lbl = newiTempLabel(NULL);
5593 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5594 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5595 pic16_emitcode("cpl","c");
5596 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5598 /* if true label then we jump if condition
5600 tlbl = newiTempLabel(NULL);
5601 if ( IC_TRUE(ifx) ) {
5602 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
5603 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
5605 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
5606 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
5608 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5611 /* left and right are both bit variables, result is carry */
5614 resolveIfx(&rIfx,ifx);
5616 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
5617 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
5618 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
5619 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
5624 DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__);
5626 /* They're not both bit variables. Is the right a literal? */
5627 if(AOP_TYPE(right) == AOP_LIT) {
5628 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5633 switch(lit & 0xff) {
5635 if ( IC_TRUE(ifx) ) {
5636 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
5638 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5640 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
5641 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5645 if ( IC_TRUE(ifx) ) {
5646 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
5648 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5650 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
5651 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5655 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5657 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
5662 /* end of size == 1 */
5666 genc16bit2lit(left,lit,offset);
5669 /* end of size == 2 */
5674 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5675 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5676 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5677 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5680 /* search for patterns that can be optimized */
5682 genc16bit2lit(left,lit,0);
5686 emitSKPZ; // if hi word unequal
5688 emitSKPNZ; // if hi word equal
5690 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key));
5691 genc16bit2lit(left,lit,2);
5694 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5695 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5699 pic16_emitpLabel(falselbl->key);
5708 } else if(AOP_TYPE(right) == AOP_CRY ) {
5709 /* we know the left is not a bit, but that the right is */
5710 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5711 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5712 pic16_popGet(AOP(right),offset));
5713 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5715 /* if the two are equal, then W will be 0 and the Z bit is set
5716 * we could test Z now, or go ahead and check the high order bytes if
5717 * the variable we're comparing is larger than a byte. */
5720 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5722 if ( IC_TRUE(ifx) ) {
5724 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5725 // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5728 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5729 // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5733 /* They're both variables that are larger than bits */
5736 tlbl = newiTempLabel(NULL);
5739 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5740 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5742 if ( IC_TRUE(ifx) ) {
5746 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5748 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5749 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5753 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5756 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5757 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5762 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5764 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5765 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5769 if(s>1 && IC_TRUE(ifx)) {
5770 pic16_emitpLabel(tlbl->key);
5771 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5775 /* mark the icode as generated */
5780 /* if they are both bit variables */
5781 if (AOP_TYPE(left) == AOP_CRY &&
5782 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5783 DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__);
5784 if(AOP_TYPE(right) == AOP_LIT){
5785 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5787 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5788 pic16_emitcode("cpl","c");
5789 } else if(lit == 1L) {
5790 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5792 pic16_emitcode("clr","c");
5794 /* AOP_TYPE(right) == AOP_CRY */
5796 symbol *lbl = newiTempLabel(NULL);
5797 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5798 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5799 pic16_emitcode("cpl","c");
5800 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5803 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5804 pic16_outBitC(result);
5808 genIfxJump (ifx,"c");
5811 /* if the result is used in an arithmetic operation
5812 then put the result in place */
5813 pic16_outBitC(result);
5816 DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__);
5817 gencjne(left,right,result,ifx);
5820 gencjne(left,right,newiTempLabel(NULL));
5822 if(IC_TRUE(ifx)->key)
5823 gencjne(left,right,IC_TRUE(ifx)->key);
5825 gencjne(left,right,IC_FALSE(ifx)->key);
5829 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5830 pic16_aopPut(AOP(result),"a",0);
5835 genIfxJump (ifx,"a");
5839 /* if the result is used in an arithmetic operation
5840 then put the result in place */
5842 if (AOP_TYPE(result) != AOP_CRY)
5843 pic16_outAcc(result);
5845 /* leave the result in acc */
5849 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5850 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5851 pic16_freeAsmop(result,NULL,ic,TRUE);
5854 /*-----------------------------------------------------------------*/
5855 /* ifxForOp - returns the icode containing the ifx for operand */
5856 /*-----------------------------------------------------------------*/
5857 static iCode *ifxForOp ( operand *op, iCode *ic )
5859 /* if true symbol then needs to be assigned */
5860 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5861 if (IS_TRUE_SYMOP(op))
5864 /* if this has register type condition and
5865 the next instruction is ifx with the same operand
5866 and live to of the operand is upto the ifx only then */
5868 ic->next->op == IFX &&
5869 IC_COND(ic->next)->key == op->key &&
5870 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5874 ic->next->op == IFX &&
5875 IC_COND(ic->next)->key == op->key) {
5876 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5880 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5882 ic->next->op == IFX)
5883 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5886 ic->next->op == IFX &&
5887 IC_COND(ic->next)->key == op->key) {
5888 DEBUGpic16_emitcode ("; "," key is okay");
5889 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5890 OP_SYMBOL(op)->liveTo,
5896 /* the code below is completely untested
5897 * it just allows ulong2fs.c compile -- VR */
5900 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
5901 __FILE__, __FUNCTION__, __LINE__);
5903 /* if this has register type condition and
5904 the next instruction is ifx with the same operand
5905 and live to of the operand is upto the ifx only then */
5907 ic->next->op == IFX &&
5908 IC_COND(ic->next)->key == op->key &&
5909 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5913 ic->next->op == IFX &&
5914 IC_COND(ic->next)->key == op->key) {
5915 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5919 fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
5920 __FILE__, __FUNCTION__, __LINE__);
5922 // return ic->next->next; /* this just might work */ /* FIXME FIXME */
5926 /*-----------------------------------------------------------------*/
5927 /* genAndOp - for && operation */
5928 /*-----------------------------------------------------------------*/
5929 static void genAndOp (iCode *ic)
5931 operand *left,*right, *result;
5934 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5935 /* note here that && operations that are in an
5936 if statement are taken away by backPatchLabels
5937 only those used in arthmetic operations remain */
5938 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5939 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5940 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5942 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5944 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5945 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5946 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5948 /* if both are bit variables */
5949 /* if (AOP_TYPE(left) == AOP_CRY && */
5950 /* AOP_TYPE(right) == AOP_CRY ) { */
5951 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5952 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5953 /* pic16_outBitC(result); */
5955 /* tlbl = newiTempLabel(NULL); */
5956 /* pic16_toBoolean(left); */
5957 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5958 /* pic16_toBoolean(right); */
5959 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5960 /* pic16_outBitAcc(result); */
5963 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5964 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5965 pic16_freeAsmop(result,NULL,ic,TRUE);
5969 /*-----------------------------------------------------------------*/
5970 /* genOrOp - for || operation */
5971 /*-----------------------------------------------------------------*/
5974 modified this code, but it doesn't appear to ever get called
5977 static void genOrOp (iCode *ic)
5979 operand *left,*right, *result;
5982 /* note here that || operations that are in an
5983 if statement are taken away by backPatchLabels
5984 only those used in arthmetic operations remain */
5985 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5986 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5987 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5988 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5990 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5992 /* if both are bit variables */
5993 if (AOP_TYPE(left) == AOP_CRY &&
5994 AOP_TYPE(right) == AOP_CRY ) {
5995 pic16_emitcode("clrc","");
5996 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5997 AOP(left)->aopu.aop_dir,
5998 AOP(left)->aopu.aop_dir);
5999 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6000 AOP(right)->aopu.aop_dir,
6001 AOP(right)->aopu.aop_dir);
6002 pic16_emitcode("setc","");
6005 tlbl = newiTempLabel(NULL);
6006 pic16_toBoolean(left);
6008 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
6009 pic16_toBoolean(right);
6010 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
6012 pic16_outBitAcc(result);
6015 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6016 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6017 pic16_freeAsmop(result,NULL,ic,TRUE);
6020 /*-----------------------------------------------------------------*/
6021 /* isLiteralBit - test if lit == 2^n */
6022 /*-----------------------------------------------------------------*/
6023 static int isLiteralBit(unsigned long lit)
6025 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
6026 0x100L,0x200L,0x400L,0x800L,
6027 0x1000L,0x2000L,0x4000L,0x8000L,
6028 0x10000L,0x20000L,0x40000L,0x80000L,
6029 0x100000L,0x200000L,0x400000L,0x800000L,
6030 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
6031 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
6034 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6035 for(idx = 0; idx < 32; idx++)
6041 /*-----------------------------------------------------------------*/
6042 /* continueIfTrue - */
6043 /*-----------------------------------------------------------------*/
6044 static void continueIfTrue (iCode *ic)
6046 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6048 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6052 /*-----------------------------------------------------------------*/
6054 /*-----------------------------------------------------------------*/
6055 static void jumpIfTrue (iCode *ic)
6057 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6059 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6063 /*-----------------------------------------------------------------*/
6064 /* jmpTrueOrFalse - */
6065 /*-----------------------------------------------------------------*/
6066 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
6068 // ugly but optimized by peephole
6069 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6071 symbol *nlbl = newiTempLabel(NULL);
6072 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
6073 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6074 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
6075 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
6078 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
6079 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6084 /*-----------------------------------------------------------------*/
6085 /* genAnd - code for and */
6086 /*-----------------------------------------------------------------*/
6087 static void genAnd (iCode *ic, iCode *ifx)
6089 operand *left, *right, *result;
6091 unsigned long lit = 0L;
6096 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6097 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6098 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6099 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6101 resolveIfx(&rIfx,ifx);
6103 /* if left is a literal & right is not then exchange them */
6104 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6105 AOP_NEEDSACC(left)) {
6106 operand *tmp = right ;
6111 /* if result = right then exchange them */
6112 if(pic16_sameRegs(AOP(result),AOP(right))){
6113 operand *tmp = right ;
6118 /* if right is bit then exchange them */
6119 if (AOP_TYPE(right) == AOP_CRY &&
6120 AOP_TYPE(left) != AOP_CRY){
6121 operand *tmp = right ;
6125 if(AOP_TYPE(right) == AOP_LIT)
6126 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6128 size = AOP_SIZE(result);
6130 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6133 // result = bit & yy;
6134 if (AOP_TYPE(left) == AOP_CRY){
6135 // c = bit & literal;
6136 if(AOP_TYPE(right) == AOP_LIT){
6138 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6141 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6144 if(size && (AOP_TYPE(result) == AOP_CRY)){
6145 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
6148 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6152 pic16_emitcode("clr","c");
6155 if (AOP_TYPE(right) == AOP_CRY){
6157 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6158 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6161 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
6163 pic16_emitcode("rrc","a");
6164 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
6170 pic16_outBitC(result);
6172 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6173 genIfxJump(ifx, "c");
6177 // if(val & 0xZZ) - size = 0, ifx != FALSE -
6178 // bit = val & 0xZZ - size = 1, ifx = FALSE -
6179 if((AOP_TYPE(right) == AOP_LIT) &&
6180 (AOP_TYPE(result) == AOP_CRY) &&
6181 (AOP_TYPE(left) != AOP_CRY)){
6182 int posbit = isLiteralBit(lit);
6186 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
6189 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
6195 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6196 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
6198 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6199 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
6202 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
6203 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
6204 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
6211 symbol *tlbl = newiTempLabel(NULL);
6212 int sizel = AOP_SIZE(left);
6214 pic16_emitcode("setb","c");
6216 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
6217 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6219 if((posbit = isLiteralBit(bytelit)) != 0)
6220 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
6222 if(bytelit != 0x0FFL)
6223 pic16_emitcode("anl","a,%s",
6224 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
6225 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6230 // bit = left & literal
6232 pic16_emitcode("clr","c");
6233 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6235 // if(left & literal)
6238 jmpTrueOrFalse(ifx, tlbl);
6242 pic16_outBitC(result);
6246 /* if left is same as result */
6247 if(pic16_sameRegs(AOP(result),AOP(left))){
6249 for(;size--; offset++,lit>>=8) {
6250 if(AOP_TYPE(right) == AOP_LIT){
6251 switch(lit & 0xff) {
6253 /* and'ing with 0 has clears the result */
6254 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6255 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6258 /* and'ing with 0xff is a nop when the result and left are the same */
6263 int p = my_powof2( (~lit) & 0xff );
6265 /* only one bit is set in the literal, so use a bcf instruction */
6266 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
6267 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6270 pic16_emitcode("movlw","0x%x", (lit & 0xff));
6271 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6272 if(know_W != (lit&0xff))
6273 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6275 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6280 if (AOP_TYPE(left) == AOP_ACC) {
6281 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6283 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6284 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
6291 // left & result in different registers
6292 if(AOP_TYPE(result) == AOP_CRY){
6294 // if(size), result in bit
6295 // if(!size && ifx), conditional oper: if(left & right)
6296 symbol *tlbl = newiTempLabel(NULL);
6297 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
6299 pic16_emitcode("setb","c");
6301 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6302 pic16_emitcode("anl","a,%s",
6303 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6304 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6309 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6310 pic16_outBitC(result);
6312 jmpTrueOrFalse(ifx, tlbl);
6314 for(;(size--);offset++) {
6316 // result = left & right
6317 if(AOP_TYPE(right) == AOP_LIT){
6318 int t = (lit >> (offset*8)) & 0x0FFL;
6321 pic16_emitcode("clrf","%s",
6322 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6323 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
6326 pic16_emitcode("movf","%s,w",
6327 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6328 pic16_emitcode("movwf","%s",
6329 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6330 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6331 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6334 pic16_emitcode("movlw","0x%x",t);
6335 pic16_emitcode("andwf","%s,w",
6336 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6337 pic16_emitcode("movwf","%s",
6338 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6340 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6341 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6342 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6347 if (AOP_TYPE(left) == AOP_ACC) {
6348 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6349 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
6351 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6352 pic16_emitcode("andwf","%s,w",
6353 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6354 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6355 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
6357 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6358 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6364 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6365 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6366 pic16_freeAsmop(result,NULL,ic,TRUE);
6369 /*-----------------------------------------------------------------*/
6370 /* genOr - code for or */
6371 /*-----------------------------------------------------------------*/
6372 static void genOr (iCode *ic, iCode *ifx)
6374 operand *left, *right, *result;
6376 unsigned long lit = 0L;
6378 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6380 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6381 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6382 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6384 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6386 /* if left is a literal & right is not then exchange them */
6387 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6388 AOP_NEEDSACC(left)) {
6389 operand *tmp = right ;
6394 /* if result = right then exchange them */
6395 if(pic16_sameRegs(AOP(result),AOP(right))){
6396 operand *tmp = right ;
6401 /* if right is bit then exchange them */
6402 if (AOP_TYPE(right) == AOP_CRY &&
6403 AOP_TYPE(left) != AOP_CRY){
6404 operand *tmp = right ;
6409 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
6411 if(AOP_TYPE(right) == AOP_LIT)
6412 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6414 size = AOP_SIZE(result);
6418 if (AOP_TYPE(left) == AOP_CRY){
6419 if(AOP_TYPE(right) == AOP_LIT){
6420 // c = bit & literal;
6422 // lit != 0 => result = 1
6423 if(AOP_TYPE(result) == AOP_CRY){
6425 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6426 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6427 // AOP(result)->aopu.aop_dir,
6428 // AOP(result)->aopu.aop_dir);
6430 continueIfTrue(ifx);
6434 // lit == 0 => result = left
6435 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6437 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
6440 if (AOP_TYPE(right) == AOP_CRY){
6441 if(pic16_sameRegs(AOP(result),AOP(left))){
6443 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6444 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
6445 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6447 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6448 AOP(result)->aopu.aop_dir,
6449 AOP(result)->aopu.aop_dir);
6450 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6451 AOP(right)->aopu.aop_dir,
6452 AOP(right)->aopu.aop_dir);
6453 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6454 AOP(result)->aopu.aop_dir,
6455 AOP(result)->aopu.aop_dir);
6457 if( AOP_TYPE(result) == AOP_ACC) {
6458 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
6459 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6460 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6461 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
6465 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6466 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
6467 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6468 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6470 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
6471 AOP(result)->aopu.aop_dir,
6472 AOP(result)->aopu.aop_dir);
6473 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
6474 AOP(right)->aopu.aop_dir,
6475 AOP(right)->aopu.aop_dir);
6476 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
6477 AOP(left)->aopu.aop_dir,
6478 AOP(left)->aopu.aop_dir);
6479 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
6480 AOP(result)->aopu.aop_dir,
6481 AOP(result)->aopu.aop_dir);
6486 symbol *tlbl = newiTempLabel(NULL);
6487 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6490 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
6491 if( AOP_TYPE(right) == AOP_ACC) {
6492 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
6494 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
6495 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
6500 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
6501 pic16_emitcode(";XXX setb","c");
6502 pic16_emitcode(";XXX jb","%s,%05d_DS_",
6503 AOP(left)->aopu.aop_dir,tlbl->key+100);
6504 pic16_toBoolean(right);
6505 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6506 if((AOP_TYPE(result) == AOP_CRY) && ifx){
6507 jmpTrueOrFalse(ifx, tlbl);
6511 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6518 pic16_outBitC(result);
6520 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6521 genIfxJump(ifx, "c");
6525 // if(val | 0xZZ) - size = 0, ifx != FALSE -
6526 // bit = val | 0xZZ - size = 1, ifx = FALSE -
6527 if((AOP_TYPE(right) == AOP_LIT) &&
6528 (AOP_TYPE(result) == AOP_CRY) &&
6529 (AOP_TYPE(left) != AOP_CRY)){
6531 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6534 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
6536 continueIfTrue(ifx);
6539 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6540 // lit = 0, result = boolean(left)
6542 pic16_emitcode(";XXX setb","c");
6543 pic16_toBoolean(right);
6545 symbol *tlbl = newiTempLabel(NULL);
6546 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6548 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6550 genIfxJump (ifx,"a");
6554 pic16_outBitC(result);
6558 /* if left is same as result */
6559 if(pic16_sameRegs(AOP(result),AOP(left))){
6561 for(;size--; offset++,lit>>=8) {
6562 if(AOP_TYPE(right) == AOP_LIT){
6563 if((lit & 0xff) == 0)
6564 /* or'ing with 0 has no effect */
6567 int p = my_powof2(lit & 0xff);
6569 /* only one bit is set in the literal, so use a bsf instruction */
6570 pic16_emitpcode(POC_BSF,
6571 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
6573 if(know_W != (lit & 0xff))
6574 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
6575 know_W = lit & 0xff;
6576 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6581 if (AOP_TYPE(left) == AOP_ACC) {
6582 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
6583 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6585 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6586 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
6588 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6589 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6595 // left & result in different registers
6596 if(AOP_TYPE(result) == AOP_CRY){
6598 // if(size), result in bit
6599 // if(!size && ifx), conditional oper: if(left | right)
6600 symbol *tlbl = newiTempLabel(NULL);
6601 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6602 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
6606 pic16_emitcode(";XXX setb","c");
6608 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6609 pic16_emitcode(";XXX orl","a,%s",
6610 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6611 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
6616 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6617 pic16_outBitC(result);
6619 jmpTrueOrFalse(ifx, tlbl);
6620 } else for(;(size--);offset++){
6622 // result = left & right
6623 if(AOP_TYPE(right) == AOP_LIT){
6624 int t = (lit >> (offset*8)) & 0x0FFL;
6627 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
6628 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6630 pic16_emitcode("movf","%s,w",
6631 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6632 pic16_emitcode("movwf","%s",
6633 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6636 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6637 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6638 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6640 pic16_emitcode("movlw","0x%x",t);
6641 pic16_emitcode("iorwf","%s,w",
6642 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6643 pic16_emitcode("movwf","%s",
6644 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6650 // faster than result <- left, anl result,right
6651 // and better if result is SFR
6652 if (AOP_TYPE(left) == AOP_ACC) {
6653 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
6654 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6656 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
6657 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
6659 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6660 pic16_emitcode("iorwf","%s,w",
6661 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6663 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6664 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6669 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6670 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6671 pic16_freeAsmop(result,NULL,ic,TRUE);
6674 /*-----------------------------------------------------------------*/
6675 /* genXor - code for xclusive or */
6676 /*-----------------------------------------------------------------*/
6677 static void genXor (iCode *ic, iCode *ifx)
6679 operand *left, *right, *result;
6681 unsigned long lit = 0L;
6683 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6685 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
6686 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
6687 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
6689 /* if left is a literal & right is not ||
6690 if left needs acc & right does not */
6691 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
6692 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
6693 operand *tmp = right ;
6698 /* if result = right then exchange them */
6699 if(pic16_sameRegs(AOP(result),AOP(right))){
6700 operand *tmp = right ;
6705 /* if right is bit then exchange them */
6706 if (AOP_TYPE(right) == AOP_CRY &&
6707 AOP_TYPE(left) != AOP_CRY){
6708 operand *tmp = right ;
6712 if(AOP_TYPE(right) == AOP_LIT)
6713 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6715 size = AOP_SIZE(result);
6719 if (AOP_TYPE(left) == AOP_CRY){
6720 if(AOP_TYPE(right) == AOP_LIT){
6721 // c = bit & literal;
6723 // lit>>1 != 0 => result = 1
6724 if(AOP_TYPE(result) == AOP_CRY){
6726 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6727 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6729 continueIfTrue(ifx);
6732 pic16_emitcode("setb","c");
6736 // lit == 0, result = left
6737 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6739 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6741 // lit == 1, result = not(left)
6742 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6743 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6744 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6745 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6748 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6749 pic16_emitcode("cpl","c");
6756 symbol *tlbl = newiTempLabel(NULL);
6757 if (AOP_TYPE(right) == AOP_CRY){
6759 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6762 int sizer = AOP_SIZE(right);
6764 // if val>>1 != 0, result = 1
6765 pic16_emitcode("setb","c");
6767 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6769 // test the msb of the lsb
6770 pic16_emitcode("anl","a,#0xfe");
6771 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6775 pic16_emitcode("rrc","a");
6777 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6778 pic16_emitcode("cpl","c");
6779 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6784 pic16_outBitC(result);
6786 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6787 genIfxJump(ifx, "c");
6791 if(pic16_sameRegs(AOP(result),AOP(left))){
6792 /* if left is same as result */
6793 for(;size--; offset++) {
6794 if(AOP_TYPE(right) == AOP_LIT){
6795 int t = (lit >> (offset*8)) & 0x0FFL;
6799 if (IS_AOP_PREG(left)) {
6800 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6801 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6802 pic16_aopPut(AOP(result),"a",offset);
6804 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6805 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6806 pic16_emitcode("xrl","%s,%s",
6807 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6808 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6811 if (AOP_TYPE(left) == AOP_ACC)
6812 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6814 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6815 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6817 if (IS_AOP_PREG(left)) {
6818 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6819 pic16_aopPut(AOP(result),"a",offset);
6821 pic16_emitcode("xrl","%s,a",
6822 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6828 // left & result in different registers
6829 if(AOP_TYPE(result) == AOP_CRY){
6831 // if(size), result in bit
6832 // if(!size && ifx), conditional oper: if(left ^ right)
6833 symbol *tlbl = newiTempLabel(NULL);
6834 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6836 pic16_emitcode("setb","c");
6838 if((AOP_TYPE(right) == AOP_LIT) &&
6839 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6840 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6842 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6843 pic16_emitcode("xrl","a,%s",
6844 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6846 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6851 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6852 pic16_outBitC(result);
6854 jmpTrueOrFalse(ifx, tlbl);
6855 } else for(;(size--);offset++){
6857 // result = left & right
6858 if(AOP_TYPE(right) == AOP_LIT){
6859 int t = (lit >> (offset*8)) & 0x0FFL;
6862 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6863 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6864 pic16_emitcode("movf","%s,w",
6865 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6866 pic16_emitcode("movwf","%s",
6867 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6870 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6871 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6872 pic16_emitcode("comf","%s,w",
6873 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6874 pic16_emitcode("movwf","%s",
6875 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6878 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6879 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6880 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6881 pic16_emitcode("movlw","0x%x",t);
6882 pic16_emitcode("xorwf","%s,w",
6883 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6884 pic16_emitcode("movwf","%s",
6885 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6891 // faster than result <- left, anl result,right
6892 // and better if result is SFR
6893 if (AOP_TYPE(left) == AOP_ACC) {
6894 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6895 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6897 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6898 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6899 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6900 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6902 if ( AOP_TYPE(result) != AOP_ACC){
6903 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6904 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6910 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6911 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6912 pic16_freeAsmop(result,NULL,ic,TRUE);
6915 /*-----------------------------------------------------------------*/
6916 /* genInline - write the inline code out */
6917 /*-----------------------------------------------------------------*/
6918 static void genInline (iCode *ic)
6920 char *buffer, *bp, *bp1;
6922 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6924 _G.inLine += (!options.asmpeep);
6926 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6927 strcpy(buffer,IC_INLINE(ic));
6929 // fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer);
6931 /* emit each line as a code */
6937 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6945 /* print label, use this special format with NULL directive
6946 * to denote that the argument should not be indented with tab */
6947 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process
6954 if ((bp1 != bp) && *bp1)
6955 pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process
6960 _G.inLine -= (!options.asmpeep);
6963 /*-----------------------------------------------------------------*/
6964 /* genRRC - rotate right with carry */
6965 /*-----------------------------------------------------------------*/
6966 static void genRRC (iCode *ic)
6968 operand *left , *result ;
6969 int size, offset = 0, same;
6971 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6973 /* rotate right with carry */
6975 result=IC_RESULT(ic);
6976 pic16_aopOp (left,ic,FALSE);
6977 pic16_aopOp (result,ic,FALSE);
6979 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6981 same = pic16_sameRegs(AOP(result),AOP(left));
6983 size = AOP_SIZE(result);
6985 DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same);
6987 /* get the lsb and put it into the carry */
6988 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6995 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6997 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6998 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7004 pic16_freeAsmop(left,NULL,ic,TRUE);
7005 pic16_freeAsmop(result,NULL,ic,TRUE);
7008 /*-----------------------------------------------------------------*/
7009 /* genRLC - generate code for rotate left with carry */
7010 /*-----------------------------------------------------------------*/
7011 static void genRLC (iCode *ic)
7013 operand *left , *result ;
7014 int size, offset = 0;
7017 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7018 /* rotate right with carry */
7020 result=IC_RESULT(ic);
7021 pic16_aopOp (left,ic,FALSE);
7022 pic16_aopOp (result,ic,FALSE);
7024 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7026 same = pic16_sameRegs(AOP(result),AOP(left));
7028 /* move it to the result */
7029 size = AOP_SIZE(result);
7031 /* get the msb and put it into the carry */
7032 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
7039 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
7041 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
7042 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7049 pic16_freeAsmop(left,NULL,ic,TRUE);
7050 pic16_freeAsmop(result,NULL,ic,TRUE);
7054 /* gpasm can get the highest order bit with HIGH/UPPER
7055 * so the following probably is not needed -- VR */
7057 /*-----------------------------------------------------------------*/
7058 /* genGetHbit - generates code get highest order bit */
7059 /*-----------------------------------------------------------------*/
7060 static void genGetHbit (iCode *ic)
7062 operand *left, *result;
7064 result=IC_RESULT(ic);
7065 pic16_aopOp (left,ic,FALSE);
7066 pic16_aopOp (result,ic,FALSE);
7068 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7069 /* get the highest order byte into a */
7070 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
7071 if(AOP_TYPE(result) == AOP_CRY){
7072 pic16_emitcode("rlc","a");
7073 pic16_outBitC(result);
7076 pic16_emitcode("rl","a");
7077 pic16_emitcode("anl","a,#0x01");
7078 pic16_outAcc(result);
7082 pic16_freeAsmop(left,NULL,ic,TRUE);
7083 pic16_freeAsmop(result,NULL,ic,TRUE);
7087 /*-----------------------------------------------------------------*/
7088 /* AccRol - rotate left accumulator by known count */
7089 /*-----------------------------------------------------------------*/
7090 static void AccRol (int shCount)
7092 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7093 shCount &= 0x0007; // shCount : 0..7
7098 pic16_emitcode("rl","a");
7101 pic16_emitcode("rl","a");
7102 pic16_emitcode("rl","a");
7105 pic16_emitcode("swap","a");
7106 pic16_emitcode("rr","a");
7109 pic16_emitcode("swap","a");
7112 pic16_emitcode("swap","a");
7113 pic16_emitcode("rl","a");
7116 pic16_emitcode("rr","a");
7117 pic16_emitcode("rr","a");
7120 pic16_emitcode("rr","a");
7126 /*-----------------------------------------------------------------*/
7127 /* AccLsh - left shift accumulator by known count */
7128 /*-----------------------------------------------------------------*/
7129 static void AccLsh (int shCount)
7131 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7137 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7140 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7141 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7144 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7145 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7148 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7151 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7152 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7155 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7156 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7159 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7163 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount]));
7166 /*-----------------------------------------------------------------*/
7167 /* AccRsh - right shift accumulator by known count */
7168 /*-----------------------------------------------------------------*/
7169 static void AccRsh (int shCount, int andmask)
7171 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7176 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7177 // andmask = 0; /* no need */
7180 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7181 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7182 // andmask = 0; /* no need */
7185 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7186 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7189 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7192 pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg));
7193 pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7196 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7197 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7200 pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg));
7205 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount]));
7207 DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__);
7211 /*-----------------------------------------------------------------*/
7212 /* AccSRsh - signed right shift accumulator by known count */
7213 /*-----------------------------------------------------------------*/
7214 static void AccSRsh (int shCount)
7217 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7220 pic16_emitcode("mov","c,acc.7");
7221 pic16_emitcode("rrc","a");
7222 } else if(shCount == 2){
7223 pic16_emitcode("mov","c,acc.7");
7224 pic16_emitcode("rrc","a");
7225 pic16_emitcode("mov","c,acc.7");
7226 pic16_emitcode("rrc","a");
7228 tlbl = newiTempLabel(NULL);
7229 /* rotate right accumulator */
7230 AccRol(8 - shCount);
7231 /* and kill the higher order bits */
7232 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
7233 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
7234 pic16_emitcode("orl","a,#0x%02x",
7235 (unsigned char)~SRMask[shCount]);
7236 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7241 /*-----------------------------------------------------------------*/
7242 /* shiftR1Left2Result - shift right one byte from left to result */
7243 /*-----------------------------------------------------------------*/
7244 static void shiftR1Left2ResultSigned (operand *left, int offl,
7245 operand *result, int offr,
7250 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7252 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7256 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7258 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7260 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7261 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7267 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7269 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7271 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7272 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7274 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7275 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7281 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7283 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7284 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7287 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7288 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7289 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7291 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7292 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
7294 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7298 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7299 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7300 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7301 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
7302 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7306 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7308 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7309 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7311 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7312 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
7313 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
7314 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
7315 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7320 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7321 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7322 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
7323 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7324 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
7325 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7327 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7328 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7329 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7330 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
7331 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
7337 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
7338 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7339 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7340 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7342 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7343 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
7344 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
7352 /*-----------------------------------------------------------------*/
7353 /* shiftR1Left2Result - shift right one byte from left to result */
7354 /*-----------------------------------------------------------------*/
7355 static void shiftR1Left2Result (operand *left, int offl,
7356 operand *result, int offr,
7357 int shCount, int sign)
7361 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7363 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7365 /* Copy the msb into the carry if signed. */
7367 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
7377 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7379 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7380 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7386 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7388 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7389 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7392 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7397 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7399 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7400 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7403 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7404 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7405 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
7406 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7410 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7411 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7412 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7416 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
7417 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7418 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7420 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7425 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7426 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
7427 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7428 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7429 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7434 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7435 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7436 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7445 /*-----------------------------------------------------------------*/
7446 /* shiftL1Left2Result - shift left one byte from left to result */
7447 /*-----------------------------------------------------------------*/
7448 static void shiftL1Left2Result (operand *left, int offl,
7449 operand *result, int offr, int shCount)
7454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7456 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
7457 DEBUGpic16_emitcode ("; ***","same = %d",same);
7458 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7460 /* shift left accumulator */
7461 //AccLsh(shCount); // don't comment out just yet...
7462 // pic16_aopPut(AOP(result),"a",offr);
7466 /* Shift left 1 bit position */
7467 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7469 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
7471 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
7472 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7476 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7477 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
7478 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7479 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7482 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7483 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
7484 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7485 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7486 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7489 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7490 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7491 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7494 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7495 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7496 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7497 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7500 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7501 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
7502 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7503 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7504 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7507 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7508 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7509 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7513 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
7518 /*-----------------------------------------------------------------*/
7519 /* movLeft2Result - move byte from left to result */
7520 /*-----------------------------------------------------------------*/
7521 static void movLeft2Result (operand *left, int offl,
7522 operand *result, int offr)
7525 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7526 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
7527 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
7529 if (*l == '@' && (IS_AOP_PREG(result))) {
7530 pic16_emitcode("mov","a,%s",l);
7531 pic16_aopPut(AOP(result),"a",offr);
7533 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7534 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7539 /*-----------------------------------------------------------------*/
7540 /* shiftL2Left2Result - shift left two bytes from left to result */
7541 /*-----------------------------------------------------------------*/
7542 static void shiftL2Left2Result (operand *left, int offl,
7543 operand *result, int offr, int shCount)
7545 int same = pic16_sameRegs(AOP(result), AOP(left));
7548 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr);
7550 if (same && (offl != offr)) { // shift bytes
7553 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7554 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7556 } else { // just treat as different later on
7569 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
7570 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
7571 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7575 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7576 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7582 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
7583 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
7584 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7585 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7586 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
7587 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7588 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7590 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7591 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7595 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7596 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7597 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7598 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7599 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7600 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7601 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7602 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7603 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7604 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7607 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7608 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
7609 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7610 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7611 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7621 /* note, use a mov/add for the shift since the mov has a
7622 chance of getting optimized out */
7623 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
7624 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7625 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7626 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7627 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7631 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7632 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7638 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7639 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7640 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7641 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7642 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7643 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
7644 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
7645 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7649 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7650 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7654 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7655 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7656 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
7657 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7659 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7660 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7661 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
7662 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
7663 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7664 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
7665 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
7666 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7669 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7670 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7671 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7672 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
7673 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7678 /*-----------------------------------------------------------------*/
7679 /* shiftR2Left2Result - shift right two bytes from left to result */
7680 /*-----------------------------------------------------------------*/
7681 static void shiftR2Left2Result (operand *left, int offl,
7682 operand *result, int offr,
7683 int shCount, int sign)
7685 int same = pic16_sameRegs(AOP(result), AOP(left));
7687 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign);
7689 if (same && (offl != offr)) { // shift right bytes
7692 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i));
7693 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i));
7695 } else { // just treat as different later on
7707 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7712 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7713 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7715 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
7716 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7717 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
7718 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7723 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
7726 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
7727 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
7734 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
7735 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
7736 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
7738 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
7739 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
7740 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7741 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7743 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
7744 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
7745 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
7747 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
7748 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
7749 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7750 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
7751 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
7755 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
7756 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
7760 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
7761 pic16_emitpcode(POC_BTFSC,
7762 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
7763 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7771 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7772 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7774 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7775 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7776 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7777 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7779 pic16_emitpcode(POC_BTFSC,
7780 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7781 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7783 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7784 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7785 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7786 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7788 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7789 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7790 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7791 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7792 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7793 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7794 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7795 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7797 pic16_emitpcode(POC_BTFSC,
7798 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7799 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7801 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7802 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7809 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7810 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7811 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7812 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7815 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7817 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7822 /*-----------------------------------------------------------------*/
7823 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7824 /*-----------------------------------------------------------------*/
7825 static void shiftLLeftOrResult (operand *left, int offl,
7826 operand *result, int offr, int shCount)
7828 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7830 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7831 /* shift left accumulator */
7833 /* or with result */
7834 /* back to result */
7835 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7838 /*-----------------------------------------------------------------*/
7839 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7840 /*-----------------------------------------------------------------*/
7841 static void shiftRLeftOrResult (operand *left, int offl,
7842 operand *result, int offr, int shCount)
7844 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7846 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl));
7847 /* shift right accumulator */
7849 /* or with result */
7850 /* back to result */
7851 pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr));
7854 /*-----------------------------------------------------------------*/
7855 /* genlshOne - left shift a one byte quantity by known count */
7856 /*-----------------------------------------------------------------*/
7857 static void genlshOne (operand *result, operand *left, int shCount)
7859 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7860 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7863 /*-----------------------------------------------------------------*/
7864 /* genlshTwo - left shift two bytes by known amount != 0 */
7865 /*-----------------------------------------------------------------*/
7866 static void genlshTwo (operand *result,operand *left, int shCount)
7870 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
7871 size = pic16_getDataSize(result);
7873 /* if shCount >= 8 */
7879 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7881 movLeft2Result(left, LSB, result, MSB16);
7883 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7886 /* 1 <= shCount <= 7 */
7889 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7891 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7895 /*-----------------------------------------------------------------*/
7896 /* shiftLLong - shift left one long from left to result */
7897 /* offr = LSB or MSB16 */
7898 /*-----------------------------------------------------------------*/
7899 static void shiftLLong (operand *left, operand *result, int offr )
7901 int size = AOP_SIZE(result);
7902 int same = pic16_sameRegs(AOP(left),AOP(result));
7905 DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size);
7907 if (same && (offr == MSB16)) { //shift one byte
7908 for(i=size-1;i>=MSB16;i--) {
7909 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1));
7910 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i));
7913 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr));
7916 if (size >= LSB+offr ){
7918 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr));
7920 pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB));
7921 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr));
7925 if(size >= MSB16+offr){
7927 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr));
7929 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16));
7930 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr));
7934 if(size >= MSB24+offr){
7936 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr));
7938 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24));
7939 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr));
7943 if(size > MSB32+offr){
7945 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr));
7947 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32));
7948 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr));
7952 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7956 /*-----------------------------------------------------------------*/
7957 /* genlshFour - shift four byte by a known amount != 0 */
7958 /*-----------------------------------------------------------------*/
7959 static void genlshFour (operand *result, operand *left, int shCount)
7963 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7964 size = AOP_SIZE(result);
7966 /* if shifting more that 3 bytes */
7967 if (shCount >= 24 ) {
7970 /* lowest order of left goes to the highest
7971 order of the destination */
7972 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7974 movLeft2Result(left, LSB, result, MSB32);
7976 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7977 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7978 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24));
7983 /* more than two bytes */
7984 else if ( shCount >= 16 ) {
7985 /* lower order two bytes goes to higher order two bytes */
7987 /* if some more remaining */
7989 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7991 movLeft2Result(left, MSB16, result, MSB32);
7992 movLeft2Result(left, LSB, result, MSB24);
7994 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7995 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7999 /* if more than 1 byte */
8000 else if ( shCount >= 8 ) {
8001 /* lower order three bytes goes to higher order three bytes */
8005 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8007 movLeft2Result(left, LSB, result, MSB16);
8009 else{ /* size = 4 */
8011 movLeft2Result(left, MSB24, result, MSB32);
8012 movLeft2Result(left, MSB16, result, MSB24);
8013 movLeft2Result(left, LSB, result, MSB16);
8014 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8016 else if(shCount == 1)
8017 shiftLLong(left, result, MSB16);
8019 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
8020 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
8021 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
8022 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
8027 /* 1 <= shCount <= 7 */
8028 else if(shCount <= 3)
8030 shiftLLong(left, result, LSB);
8031 while(--shCount >= 1)
8032 shiftLLong(result, result, LSB);
8034 /* 3 <= shCount <= 7, optimize */
8036 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
8037 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
8038 shiftL2Left2Result(left, LSB, result, LSB, shCount);
8042 /*-----------------------------------------------------------------*/
8043 /* genLeftShiftLiteral - left shifting by known count */
8044 /*-----------------------------------------------------------------*/
8045 static void genLeftShiftLiteral (operand *left,
8050 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8053 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8054 pic16_freeAsmop(right,NULL,ic,TRUE);
8056 pic16_aopOp(left,ic,FALSE);
8057 pic16_aopOp(result,ic,FALSE);
8059 size = getSize(operandType(result));
8062 pic16_emitcode("; shift left ","result %d, left %d",size,
8066 /* I suppose that the left size >= result size */
8069 movLeft2Result(left, size, result, size);
8073 else if(shCount >= (size * 8))
8075 pic16_aopPut(AOP(result),zero,size);
8079 genlshOne (result,left,shCount);
8084 genlshTwo (result,left,shCount);
8088 genlshFour (result,left,shCount);
8092 pic16_freeAsmop(left,NULL,ic,TRUE);
8093 pic16_freeAsmop(result,NULL,ic,TRUE);
8096 /*-----------------------------------------------------------------*
8097 * genMultiAsm - repeat assembly instruction for size of register.
8098 * if endian == 1, then the high byte (i.e base address + size of
8099 * register) is used first else the low byte is used first;
8100 *-----------------------------------------------------------------*/
8101 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
8106 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8119 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
8124 /*-----------------------------------------------------------------*/
8125 /* genLeftShift - generates code for left shifting */
8126 /*-----------------------------------------------------------------*/
8127 static void genLeftShift (iCode *ic)
8129 operand *left,*right, *result;
8132 symbol *tlbl , *tlbl1;
8135 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8137 right = IC_RIGHT(ic);
8139 result = IC_RESULT(ic);
8141 pic16_aopOp(right,ic,FALSE);
8143 /* if the shift count is known then do it
8144 as efficiently as possible */
8145 if (AOP_TYPE(right) == AOP_LIT) {
8146 genLeftShiftLiteral (left,right,result,ic);
8150 /* shift count is unknown then we have to form
8151 a loop get the loop count in B : Note: we take
8152 only the lower order byte since shifting
8153 more that 32 bits make no sense anyway, ( the
8154 largest size of an object can be only 32 bits ) */
8157 pic16_aopOp(left,ic,FALSE);
8158 pic16_aopOp(result,ic,FALSE);
8160 /* now move the left to the result if they are not the
8162 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8163 AOP_SIZE(result) > 1) {
8165 size = AOP_SIZE(result);
8168 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8169 if (*l == '@' && (IS_AOP_PREG(result))) {
8171 pic16_emitcode("mov","a,%s",l);
8172 pic16_aopPut(AOP(result),"a",offset);
8174 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8175 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8176 //pic16_aopPut(AOP(result),l,offset);
8182 size = AOP_SIZE(result);
8184 /* if it is only one byte then */
8186 if(optimized_for_speed) {
8187 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
8188 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
8189 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
8190 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8191 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8192 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
8193 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8194 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
8195 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
8196 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
8197 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
8198 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
8201 tlbl = newiTempLabel(NULL);
8202 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8203 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8204 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8207 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8208 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8209 pic16_emitpLabel(tlbl->key);
8210 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8211 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8213 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8218 if (pic16_sameRegs(AOP(left),AOP(result))) {
8220 tlbl = newiTempLabel(NULL);
8221 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8222 genMultiAsm(POC_RRCF, result, size,1);
8223 pic16_emitpLabel(tlbl->key);
8224 genMultiAsm(POC_RLCF, result, size,0);
8225 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8227 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8231 //tlbl = newiTempLabel(NULL);
8233 //tlbl1 = newiTempLabel(NULL);
8235 //reAdjustPreg(AOP(result));
8237 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8238 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8239 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8241 //pic16_emitcode("add","a,acc");
8242 //pic16_aopPut(AOP(result),"a",offset++);
8244 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8246 // pic16_emitcode("rlc","a");
8247 // pic16_aopPut(AOP(result),"a",offset++);
8249 //reAdjustPreg(AOP(result));
8251 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8252 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8255 tlbl = newiTempLabel(NULL);
8256 tlbl1= newiTempLabel(NULL);
8258 size = AOP_SIZE(result);
8261 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8263 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8265 /* offset should be 0, 1 or 3 */
8267 pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1));
8269 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8271 pic16_emitpcode(POC_MOVWF, pctemp);
8274 pic16_emitpLabel(tlbl->key);
8277 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8279 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
8281 pic16_emitpcode(POC_DECFSZ, pctemp);
8282 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8283 pic16_emitpLabel(tlbl1->key);
8285 pic16_popReleaseTempReg(pctemp);
8289 pic16_freeAsmop (right,NULL,ic,TRUE);
8290 pic16_freeAsmop(left,NULL,ic,TRUE);
8291 pic16_freeAsmop(result,NULL,ic,TRUE);
8294 /*-----------------------------------------------------------------*/
8295 /* genrshOne - right shift a one byte quantity by known count */
8296 /*-----------------------------------------------------------------*/
8297 static void genrshOne (operand *result, operand *left,
8298 int shCount, int sign)
8300 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8301 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
8304 /*-----------------------------------------------------------------*/
8305 /* genrshTwo - right shift two bytes by known amount != 0 */
8306 /*-----------------------------------------------------------------*/
8307 static void genrshTwo (operand *result,operand *left,
8308 int shCount, int sign)
8310 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount);
8311 /* if shCount >= 8 */
8315 shiftR1Left2Result(left, MSB16, result, LSB,
8318 movLeft2Result(left, MSB16, result, LSB);
8320 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
8323 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
8324 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
8328 /* 1 <= shCount <= 7 */
8330 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
8333 /*-----------------------------------------------------------------*/
8334 /* shiftRLong - shift right one long from left to result */
8335 /* offl = LSB or MSB16 */
8336 /*-----------------------------------------------------------------*/
8337 static void shiftRLong (operand *left, int offl,
8338 operand *result, int sign)
8340 int size = AOP_SIZE(result);
8341 int same = pic16_sameRegs(AOP(left),AOP(result));
8343 DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size);
8345 if (same && (offl == MSB16)) { //shift one byte right
8346 for(i=MSB16;i<size;i++) {
8347 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i));
8348 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i-1));
8353 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(left),MSB32));
8359 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB32));
8361 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB32));
8362 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB32-offl));
8366 /* add sign of "a" */
8367 pic16_addSign(result, MSB32, sign);
8371 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB24));
8373 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB24));
8374 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB24-offl));
8378 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),MSB16));
8380 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),MSB16));
8381 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),MSB16-offl));
8385 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),LSB));
8388 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),LSB));
8389 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),LSB));
8394 /*-----------------------------------------------------------------*/
8395 /* genrshFour - shift four byte by a known amount != 0 */
8396 /*-----------------------------------------------------------------*/
8397 static void genrshFour (operand *result, operand *left,
8398 int shCount, int sign)
8400 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8401 /* if shifting more that 3 bytes */
8402 if(shCount >= 24 ) {
8405 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
8407 movLeft2Result(left, MSB32, result, LSB);
8409 pic16_addSign(result, MSB16, sign);
8411 else if(shCount >= 16){
8414 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
8416 movLeft2Result(left, MSB24, result, LSB);
8417 movLeft2Result(left, MSB32, result, MSB16);
8419 pic16_addSign(result, MSB24, sign);
8421 else if(shCount >= 8){
8424 shiftRLong(left, MSB16, result, sign);
8425 else if(shCount == 0){
8426 movLeft2Result(left, MSB16, result, LSB);
8427 movLeft2Result(left, MSB24, result, MSB16);
8428 movLeft2Result(left, MSB32, result, MSB24);
8429 pic16_addSign(result, MSB32, sign);
8431 else{ //shcount >= 2
8432 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
8433 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
8434 /* the last shift is signed */
8435 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
8436 pic16_addSign(result, MSB32, sign);
8439 else{ /* 1 <= shCount <= 7 */
8441 shiftRLong(left, LSB, result, sign);
8443 shiftRLong(result, LSB, result, sign);
8446 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
8447 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
8448 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
8453 /*-----------------------------------------------------------------*/
8454 /* genRightShiftLiteral - right shifting by known count */
8455 /*-----------------------------------------------------------------*/
8456 static void genRightShiftLiteral (operand *left,
8462 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
8465 pic16_freeAsmop(right,NULL,ic,TRUE);
8467 pic16_aopOp(left,ic,FALSE);
8468 pic16_aopOp(result,ic,FALSE);
8470 DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left));
8473 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
8477 lsize = pic16_getDataSize(left);
8478 res_size = pic16_getDataSize(result);
8479 /* test the LEFT size !!! */
8481 /* I suppose that the left size >= result size */
8484 movLeft2Result(left, lsize, result, res_size);
8487 else if(shCount >= (lsize * 8)){
8490 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
8492 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8493 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
8498 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
8499 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
8500 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
8502 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
8507 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
8514 genrshOne (result,left,shCount,sign);
8518 genrshTwo (result,left,shCount,sign);
8522 genrshFour (result,left,shCount,sign);
8530 pic16_freeAsmop(left,NULL,ic,TRUE);
8531 pic16_freeAsmop(result,NULL,ic,TRUE);
8534 /*-----------------------------------------------------------------*/
8535 /* genSignedRightShift - right shift of signed number */
8536 /*-----------------------------------------------------------------*/
8537 static void genSignedRightShift (iCode *ic)
8539 operand *right, *left, *result;
8542 symbol *tlbl, *tlbl1 ;
8545 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
8547 /* we do it the hard way put the shift count in b
8548 and loop thru preserving the sign */
8549 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8551 right = IC_RIGHT(ic);
8553 result = IC_RESULT(ic);
8555 pic16_aopOp(right,ic,FALSE);
8556 pic16_aopOp(left,ic,FALSE);
8557 pic16_aopOp(result,ic,FALSE);
8560 if ( AOP_TYPE(right) == AOP_LIT) {
8561 genRightShiftLiteral (left,right,result,ic,1);
8564 /* shift count is unknown then we have to form
8565 a loop get the loop count in B : Note: we take
8566 only the lower order byte since shifting
8567 more that 32 bits make no sense anyway, ( the
8568 largest size of an object can be only 32 bits ) */
8570 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8571 //pic16_emitcode("inc","b");
8572 //pic16_freeAsmop (right,NULL,ic,TRUE);
8573 //pic16_aopOp(left,ic,FALSE);
8574 //pic16_aopOp(result,ic,FALSE);
8576 /* now move the left to the result if they are not the
8578 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8579 AOP_SIZE(result) > 1) {
8581 size = AOP_SIZE(result);
8585 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8586 if (*l == '@' && IS_AOP_PREG(result)) {
8588 pic16_emitcode("mov","a,%s",l);
8589 pic16_aopPut(AOP(result),"a",offset);
8591 pic16_aopPut(AOP(result),l,offset);
8593 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
8594 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8600 /* mov the highest order bit to OVR */
8601 tlbl = newiTempLabel(NULL);
8602 tlbl1= newiTempLabel(NULL);
8604 size = AOP_SIZE(result);
8607 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
8609 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8611 /* offset should be 0, 1 or 3 */
8612 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
8614 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
8616 pic16_emitpcode(POC_MOVWF, pctemp);
8619 pic16_emitpLabel(tlbl->key);
8621 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
8622 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
8625 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
8628 pic16_emitpcode(POC_DECFSZ, pctemp);
8629 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8630 pic16_emitpLabel(tlbl1->key);
8632 pic16_popReleaseTempReg(pctemp);
8634 size = AOP_SIZE(result);
8636 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
8637 pic16_emitcode("rlc","a");
8638 pic16_emitcode("mov","ov,c");
8639 /* if it is only one byte then */
8641 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8643 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8644 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8645 pic16_emitcode("mov","c,ov");
8646 pic16_emitcode("rrc","a");
8647 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8648 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8649 pic16_aopPut(AOP(result),"a",0);
8653 reAdjustPreg(AOP(result));
8654 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8655 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8656 pic16_emitcode("mov","c,ov");
8658 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8660 pic16_emitcode("rrc","a");
8661 pic16_aopPut(AOP(result),"a",offset--);
8663 reAdjustPreg(AOP(result));
8664 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8665 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8670 pic16_freeAsmop(left,NULL,ic,TRUE);
8671 pic16_freeAsmop(result,NULL,ic,TRUE);
8672 pic16_freeAsmop(right,NULL,ic,TRUE);
8675 /*-----------------------------------------------------------------*/
8676 /* genRightShift - generate code for right shifting */
8677 /*-----------------------------------------------------------------*/
8678 static void genRightShift (iCode *ic)
8680 operand *right, *left, *result;
8684 symbol *tlbl, *tlbl1 ;
8686 /* if signed then we do it the hard way preserve the
8687 sign bit moving it inwards */
8688 letype = getSpec(operandType(IC_LEFT(ic)));
8689 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8691 if (!SPEC_USIGN(letype)) {
8692 genSignedRightShift (ic);
8696 /* signed & unsigned types are treated the same : i.e. the
8697 signed is NOT propagated inwards : quoting from the
8698 ANSI - standard : "for E1 >> E2, is equivalent to division
8699 by 2**E2 if unsigned or if it has a non-negative value,
8700 otherwise the result is implementation defined ", MY definition
8701 is that the sign does not get propagated */
8703 right = IC_RIGHT(ic);
8705 result = IC_RESULT(ic);
8707 pic16_aopOp(right,ic,FALSE);
8709 /* if the shift count is known then do it
8710 as efficiently as possible */
8711 if (AOP_TYPE(right) == AOP_LIT) {
8712 genRightShiftLiteral (left,right,result,ic, 0);
8716 /* shift count is unknown then we have to form
8717 a loop get the loop count in B : Note: we take
8718 only the lower order byte since shifting
8719 more that 32 bits make no sense anyway, ( the
8720 largest size of an object can be only 32 bits ) */
8722 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
8723 pic16_emitcode("inc","b");
8724 pic16_aopOp(left,ic,FALSE);
8725 pic16_aopOp(result,ic,FALSE);
8727 /* now move the left to the result if they are not the
8729 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
8730 AOP_SIZE(result) > 1) {
8732 size = AOP_SIZE(result);
8735 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
8736 if (*l == '@' && IS_AOP_PREG(result)) {
8738 pic16_emitcode("mov","a,%s",l);
8739 pic16_aopPut(AOP(result),"a",offset);
8741 pic16_aopPut(AOP(result),l,offset);
8746 tlbl = newiTempLabel(NULL);
8747 tlbl1= newiTempLabel(NULL);
8748 size = AOP_SIZE(result);
8751 /* if it is only one byte then */
8754 tlbl = newiTempLabel(NULL);
8755 if (!pic16_sameRegs(AOP(left),AOP(result))) {
8756 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8757 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8760 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
8761 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
8762 pic16_emitpLabel(tlbl->key);
8763 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
8764 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
8766 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
8771 reAdjustPreg(AOP(result));
8772 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
8773 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
8776 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
8778 pic16_emitcode("rrc","a");
8779 pic16_aopPut(AOP(result),"a",offset--);
8781 reAdjustPreg(AOP(result));
8783 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
8784 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
8787 pic16_freeAsmop(left,NULL,ic,TRUE);
8788 pic16_freeAsmop (right,NULL,ic,TRUE);
8789 pic16_freeAsmop(result,NULL,ic,TRUE);
8792 /*-----------------------------------------------------------------*/
8793 /* genUnpackBits - generates code for unpacking bits */
8794 /*-----------------------------------------------------------------*/
8795 static void genUnpackBits (operand *result, char *rname, int ptype)
8802 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8803 etype = getSpec(operandType(result));
8805 /* read the first byte */
8812 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
8815 pic16_emitcode("clr","a");
8816 pic16_emitcode("movc","a","@a+dptr");
8821 /* if we have bitdisplacement then it fits */
8822 /* into this byte completely or if length is */
8823 /* less than a byte */
8824 if ((shCnt = SPEC_BSTR(etype)) ||
8825 (SPEC_BLEN(etype) <= 8)) {
8827 /* shift right acc */
8830 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
8831 (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ]));
8833 /* VR -- normally I would use the following, but since we use the hack,
8834 * to avoid the masking from AccRsh, why not mask it right now? */
8837 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
8840 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
8846 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
8847 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
8850 /* bit field did not fit in a byte */
8851 rlen = SPEC_BLEN(etype) - 8;
8852 pic16_aopPut(AOP(result),"a",offset++);
8859 pic16_emitcode("inc","%s",rname);
8860 pic16_emitcode("mov","a,@%s",rname);
8864 pic16_emitcode("inc","%s",rname);
8865 pic16_emitcode("movx","a,@%s",rname);
8869 pic16_emitcode("inc","dptr");
8870 pic16_emitcode("movx","a,@dptr");
8874 pic16_emitcode("clr","a");
8875 pic16_emitcode("inc","dptr");
8876 pic16_emitcode("movc","a","@a+dptr");
8880 pic16_emitcode("inc","dptr");
8881 pic16_emitcode("lcall","__gptrget");
8886 /* if we are done */
8890 pic16_aopPut(AOP(result),"a",offset++);
8895 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8896 pic16_aopPut(AOP(result),"a",offset);
8903 static void genDataPointerGet(operand *left,
8907 int size, offset = 0, leoffset=0 ;
8909 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8910 pic16_aopOp(result, ic, FALSE);
8912 size = AOP_SIZE(result);
8913 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
8917 /* The following tests may save a redudant movff instruction when
8918 * accessing unions */
8920 /* if they are the same */
8921 if (operandsEqu (left, result)) {
8922 DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
8928 /* if they are the same registers */
8929 if (pic16_sameRegs(AOP(left),AOP(result))) {
8930 DEBUGpic16_emitcode("; ***", "left and result registers are same");
8936 if ( AOP_TYPE(left) == AOP_PCODE) {
8937 fprintf(stderr,"genDataPointerGet %s, %d\n",
8938 AOP(left)->aopu.pcop->name,
8939 (AOP(left)->aopu.pcop->type == PO_DIR)?
8940 PCOR(AOP(left)->aopu.pcop)->instance:
8941 PCOI(AOP(left)->aopu.pcop)->offset);
8945 if(AOP(left)->aopu.pcop->type == PO_DIR)
8946 leoffset=PCOR(AOP(left)->aopu.pcop)->instance;
8948 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8951 DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
8953 if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
8954 || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
8955 mov2w(AOP(left), offset); // patch 8
8956 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
8958 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
8959 pic16_popGet(AOP(left), offset), //patch 8
8960 pic16_popGet(AOP(result), offset)));
8968 pic16_freeAsmop(result,NULL,ic,TRUE);
8971 void pic16_loadFSR0(operand *op)
8973 pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0)));
8977 /*-----------------------------------------------------------------*/
8978 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8979 /*-----------------------------------------------------------------*/
8980 static void genNearPointerGet (operand *left,
8985 //regs *preg = NULL ;
8986 sym_link *rtype, *retype;
8987 sym_link *ltype = operandType(left);
8989 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8990 rtype = operandType(result);
8991 retype= getSpec(rtype);
8993 pic16_aopOp(left,ic,FALSE);
8995 pic16_DumpOp("(left)",left);
8996 pic16_DumpOp("(result)",result);
8998 /* if left is rematerialisable and
8999 * result is not bit variable type and
9000 * the left is pointer to data space i.e
9001 * lower 128 bytes of space */
9002 if (AOP_TYPE(left) == AOP_PCODE
9003 && !IS_BITFIELD(retype)
9004 && DCL_TYPE(ltype) == POINTER) {
9006 genDataPointerGet (left,result,ic);
9007 pic16_freeAsmop(left, NULL, ic, TRUE);
9011 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9013 /* if the value is already in a pointer register
9014 * then don't need anything more */
9015 if (!AOP_INPREG(AOP(left))) {
9016 /* otherwise get a free pointer register */
9017 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9019 /* VR -- the whole concept is to load FSR0 with the address of the symbol */
9020 if( (AOP_TYPE(left) == AOP_PCODE)
9021 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9022 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10
9024 pic16_loadFSR0( left ); // patch 10
9026 // set up FSR0 with address from left
9027 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9028 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9032 // rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9034 pic16_aopOp (result,ic,FALSE);
9036 /* if bitfield then unpack the bits */
9037 if (IS_BITFIELD(retype))
9038 genUnpackBits (result, NULL, POINTER);
9040 /* we have can just get the values */
9041 int size = AOP_SIZE(result);
9044 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9047 /* fsr0 is loaded already -- VR */
9048 // pic16_loadFSR0( left );
9050 // pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
9051 // pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9055 pic16_emitpcode(POC_MOVFF,
9056 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0),
9057 pic16_popGet(AOP(result), offset++)));
9059 pic16_emitpcode(POC_MOVFF,
9060 pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0),
9061 pic16_popGet(AOP(result), offset++)));
9065 // pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0));
9066 // pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
9068 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9072 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
9074 pic16_emitcode("mov","a,@%s",rname);
9075 pic16_aopPut(AOP(result),"a",offset);
9077 sprintf(buffer,"@%s",rname);
9078 pic16_aopPut(AOP(result),buffer,offset);
9082 pic16_emitcode("inc","%s",rname);
9087 /* now some housekeeping stuff */
9089 /* we had to allocate for this iCode */
9090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9091 pic16_freeAsmop(NULL,aop,ic,TRUE);
9093 /* we did not allocate which means left
9094 already in a pointer register, then
9095 if size > 0 && this could be used again
9096 we have to point it back to where it
9098 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9099 if (AOP_SIZE(result) > 1 &&
9100 !OP_SYMBOL(left)->remat &&
9101 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9103 // int size = AOP_SIZE(result) - 1;
9105 // pic16_emitcode("dec","%s",rname);
9110 pic16_freeAsmop(left,NULL,ic,TRUE);
9111 pic16_freeAsmop(result,NULL,ic,TRUE);
9115 /*-----------------------------------------------------------------*/
9116 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
9117 /*-----------------------------------------------------------------*/
9118 static void genPagedPointerGet (operand *left,
9125 sym_link *rtype, *retype;
9127 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9129 rtype = operandType(result);
9130 retype= getSpec(rtype);
9132 pic16_aopOp(left,ic,FALSE);
9134 /* if the value is already in a pointer register
9135 then don't need anything more */
9136 if (!AOP_INPREG(AOP(left))) {
9137 /* otherwise get a free pointer register */
9139 preg = getFreePtr(ic,&aop,FALSE);
9140 pic16_emitcode("mov","%s,%s",
9142 pic16_aopGet(AOP(left),0,FALSE,TRUE));
9143 rname = preg->name ;
9145 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
9147 pic16_freeAsmop(left,NULL,ic,TRUE);
9148 pic16_aopOp (result,ic,FALSE);
9150 /* if bitfield then unpack the bits */
9151 if (IS_BITFIELD(retype))
9152 genUnpackBits (result,rname,PPOINTER);
9154 /* we have can just get the values */
9155 int size = AOP_SIZE(result);
9160 pic16_emitcode("movx","a,@%s",rname);
9161 pic16_aopPut(AOP(result),"a",offset);
9166 pic16_emitcode("inc","%s",rname);
9170 /* now some housekeeping stuff */
9172 /* we had to allocate for this iCode */
9173 pic16_freeAsmop(NULL,aop,ic,TRUE);
9175 /* we did not allocate which means left
9176 already in a pointer register, then
9177 if size > 0 && this could be used again
9178 we have to point it back to where it
9180 if (AOP_SIZE(result) > 1 &&
9181 !OP_SYMBOL(left)->remat &&
9182 ( OP_SYMBOL(left)->liveTo > ic->seq ||
9184 int size = AOP_SIZE(result) - 1;
9186 pic16_emitcode("dec","%s",rname);
9191 pic16_freeAsmop(result,NULL,ic,TRUE);
9196 /*-----------------------------------------------------------------*/
9197 /* genFarPointerGet - gget value from far space */
9198 /*-----------------------------------------------------------------*/
9199 static void genFarPointerGet (operand *left,
9200 operand *result, iCode *ic)
9203 sym_link *retype = getSpec(operandType(result));
9205 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9207 pic16_aopOp(left,ic,FALSE);
9209 /* if the operand is already in dptr
9210 then we do nothing else we move the value to dptr */
9211 if (AOP_TYPE(left) != AOP_STR) {
9212 /* if this is remateriazable */
9213 if (AOP_TYPE(left) == AOP_IMMD)
9214 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9215 else { /* we need to get it byte by byte */
9216 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9217 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9218 if (options.model == MODEL_FLAT24)
9220 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9224 /* so dptr know contains the address */
9225 pic16_freeAsmop(left,NULL,ic,TRUE);
9226 pic16_aopOp(result,ic,FALSE);
9228 /* if bit then unpack */
9229 if (IS_BITFIELD(retype))
9230 genUnpackBits(result,"dptr",FPOINTER);
9232 size = AOP_SIZE(result);
9236 pic16_emitcode("movx","a,@dptr");
9237 pic16_aopPut(AOP(result),"a",offset++);
9239 pic16_emitcode("inc","dptr");
9243 pic16_freeAsmop(result,NULL,ic,TRUE);
9246 /*-----------------------------------------------------------------*/
9247 /* genCodePointerGet - get value from code space */
9248 /*-----------------------------------------------------------------*/
9249 static void genCodePointerGet (operand *left,
9250 operand *result, iCode *ic)
9253 sym_link *retype = getSpec(operandType(result));
9255 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9257 pic16_aopOp(left,ic,FALSE);
9259 /* if the operand is already in dptr
9260 then we do nothing else we move the value to dptr */
9261 if (AOP_TYPE(left) != AOP_STR) {
9262 /* if this is remateriazable */
9263 if (AOP_TYPE(left) == AOP_IMMD)
9264 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
9265 else { /* we need to get it byte by byte */
9266 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
9267 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
9268 if (options.model == MODEL_FLAT24)
9270 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
9274 /* so dptr know contains the address */
9275 pic16_freeAsmop(left,NULL,ic,TRUE);
9276 pic16_aopOp(result,ic,FALSE);
9278 /* if bit then unpack */
9279 if (IS_BITFIELD(retype))
9280 genUnpackBits(result,"dptr",CPOINTER);
9282 size = AOP_SIZE(result);
9286 pic16_emitcode("clr","a");
9287 pic16_emitcode("movc","a,@a+dptr");
9288 pic16_aopPut(AOP(result),"a",offset++);
9290 pic16_emitcode("inc","dptr");
9294 pic16_freeAsmop(result,NULL,ic,TRUE);
9297 /*-----------------------------------------------------------------*/
9298 /* genGenPointerGet - gget value from generic pointer space */
9299 /*-----------------------------------------------------------------*/
9300 static void genGenPointerGet (operand *left,
9301 operand *result, iCode *ic)
9303 int size, offset, lit;
9304 sym_link *retype = getSpec(operandType(result));
9306 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9307 pic16_aopOp(left,ic,FALSE);
9308 pic16_aopOp(result,ic,FALSE);
9309 size = AOP_SIZE(result);
9311 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9313 if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!)
9315 lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit);
9316 // load FSR0 from immediate
9317 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
9319 // pic16_loadFSR0( left );
9324 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9326 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9333 else { /* we need to get it byte by byte */
9334 // set up FSR0 with address from left
9335 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
9336 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
9342 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset)));
9344 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset)));
9351 /* if bit then unpack */
9352 if (IS_BITFIELD(retype))
9353 genUnpackBits(result,"BAD",GPOINTER);
9356 pic16_freeAsmop(left,NULL,ic,TRUE);
9357 pic16_freeAsmop(result,NULL,ic,TRUE);
9361 /*-----------------------------------------------------------------*/
9362 /* genConstPointerGet - get value from const generic pointer space */
9363 /*-----------------------------------------------------------------*/
9364 static void genConstPointerGet (operand *left,
9365 operand *result, iCode *ic)
9367 //sym_link *retype = getSpec(operandType(result));
9368 // symbol *albl = newiTempLabel(NULL); // patch 15
9369 // symbol *blbl = newiTempLabel(NULL); //
9370 // PIC_OPCODE poc; // patch 15
9374 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9375 pic16_aopOp(left,ic,FALSE);
9376 pic16_aopOp(result,ic,TRUE);
9377 size = AOP_SIZE(result);
9379 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
9381 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
9383 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
9384 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
9385 pic16_emitpLabel(albl->key);
9387 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
9389 /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
9390 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
9391 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
9392 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
9393 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
9395 pic16_emitpLabel(blbl->key);
9397 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
9401 // set up table pointer
9402 if( (AOP_TYPE(left) == AOP_PCODE)
9403 && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE)
9404 || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ......
9406 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
9407 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
9408 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1));
9409 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh));
9410 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2));
9411 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
9415 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl)));
9416 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh)));
9417 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru)));
9423 pic16_emitpcodeNULLop(POC_TBLRD_POSTINC);
9424 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset)));
9428 pic16_freeAsmop(left,NULL,ic,TRUE);
9429 pic16_freeAsmop(result,NULL,ic,TRUE);
9432 /*-----------------------------------------------------------------*/
9433 /* genPointerGet - generate code for pointer get */
9434 /*-----------------------------------------------------------------*/
9435 static void genPointerGet (iCode *ic)
9437 operand *left, *result ;
9438 sym_link *type, *etype;
9441 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9444 result = IC_RESULT(ic) ;
9446 /* depending on the type of pointer we need to
9447 move it to the correct pointer register */
9448 type = operandType(left);
9449 etype = getSpec(type);
9452 if (IS_PTR_CONST(type))
9454 if (IS_CODEPTR(type))
9456 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
9458 /* if left is of type of pointer then it is simple */
9459 if (IS_PTR(type) && !IS_FUNC(type->next))
9460 p_type = DCL_TYPE(type);
9462 /* we have to go by the storage class */
9463 p_type = PTR_TYPE(SPEC_OCLS(etype));
9465 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
9467 if (SPEC_OCLS(etype)->codesp ) {
9468 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
9469 //p_type = CPOINTER ;
9472 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
9473 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
9474 /*p_type = FPOINTER ;*/
9476 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
9477 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
9478 /* p_type = PPOINTER; */
9480 if (SPEC_OCLS(etype) == idata )
9481 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
9482 /* p_type = IPOINTER; */
9484 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
9485 /* p_type = POINTER ; */
9488 /* now that we have the pointer type we assign
9489 the pointer values */
9494 genNearPointerGet (left,result,ic);
9498 genPagedPointerGet(left,result,ic);
9502 genFarPointerGet (left,result,ic);
9506 genConstPointerGet (left,result,ic);
9507 //pic16_emitcodePointerGet (left,result,ic);
9512 if (IS_PTR_CONST(type))
9513 genConstPointerGet (left,result,ic);
9516 genGenPointerGet (left,result,ic);
9522 /*-----------------------------------------------------------------*/
9523 /* genPackBits - generates code for packed bit storage */
9524 /*-----------------------------------------------------------------*/
9525 static void genPackBits (sym_link *etype ,
9527 char *rname, int p_type)
9535 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9536 blen = SPEC_BLEN(etype);
9537 bstr = SPEC_BSTR(etype);
9539 if(AOP_TYPE(right) == AOP_LIT) {
9540 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0));
9543 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++));
9545 /* l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9548 /* if the bit lenth is less than or */
9549 /* it exactly fits a byte then */
9550 if((shCnt=SPEC_BSTR(etype))
9551 || SPEC_BLEN(etype) <= 8 ) {
9553 /* shift left acc */
9556 /* using PRODL as a temporary register here */
9557 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl));
9563 pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0));
9564 // pic16_emitcode ("mov","b,a");
9565 // pic16_emitcode("mov","a,@%s",rname);
9569 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(
9570 (unsigned char)((unsigned char)(0xff << (blen+bstr)) |
9571 (unsigned char)(0xff >> (8-bstr))) ));
9572 pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl));
9573 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
9577 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
9578 ((unsigned char)(0xFF << (blen+bstr)) |
9579 (unsigned char)(0xFF >> (8-bstr)) ) );
9580 pic16_emitcode ("orl","a,b");
9581 if (p_type == GPOINTER)
9582 pic16_emitcode("pop","b");
9587 pic16_emitcode("mov","@%s,a",rname);
9590 pic16_emitcode("movx","@dptr,a");
9593 DEBUGpic16_emitcode(";lcall","__gptrput");
9602 fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n");
9603 fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n");
9608 if ( SPEC_BLEN(etype) <= 8 )
9611 pic16_emitcode("inc","%s",rname);
9612 rLen = SPEC_BLEN(etype) ;
9616 /* now generate for lengths greater than one byte */
9619 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
9629 pic16_emitcode("mov","@%s,a",rname);
9631 pic16_emitcode("mov","@%s,%s",rname,l);
9636 pic16_emitcode("movx","@dptr,a");
9641 DEBUGpic16_emitcode(";lcall","__gptrput");
9644 pic16_emitcode ("inc","%s",rname);
9649 /* last last was not complete */
9651 /* save the byte & read byte */
9654 pic16_emitcode ("mov","b,a");
9655 pic16_emitcode("mov","a,@%s",rname);
9659 pic16_emitcode ("mov","b,a");
9660 pic16_emitcode("movx","a,@dptr");
9664 pic16_emitcode ("push","b");
9665 pic16_emitcode ("push","acc");
9666 pic16_emitcode ("lcall","__gptrget");
9667 pic16_emitcode ("pop","b");
9671 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
9672 pic16_emitcode ("orl","a,b");
9675 if (p_type == GPOINTER)
9676 pic16_emitcode("pop","b");
9681 pic16_emitcode("mov","@%s,a",rname);
9685 pic16_emitcode("movx","@dptr,a");
9689 DEBUGpic16_emitcode(";lcall","__gptrput");
9693 /*-----------------------------------------------------------------*/
9694 /* genDataPointerSet - remat pointer to data space */
9695 /*-----------------------------------------------------------------*/
9696 static void genDataPointerSet(operand *right,
9700 int size, offset = 0, resoffset=0 ;
9702 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9703 pic16_aopOp(right,ic,FALSE);
9705 size = AOP_SIZE(right);
9707 // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
9710 if ( AOP_TYPE(result) == AOP_PCODE) {
9711 fprintf(stderr,"genDataPointerSet %s, %d\n",
9712 AOP(result)->aopu.pcop->name,
9713 (AOP(result)->aopu.pcop->type == PO_DIR)?
9714 PCOR(AOP(result)->aopu.pcop)->instance:
9715 PCOI(AOP(result)->aopu.pcop)->offset);
9719 if(AOP(result)->aopu.pcop->type == PO_DIR)
9720 resoffset=PCOR(AOP(result)->aopu.pcop)->instance;
9723 if (AOP_TYPE(right) == AOP_LIT) {
9724 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
9726 lit = lit >> (8*offset);
9728 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
9729 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8
9731 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8
9734 mov2w(AOP(right), offset);
9735 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8
9741 pic16_freeAsmop(right,NULL,ic,TRUE);
9746 /*-----------------------------------------------------------------*/
9747 /* genNearPointerSet - pic16_emitcode for near pointer put */
9748 /*-----------------------------------------------------------------*/
9749 static void genNearPointerSet (operand *right,
9756 sym_link *ptype = operandType(result);
9759 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9760 retype= getSpec(operandType(right));
9761 resetype = getSpec(operandType(result));
9763 pic16_aopOp(result,ic,FALSE);
9765 /* if the result is rematerializable &
9766 * in data space & not a bit variable */
9768 /* and result is not a bit variable */
9769 if (AOP_TYPE(result) == AOP_PCODE
9770 // && AOP_TYPE(result) == AOP_IMMD
9771 && DCL_TYPE(ptype) == POINTER
9772 && !IS_BITFIELD(retype)
9773 && !IS_BITFIELD(resetype)) {
9775 genDataPointerSet (right,result,ic);
9776 pic16_freeAsmop(result,NULL,ic,TRUE);
9780 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9781 pic16_aopOp(right,ic,FALSE);
9782 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9784 /* if the value is already in a pointer register
9785 * then don't need anything more */
9786 if (!AOP_INPREG(AOP(result))) {
9787 /* otherwise get a free pointer register */
9788 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9790 if( (AOP_TYPE(result) == AOP_PCODE)
9791 && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE)
9792 || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10
9794 pic16_loadFSR0( result ); // patch 10
9796 // set up FSR0 with address of result
9797 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10
9798 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10
9803 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9805 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9807 /* if bitfield then unpack the bits */
9808 if (IS_BITFIELD(resetype)) {
9809 genPackBits (resetype, right, NULL, POINTER);
9811 /* we have can just get the values */
9812 int size = AOP_SIZE(right);
9815 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9817 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9820 //pic16_emitcode("mov","@%s,a",rname);
9821 pic16_emitcode("movf","indf0,w ;1");
9824 if (AOP_TYPE(right) == AOP_LIT) { // patch 10
9825 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); //
9827 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); //
9829 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); //
9831 } else { // no literal //
9833 pic16_emitpcode(POC_MOVFF, //
9834 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
9835 pic16_popCopyReg(&pic16_pc_postinc0))); //
9837 pic16_emitpcode(POC_MOVFF, //
9838 pic16_popGet2p(pic16_popGet(AOP(right),offset), //
9839 pic16_popCopyReg(&pic16_pc_indf0))); //
9847 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9848 /* now some housekeeping stuff */
9850 /* we had to allocate for this iCode */
9851 pic16_freeAsmop(NULL,aop,ic,TRUE);
9853 /* we did not allocate which means left
9854 * already in a pointer register, then
9855 * if size > 0 && this could be used again
9856 * we have to point it back to where it
9858 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9859 if (AOP_SIZE(right) > 1
9860 && !OP_SYMBOL(result)->remat
9861 && ( OP_SYMBOL(result)->liveTo > ic->seq
9864 int size = AOP_SIZE(right) - 1;
9867 pic16_emitcode("decf","fsr0,f");
9868 //pic16_emitcode("dec","%s",rname);
9872 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9875 pic16_freeAsmop(right,NULL,ic,TRUE);
9876 pic16_freeAsmop(result,NULL,ic,TRUE);
9879 /*-----------------------------------------------------------------*/
9880 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
9881 /*-----------------------------------------------------------------*/
9882 static void genPagedPointerSet (operand *right,
9891 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9893 retype= getSpec(operandType(right));
9895 pic16_aopOp(result,ic,FALSE);
9897 /* if the value is already in a pointer register
9898 then don't need anything more */
9899 if (!AOP_INPREG(AOP(result))) {
9900 /* otherwise get a free pointer register */
9902 preg = getFreePtr(ic,&aop,FALSE);
9903 pic16_emitcode("mov","%s,%s",
9905 pic16_aopGet(AOP(result),0,FALSE,TRUE));
9906 rname = preg->name ;
9908 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9910 pic16_freeAsmop(result,NULL,ic,TRUE);
9911 pic16_aopOp (right,ic,FALSE);
9913 /* if bitfield then unpack the bits */
9914 if (IS_BITFIELD(retype))
9915 genPackBits (retype,right,rname,PPOINTER);
9917 /* we have can just get the values */
9918 int size = AOP_SIZE(right);
9922 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9925 pic16_emitcode("movx","@%s,a",rname);
9928 pic16_emitcode("inc","%s",rname);
9934 /* now some housekeeping stuff */
9936 /* we had to allocate for this iCode */
9937 pic16_freeAsmop(NULL,aop,ic,TRUE);
9939 /* we did not allocate which means left
9940 already in a pointer register, then
9941 if size > 0 && this could be used again
9942 we have to point it back to where it
9944 if (AOP_SIZE(right) > 1 &&
9945 !OP_SYMBOL(result)->remat &&
9946 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9948 int size = AOP_SIZE(right) - 1;
9950 pic16_emitcode("dec","%s",rname);
9955 pic16_freeAsmop(right,NULL,ic,TRUE);
9960 /*-----------------------------------------------------------------*/
9961 /* genFarPointerSet - set value from far space */
9962 /*-----------------------------------------------------------------*/
9963 static void genFarPointerSet (operand *right,
9964 operand *result, iCode *ic)
9967 sym_link *retype = getSpec(operandType(right));
9969 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9970 pic16_aopOp(result,ic,FALSE);
9972 /* if the operand is already in dptr
9973 then we do nothing else we move the value to dptr */
9974 if (AOP_TYPE(result) != AOP_STR) {
9975 /* if this is remateriazable */
9976 if (AOP_TYPE(result) == AOP_IMMD)
9977 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9978 else { /* we need to get it byte by byte */
9979 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9980 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9981 if (options.model == MODEL_FLAT24)
9983 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9987 /* so dptr know contains the address */
9988 pic16_freeAsmop(result,NULL,ic,TRUE);
9989 pic16_aopOp(right,ic,FALSE);
9991 /* if bit then unpack */
9992 if (IS_BITFIELD(retype))
9993 genPackBits(retype,right,"dptr",FPOINTER);
9995 size = AOP_SIZE(right);
9999 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10001 pic16_emitcode("movx","@dptr,a");
10003 pic16_emitcode("inc","dptr");
10007 pic16_freeAsmop(right,NULL,ic,TRUE);
10010 /*-----------------------------------------------------------------*/
10011 /* genGenPointerSet - set value from generic pointer space */
10012 /*-----------------------------------------------------------------*/
10013 static void genGenPointerSet (operand *right,
10014 operand *result, iCode *ic)
10016 int i, size, offset, lit;
10017 sym_link *retype = getSpec(operandType(right));
10019 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10021 pic16_aopOp(result,ic,FALSE);
10022 pic16_aopOp(right,ic,FALSE);
10023 size = AOP_SIZE(right);
10026 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10028 /* if the operand is already in dptr
10029 then we do nothing else we move the value to dptr */
10030 if (AOP_TYPE(result) != AOP_STR) {
10031 /* if this is remateriazable */
10032 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10033 // WARNING: anythig until "else" is untested!
10034 if (AOP_TYPE(result) == AOP_IMMD) {
10035 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10036 lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit);
10037 // load FSR0 from immediate
10038 pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit)));
10042 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10044 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10050 else { /* we need to get it byte by byte */
10051 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10052 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
10054 // set up FSR0 with address of result
10055 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10056 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10058 /* hack hack! see if this the FSR. If so don't load W */
10059 if(AOP_TYPE(right) != AOP_ACC) {
10061 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10063 if(AOP_TYPE(right) == AOP_LIT)
10066 // note: pic16_popGet handles sign extension
10067 for(i=0;i<size;i++) {
10068 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),i));
10070 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0));
10072 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
10077 for(i=0;i<size;i++) {
10079 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10080 pic16_popCopyReg(&pic16_pc_postinc0)));
10082 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),i),
10083 pic16_popCopyReg(&pic16_pc_indf0)));
10089 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10090 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10092 } // if (AOP_TYPE(result) != AOP_IMMD)
10094 } // if (AOP_TYPE(result) != AOP_STR)
10095 /* so dptr know contains the address */
10098 /* if bit then unpack */
10099 if (IS_BITFIELD(retype))
10100 genPackBits(retype,right,"dptr",GPOINTER);
10102 size = AOP_SIZE(right);
10105 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
10107 // set up FSR0 with address of result
10108 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l)));
10109 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h)));
10112 if (AOP_TYPE(right) == AOP_LIT) {
10113 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10115 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0));
10117 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
10119 } else { // no literal
10121 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0)));
10123 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0)));
10131 pic16_freeAsmop(right,NULL,ic,TRUE);
10132 pic16_freeAsmop(result,NULL,ic,TRUE);
10135 /*-----------------------------------------------------------------*/
10136 /* genPointerSet - stores the value into a pointer location */
10137 /*-----------------------------------------------------------------*/
10138 static void genPointerSet (iCode *ic)
10140 operand *right, *result ;
10141 sym_link *type, *etype;
10144 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10146 right = IC_RIGHT(ic);
10147 result = IC_RESULT(ic) ;
10149 /* depending on the type of pointer we need to
10150 move it to the correct pointer register */
10151 type = operandType(result);
10152 etype = getSpec(type);
10153 /* if left is of type of pointer then it is simple */
10154 if (IS_PTR(type) && !IS_FUNC(type->next)) {
10155 p_type = DCL_TYPE(type);
10158 /* we have to go by the storage class */
10159 p_type = PTR_TYPE(SPEC_OCLS(etype));
10161 /* if (SPEC_OCLS(etype)->codesp ) { */
10162 /* p_type = CPOINTER ; */
10165 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10166 /* p_type = FPOINTER ; */
10168 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10169 /* p_type = PPOINTER ; */
10171 /* if (SPEC_OCLS(etype) == idata ) */
10172 /* p_type = IPOINTER ; */
10174 /* p_type = POINTER ; */
10177 /* now that we have the pointer type we assign
10178 the pointer values */
10183 genNearPointerSet (right,result,ic);
10187 genPagedPointerSet (right,result,ic);
10191 genFarPointerSet (right,result,ic);
10195 genGenPointerSet (right,result,ic);
10199 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
10200 "genPointerSet: illegal pointer type");
10204 /*-----------------------------------------------------------------*/
10205 /* genIfx - generate code for Ifx statement */
10206 /*-----------------------------------------------------------------*/
10207 static void genIfx (iCode *ic, iCode *popIc)
10209 operand *cond = IC_COND(ic);
10212 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10214 pic16_aopOp(cond,ic,FALSE);
10216 /* get the value into acc */
10217 if (AOP_TYPE(cond) != AOP_CRY)
10218 pic16_toBoolean(cond);
10221 /* the result is now in the accumulator */
10222 pic16_freeAsmop(cond,NULL,ic,TRUE);
10224 /* if there was something to be popped then do it */
10228 /* if the condition is a bit variable */
10229 if (isbit && IS_ITEMP(cond) &&
10231 genIfxJump(ic,SPIL_LOC(cond)->rname);
10232 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
10235 if (isbit && !IS_ITEMP(cond))
10236 genIfxJump(ic,OP_SYMBOL(cond)->rname);
10238 genIfxJump(ic,"a");
10244 /*-----------------------------------------------------------------*/
10245 /* genAddrOf - generates code for address of */
10246 /*-----------------------------------------------------------------*/
10247 static void genAddrOf (iCode *ic)
10249 operand *result, *left;
10251 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
10252 pCodeOp *pcop0, *pcop1, *pcop2;
10254 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10256 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
10257 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
10259 sym = OP_SYMBOL( left );
10261 size = AOP_SIZE(IC_RESULT(ic));
10263 if(pic16_debug_verbose) {
10264 fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
10265 __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
10268 /* Assume that what we want the address of is in data space
10269 * since there is no stack on the PIC, yet! -- VR */
10271 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10274 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10277 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10281 pic16_emitpcode(POC_MOVLW, pcop0);
10282 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10283 pic16_emitpcode(POC_MOVLW, pcop1);
10284 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10285 pic16_emitpcode(POC_MOVLW, pcop2);
10286 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10289 pic16_emitpcode(POC_MOVLW, pcop0);
10290 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10291 pic16_emitpcode(POC_MOVLW, pcop1);
10292 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10294 pic16_emitpcode(POC_MOVLW, pcop0);
10295 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10298 pic16_freeAsmop(result,NULL,ic,TRUE);
10299 pic16_freeAsmop(left, NULL, ic, FALSE);
10304 /*-----------------------------------------------------------------*/
10305 /* genFarFarAssign - assignment when both are in far space */
10306 /*-----------------------------------------------------------------*/
10307 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
10309 int size = AOP_SIZE(right);
10312 /* first push the right side on to the stack */
10314 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
10316 pic16_emitcode ("push","acc");
10319 pic16_freeAsmop(right,NULL,ic,FALSE);
10320 /* now assign DPTR to result */
10321 pic16_aopOp(result,ic,FALSE);
10322 size = AOP_SIZE(result);
10324 pic16_emitcode ("pop","acc");
10325 pic16_aopPut(AOP(result),"a",--offset);
10327 pic16_freeAsmop(result,NULL,ic,FALSE);
10332 /*-----------------------------------------------------------------*/
10333 /* genAssign - generate code for assignment */
10334 /*-----------------------------------------------------------------*/
10335 static void genAssign (iCode *ic)
10337 operand *result, *right;
10338 int size, offset,know_W;
10339 unsigned long lit = 0L;
10341 result = IC_RESULT(ic);
10342 right = IC_RIGHT(ic) ;
10344 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10346 /* if they are the same */
10347 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
10350 pic16_aopOp(right,ic,FALSE);
10351 pic16_aopOp(result,ic,TRUE);
10353 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10355 /* if they are the same registers */
10356 if (pic16_sameRegs(AOP(right),AOP(result)))
10359 /* if the result is a bit */
10360 if (AOP_TYPE(result) == AOP_CRY) {
10361 /* if the right size is a literal then
10362 we know what the value is */
10363 if (AOP_TYPE(right) == AOP_LIT) {
10365 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10366 pic16_popGet(AOP(result),0));
10368 if (((int) operandLitValue(right)))
10369 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10370 AOP(result)->aopu.aop_dir,
10371 AOP(result)->aopu.aop_dir);
10373 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10374 AOP(result)->aopu.aop_dir,
10375 AOP(result)->aopu.aop_dir);
10379 /* the right is also a bit variable */
10380 if (AOP_TYPE(right) == AOP_CRY) {
10381 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10382 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10383 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10385 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
10386 AOP(result)->aopu.aop_dir,
10387 AOP(result)->aopu.aop_dir);
10388 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
10389 AOP(right)->aopu.aop_dir,
10390 AOP(right)->aopu.aop_dir);
10391 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
10392 AOP(result)->aopu.aop_dir,
10393 AOP(result)->aopu.aop_dir);
10397 /* we need to or */
10398 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10399 pic16_toBoolean(right);
10401 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10402 //pic16_aopPut(AOP(result),"a",0);
10406 /* bit variables done */
10408 size = AOP_SIZE(result);
10410 if(AOP_TYPE(right) == AOP_LIT)
10411 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
10413 /* VR - What is this?! */
10414 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
10415 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10416 if(aopIdx(AOP(result),0) == 4) {
10417 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10418 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10419 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10422 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
10427 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10428 if(AOP_TYPE(right) == AOP_LIT) {
10430 if(know_W != (lit&0xff))
10431 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
10433 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10435 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10439 } else if (AOP_TYPE(right) == AOP_CRY) {
10440 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10442 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
10443 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10445 } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) {
10446 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10447 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10449 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10452 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
10453 normally should work, but mind that the W register live range
10454 is not checked, so if the code generator assumes that the W
10455 is already loaded after such a pair, wrong code will be generated.
10457 Checking the live range is the next step.
10458 This is experimental code yet and has not been fully tested yet.
10459 USE WITH CARE. Revert to old code by setting 0 to the condition above.
10460 Vangelis Rokas 030603 (vrokas@otenet.gr) */
10462 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
10464 /* This is the old code, which is assumed(?!) that works fine(!?) */
10466 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10467 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10476 pic16_freeAsmop (right,NULL,ic,FALSE);
10477 pic16_freeAsmop (result,NULL,ic,TRUE);
10480 /*-----------------------------------------------------------------*/
10481 /* genJumpTab - generates code for jump table */
10482 /*-----------------------------------------------------------------*/
10483 static void genJumpTab (iCode *ic)
10488 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10490 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
10491 /* get the condition into accumulator */
10492 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
10494 /* multiply by three */
10495 pic16_emitcode("add","a,acc");
10496 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
10498 jtab = newiTempLabel(NULL);
10499 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
10500 pic16_emitcode("jmp","@a+dptr");
10501 pic16_emitcode("","%05d_DS_:",jtab->key+100);
10503 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
10504 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
10506 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
10507 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
10508 pic16_emitpLabel(jtab->key);
10510 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
10512 /* now generate the jump labels */
10513 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
10514 jtab = setNextItem(IC_JTLABELS(ic))) {
10515 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
10516 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
10522 /*-----------------------------------------------------------------*/
10523 /* genMixedOperation - gen code for operators between mixed types */
10524 /*-----------------------------------------------------------------*/
10526 TSD - Written for the PIC port - but this unfortunately is buggy.
10527 This routine is good in that it is able to efficiently promote
10528 types to different (larger) sizes. Unfortunately, the temporary
10529 variables that are optimized out by this routine are sometimes
10530 used in other places. So until I know how to really parse the
10531 iCode tree, I'm going to not be using this routine :(.
10533 static int genMixedOperation (iCode *ic)
10536 operand *result = IC_RESULT(ic);
10537 sym_link *ctype = operandType(IC_LEFT(ic));
10538 operand *right = IC_RIGHT(ic);
10544 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
10546 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10552 nextright = IC_RIGHT(nextic);
10553 nextleft = IC_LEFT(nextic);
10554 nextresult = IC_RESULT(nextic);
10556 pic16_aopOp(right,ic,FALSE);
10557 pic16_aopOp(result,ic,FALSE);
10558 pic16_aopOp(nextright, nextic, FALSE);
10559 pic16_aopOp(nextleft, nextic, FALSE);
10560 pic16_aopOp(nextresult, nextic, FALSE);
10562 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
10564 operand *t = right;
10568 pic16_emitcode(";remove right +","");
10570 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
10572 operand *t = right;
10576 pic16_emitcode(";remove left +","");
10580 big = AOP_SIZE(nextleft);
10581 small = AOP_SIZE(nextright);
10583 switch(nextic->op) {
10586 pic16_emitcode(";optimize a +","");
10587 /* if unsigned or not an integral type */
10588 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
10589 pic16_emitcode(";add a bit to something","");
10592 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
10594 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
10595 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
10596 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
10598 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
10606 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10607 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10608 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10611 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10613 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10614 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
10615 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
10616 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10617 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
10620 pic16_emitcode("rlf","known_zero,w");
10627 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
10628 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
10629 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10631 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
10641 pic16_freeAsmop(right,NULL,ic,TRUE);
10642 pic16_freeAsmop(result,NULL,ic,TRUE);
10643 pic16_freeAsmop(nextright,NULL,ic,TRUE);
10644 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
10646 nextic->generated = 1;
10653 /*-----------------------------------------------------------------*/
10654 /* genCast - gen code for casting */
10655 /*-----------------------------------------------------------------*/
10656 static void genCast (iCode *ic)
10658 operand *result = IC_RESULT(ic);
10659 sym_link *ctype = operandType(IC_LEFT(ic));
10660 sym_link *rtype = operandType(IC_RIGHT(ic));
10661 operand *right = IC_RIGHT(ic);
10664 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10665 /* if they are equivalent then do nothing */
10666 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
10669 pic16_aopOp(right,ic,FALSE) ;
10670 pic16_aopOp(result,ic,FALSE);
10672 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
10674 /* if the result is a bit */
10675 if (AOP_TYPE(result) == AOP_CRY) {
10677 /* if the right size is a literal then
10678 * we know what the value is */
10679 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10681 if (AOP_TYPE(right) == AOP_LIT) {
10682 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
10683 pic16_popGet(AOP(result),0));
10685 if (((int) operandLitValue(right)))
10686 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
10687 AOP(result)->aopu.aop_dir,
10688 AOP(result)->aopu.aop_dir);
10690 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
10691 AOP(result)->aopu.aop_dir,
10692 AOP(result)->aopu.aop_dir);
10696 /* the right is also a bit variable */
10697 if (AOP_TYPE(right) == AOP_CRY) {
10699 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10701 pic16_emitcode("clrc","");
10702 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
10703 AOP(right)->aopu.aop_dir,
10704 AOP(right)->aopu.aop_dir);
10705 pic16_aopPut(AOP(result),"c",0);
10709 /* we need to or */
10710 if (AOP_TYPE(right) == AOP_REG) {
10711 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
10712 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
10713 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
10715 pic16_toBoolean(right);
10716 pic16_aopPut(AOP(result),"a",0);
10720 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
10723 size = AOP_SIZE(result);
10725 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10727 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
10728 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
10729 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
10732 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10737 /* if they are the same size : or less */
10738 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
10740 /* if they are in the same place */
10741 if (pic16_sameRegs(AOP(right),AOP(result)))
10744 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10746 if (IS_PTR_CONST(rtype))
10748 if (IS_CODEPTR(rtype))
10750 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
10753 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
10755 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
10757 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
10760 if(AOP_TYPE(right) == AOP_IMMD) {
10761 pCodeOp *pcop0, *pcop1, *pcop2;
10762 symbol *sym = OP_SYMBOL( right );
10764 size = AOP_SIZE(result);
10766 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10768 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10770 pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
10773 pic16_emitpcode(POC_MOVLW, pcop0);
10774 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
10775 pic16_emitpcode(POC_MOVLW, pcop1);
10776 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
10777 pic16_emitpcode(POC_MOVLW, pcop2);
10778 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
10781 pic16_emitpcode(POC_MOVLW, pcop0);
10782 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10783 pic16_emitpcode(POC_MOVLW, pcop1);
10784 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10786 pic16_emitpcode(POC_MOVLW, pcop0);
10787 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10791 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10792 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
10793 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
10794 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
10795 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
10796 if(AOP_SIZE(result) <2)
10797 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
10799 /* if they in different places then copy */
10800 size = AOP_SIZE(result);
10803 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10804 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10811 /* if the result is of type pointer */
10812 if (IS_PTR(ctype)) {
10814 sym_link *type = operandType(right);
10815 sym_link *etype = getSpec(type);
10817 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
10819 /* pointer to generic pointer */
10820 if (IS_GENPTR(ctype)) {
10824 p_type = DCL_TYPE(type);
10826 /* we have to go by the storage class */
10827 p_type = PTR_TYPE(SPEC_OCLS(etype));
10829 /* if (SPEC_OCLS(etype)->codesp ) */
10830 /* p_type = CPOINTER ; */
10832 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
10833 /* p_type = FPOINTER ; */
10835 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
10836 /* p_type = PPOINTER; */
10838 /* if (SPEC_OCLS(etype) == idata ) */
10839 /* p_type = IPOINTER ; */
10841 /* p_type = POINTER ; */
10844 /* the first two bytes are known */
10845 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
10846 size = GPTRSIZE - 1;
10849 if(offset < AOP_SIZE(right)) {
10850 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
10851 if ((AOP_TYPE(right) == AOP_PCODE) &&
10852 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
10853 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
10854 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10856 pic16_aopPut(AOP(result),
10857 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10861 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
10864 /* the last byte depending on type */
10868 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
10871 pic16_emitcode(";BUG!? ","%d",__LINE__);
10875 pic16_emitcode(";BUG!? ","%d",__LINE__);
10879 pic16_emitcode(";BUG!? ","%d",__LINE__);
10884 /* this should never happen */
10885 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10886 "got unknown pointer type");
10889 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
10893 /* just copy the pointers */
10894 size = AOP_SIZE(result);
10897 pic16_aopPut(AOP(result),
10898 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
10907 /* so we now know that the size of destination is greater
10908 than the size of the source.
10909 Now, if the next iCode is an operator then we might be
10910 able to optimize the operation without performing a cast.
10912 if(genMixedOperation(ic))
10915 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
10917 /* we move to result for the size of source */
10918 size = AOP_SIZE(right);
10921 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
10922 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
10926 /* now depending on the sign of the destination */
10927 size = AOP_SIZE(result) - AOP_SIZE(right);
10928 /* if unsigned or not an integral type */
10929 if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) {
10931 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10933 /* we need to extend the sign :( */
10936 /* Save one instruction of casting char to int */
10937 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10938 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10939 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10941 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10944 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10946 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10948 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10951 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10956 pic16_freeAsmop(right,NULL,ic,TRUE);
10957 pic16_freeAsmop(result,NULL,ic,TRUE);
10961 /*-----------------------------------------------------------------*/
10962 /* genDjnz - generate decrement & jump if not zero instrucion */
10963 /*-----------------------------------------------------------------*/
10964 static int genDjnz (iCode *ic, iCode *ifx)
10966 symbol *lbl, *lbl1;
10967 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10972 /* if the if condition has a false label
10973 then we cannot save */
10977 /* if the minus is not of the form
10979 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10980 !IS_OP_LITERAL(IC_RIGHT(ic)))
10983 if (operandLitValue(IC_RIGHT(ic)) != 1)
10986 /* if the size of this greater than one then no
10988 if (getSize(operandType(IC_RESULT(ic))) > 1)
10991 /* otherwise we can save BIG */
10992 lbl = newiTempLabel(NULL);
10993 lbl1= newiTempLabel(NULL);
10995 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10997 if (IS_AOP_PREG(IC_RESULT(ic))) {
10998 pic16_emitcode("dec","%s",
10999 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11000 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11001 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
11005 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
11006 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
11008 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
11009 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
11012 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
11013 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
11014 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
11015 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
11018 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11019 ifx->generated = 1;
11023 /*-----------------------------------------------------------------*/
11024 /* genReceive - generate code for a receive iCode */
11025 /*-----------------------------------------------------------------*/
11026 static void genReceive (iCode *ic)
11028 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
11030 if (isOperandInFarSpace(IC_RESULT(ic)) &&
11031 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
11032 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
11034 int size = getSize(operandType(IC_RESULT(ic)));
11035 int offset = pic16_fReturnSizePic - size;
11038 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
11039 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
11043 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
11045 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11046 size = AOP_SIZE(IC_RESULT(ic));
11049 pic16_emitcode ("pop","acc");
11050 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
11053 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
11056 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
11058 assignResultValue(IC_RESULT(ic), 0);
11061 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
11064 /*-----------------------------------------------------------------*/
11065 /* genDummyRead - generate code for dummy read of volatiles */
11066 /*-----------------------------------------------------------------*/
11068 genDummyRead (iCode * ic)
11070 pic16_emitcode ("; genDummyRead","");
11071 pic16_emitcode ("; not implemented","");
11076 /*-----------------------------------------------------------------*/
11077 /* genpic16Code - generate code for pic16 based controllers */
11078 /*-----------------------------------------------------------------*/
11080 * At this point, ralloc.c has gone through the iCode and attempted
11081 * to optimize in a way suitable for a PIC. Now we've got to generate
11082 * PIC instructions that correspond to the iCode.
11084 * Once the instructions are generated, we'll pass through both the
11085 * peep hole optimizer and the pCode optimizer.
11086 *-----------------------------------------------------------------*/
11088 void genpic16Code (iCode *lic)
11093 lineHead = lineCurr = NULL;
11095 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
11096 pic16_addpBlock(pb);
11099 /* if debug information required */
11100 if (options.debug && currFunc) {
11102 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
11104 if (IS_STATIC(currFunc->etype)) {
11105 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
11106 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
11108 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
11109 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
11116 for (ic = lic ; ic ; ic = ic->next ) {
11118 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
11119 if ( cln != ic->lineno ) {
11120 if ( options.debug ) {
11122 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
11123 FileBaseName(ic->filename),ic->lineno,
11124 ic->level,ic->block);
11128 if(!options.noCcodeInAsm) {
11129 pic16_addpCode2pBlock(pb,
11130 pic16_newpCodeCSource(ic->lineno, ic->filename,
11131 printCLine(ic->filename, ic->lineno)));
11137 if(options.iCodeInAsm) {
11139 /* insert here code to print iCode as comment */
11140 l = Safe_strdup(printILine(ic));
11141 pic16_emitpcomment("ic:%d: %s", ic->seq, l);
11144 /* if the result is marked as
11145 spilt and rematerializable or code for
11146 this has already been generated then
11148 if (resultRemat(ic) || ic->generated )
11151 /* depending on the operation */
11170 /* IPOP happens only when trying to restore a
11171 spilt live range, if there is an ifx statement
11172 following this pop then the if statement might
11173 be using some of the registers being popped which
11174 would destroy the contents of the register so
11175 we need to check for this condition and handle it */
11177 ic->next->op == IFX &&
11178 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
11179 genIfx (ic->next,ic);
11197 genEndFunction (ic);
11213 pic16_genPlus (ic) ;
11217 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
11218 pic16_genMinus (ic);
11234 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
11238 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
11245 /* note these two are xlated by algebraic equivalence
11246 during parsing SDCC.y */
11247 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
11248 "got '>=' or '<=' shouldn't have come here");
11252 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
11264 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
11268 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
11272 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
11296 genRightShift (ic);
11299 case GET_VALUE_AT_ADDRESS:
11304 if (POINTER_SET(ic))
11331 addSet(&_G.sendSet,ic);
11334 case DUMMY_READ_VOLATILE:
11344 /* now we are ready to call the
11345 peep hole optimizer */
11346 if (!options.nopeep) {
11347 peepHole (&lineHead);
11349 /* now do the actual printing */
11350 printLine (lineHead,codeOutFile);
11353 DFPRINTF((stderr,"printing pBlock\n\n"));
11354 pic16_printpBlock(stdout,pb);