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"
47 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
49 void pic16_genMult8X8_8 (operand *, operand *,operand *);
50 pCode *pic16_AssembleLine(char *line);
51 extern void pic16_printpBlock(FILE *of, pBlock *pb);
52 static asmop *newAsmop (short type);
53 static pCodeOp *popRegFromString(char *str, int size, int offset);
54 static void mov2w (asmop *aop, int offset);
55 static int aopIdx (asmop *aop, int offset);
57 static int labelOffset=0;
58 extern int pic16_debug_verbose;
59 static int optimized_for_speed = 0;
64 int options_no_movff = 1;
66 /* max_key keeps track of the largest label number used in
67 a function. This is then used to adjust the label offset
68 for the next function.
71 static int GpsuedoStkPtr=0;
73 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
74 unsigned int pic16aopLiteral (value *val, int offset);
75 const char *pic16_AopType(short type);
76 static iCode *ifxForOp ( operand *op, iCode *ic );
78 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
80 /* this is the down and dirty file with all kinds of
81 kludgy & hacky stuff. This is what it is all about
82 CODE GENERATION for a specific MCU . some of the
83 routines may be reusable, will have to see */
85 static char *zero = "#0x00";
86 static char *one = "#0x01";
87 static char *spname = "sp";
89 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic16;
94 static char *accUse[] = {"a","b"};
96 //static short rbank = -1;
108 /* Resolved ifx structure. This structure stores information
109 about an iCode ifx that makes it easier to generate code.
111 typedef struct resolvedIfx {
112 symbol *lbl; /* pointer to a label */
113 int condition; /* true or false ifx */
114 int generated; /* set true when the code associated with the ifx
118 extern int pic16_ptrRegReq ;
119 extern int pic16_nRegs;
120 extern FILE *codeOutFile;
121 static void saverbank (int, iCode *,bool);
123 static lineNode *lineHead = NULL;
124 static lineNode *lineCurr = NULL;
126 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
127 0xE0, 0xC0, 0x80, 0x00};
128 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
129 0x07, 0x03, 0x01, 0x00};
133 /*-----------------------------------------------------------------*/
134 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
135 /* exponent of 2 is returned, otherwise -1 is */
137 /* note that this is similar to the function `powof2' in SDCCsymt */
141 /*-----------------------------------------------------------------*/
142 static int my_powof2 (unsigned long num)
145 if( (num & (num-1)) == 0) {
158 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
161 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
163 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
164 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
166 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
168 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169 ((result) ? AOP_SIZE(result) : 0));
173 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
176 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
178 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
179 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
180 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
181 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
182 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
183 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
187 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
190 char lb[INITIAL_INLINEASM];
193 if(!pic16_debug_verbose)
200 sprintf(lb,"%s\t",inst);
202 sprintf(lb,"%s",inst);
203 vsprintf(lb+(strlen(lb)),fmt,ap);
207 while (isspace(*lbp)) lbp++;
210 lineCurr = (lineCurr ?
211 connectLine(lineCurr,newLineNode(lb)) :
212 (lineHead = newLineNode(lb)));
213 lineCurr->isInline = _G.inLine;
214 lineCurr->isDebug = _G.debugLine;
216 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
219 // fprintf(stderr, "%s\n", lb);
223 void pic16_emitpLabel(int key)
225 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
228 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
232 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
234 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
236 // fprintf(stderr, "%s\n", pcop->name);
239 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
242 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
246 /*-----------------------------------------------------------------*/
247 /* pic16_emitcode - writes the code into a file : for now it is simple */
248 /*-----------------------------------------------------------------*/
249 void pic16_emitcode (char *inst,char *fmt, ...)
252 char lb[INITIAL_INLINEASM];
259 sprintf(lb,"%s\t",inst);
261 sprintf(lb,"%s",inst);
262 vsprintf(lb+(strlen(lb)),fmt,ap);
266 while (isspace(*lbp)) lbp++;
269 lineCurr = (lineCurr ?
270 connectLine(lineCurr,newLineNode(lb)) :
271 (lineHead = newLineNode(lb)));
272 lineCurr->isInline = _G.inLine;
273 lineCurr->isDebug = _G.debugLine;
275 // VR fprintf(stderr, "lb = <%s>\n", lbp);
277 if(pic16_debug_verbose)
278 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
289 bool r0iu = FALSE , r1iu = FALSE;
290 bool r0ou = FALSE , r1ou = FALSE;
292 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
294 /* the logic: if r0 & r1 used in the instruction
295 then we are in trouble otherwise */
297 /* first check if r0 & r1 are used by this
298 instruction, in which case we are in trouble */
299 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
300 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
305 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
306 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
308 /* if no usage of r0 then return it */
309 if (!r0iu && !r0ou) {
310 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
311 (*aopp)->type = AOP_R0;
313 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
316 /* if no usage of r1 then return it */
317 if (!r1iu && !r1ou) {
318 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
319 (*aopp)->type = AOP_R1;
321 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
324 /* now we know they both have usage */
325 /* if r0 not used in this instruction */
327 /* push it if not already pushed */
329 //pic16_emitcode ("push","%s",
330 // pic16_regWithIdx(R0_IDX)->dname);
334 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
335 (*aopp)->type = AOP_R0;
337 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
340 /* if r1 not used then */
343 /* push it if not already pushed */
345 //pic16_emitcode ("push","%s",
346 // pic16_regWithIdx(R1_IDX)->dname);
350 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
351 (*aopp)->type = AOP_R1;
352 return pic16_regWithIdx(R1_IDX);
356 /* I said end of world but not quite end of world yet */
357 /* if this is a result then we can push it on the stack*/
359 (*aopp)->type = AOP_STK;
363 /* other wise this is true end of the world */
364 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
365 "getFreePtr should never reach here");
369 /*-----------------------------------------------------------------*/
370 /* newAsmop - creates a new asmOp */
371 /*-----------------------------------------------------------------*/
372 static asmop *newAsmop (short type)
376 aop = Safe_calloc(1,sizeof(asmop));
381 static void genSetDPTR(int n)
385 pic16_emitcode(";", "Select standard DPTR");
386 pic16_emitcode("mov", "dps, #0x00");
390 pic16_emitcode(";", "Select alternate DPTR");
391 pic16_emitcode("mov", "dps, #0x01");
395 /*-----------------------------------------------------------------*/
396 /* resolveIfx - converts an iCode ifx into a form more useful for */
397 /* generating code */
398 /*-----------------------------------------------------------------*/
399 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
404 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
406 resIfx->condition = 1; /* assume that the ifx is true */
407 resIfx->generated = 0; /* indicate that the ifx has not been used */
410 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
412 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
413 __FUNCTION__,__LINE__,resIfx->lbl->key);
417 resIfx->lbl = IC_TRUE(ifx);
419 resIfx->lbl = IC_FALSE(ifx);
420 resIfx->condition = 0;
424 DEBUGpic16_emitcode("; ***","ifx true is non-null");
426 DEBUGpic16_emitcode("; ***","ifx false is non-null");
430 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
433 /*-----------------------------------------------------------------*/
434 /* pointerCode - returns the code for a pointer type */
435 /*-----------------------------------------------------------------*/
436 static int pointerCode (sym_link *etype)
439 return PTR_TYPE(SPEC_OCLS(etype));
443 /*-----------------------------------------------------------------*/
444 /* aopForSym - for a true symbol */
445 /*-----------------------------------------------------------------*/
446 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
449 memmap *space= SPEC_OCLS(sym->etype);
451 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
452 /* if already has one */
454 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
458 /* assign depending on the storage class */
459 /* if it is on the stack or indirectly addressable */
460 /* space we need to assign either r0 or r1 to it */
461 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
462 sym->aop = aop = newAsmop(0);
463 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
464 aop->size = getSize(sym->type);
466 /* now assign the address of the variable to
467 the pointer register */
468 if (aop->type != AOP_STK) {
472 pic16_emitcode("push","acc");
474 pic16_emitcode("mov","a,_bp");
475 pic16_emitcode("add","a,#0x%02x",
477 ((char)(sym->stack - _G.nRegsSaved )) :
478 ((char)sym->stack)) & 0xff);
479 pic16_emitcode("mov","%s,a",
480 aop->aopu.aop_ptr->name);
483 pic16_emitcode("pop","acc");
485 pic16_emitcode("mov","%s,#%s",
486 aop->aopu.aop_ptr->name,
488 aop->paged = space->paged;
490 aop->aopu.aop_stk = sym->stack;
494 if (sym->onStack && options.stack10bit)
496 /* It's on the 10 bit stack, which is located in
500 //DEBUGpic16_emitcode(";","%d",__LINE__);
503 pic16_emitcode("push","acc");
505 pic16_emitcode("mov","a,_bp");
506 pic16_emitcode("add","a,#0x%02x",
508 ((char)(sym->stack - _G.nRegsSaved )) :
509 ((char)sym->stack)) & 0xff);
512 pic16_emitcode ("mov","dpx1,#0x40");
513 pic16_emitcode ("mov","dph1,#0x00");
514 pic16_emitcode ("mov","dpl1, a");
518 pic16_emitcode("pop","acc");
520 sym->aop = aop = newAsmop(AOP_DPTR2);
521 aop->size = getSize(sym->type);
525 //DEBUGpic16_emitcode(";","%d",__LINE__);
526 /* if in bit space */
527 if (IN_BITSPACE(space)) {
528 sym->aop = aop = newAsmop (AOP_CRY);
529 aop->aopu.aop_dir = sym->rname ;
530 aop->size = getSize(sym->type);
531 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
534 /* if it is in direct space */
535 if (IN_DIRSPACE(space)) {
536 sym->aop = aop = newAsmop (AOP_DIR);
537 aop->aopu.aop_dir = sym->rname ;
538 aop->size = getSize(sym->type);
539 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
543 /* special case for a function */
544 if (IS_FUNC(sym->type)) {
545 sym->aop = aop = newAsmop(AOP_IMMD);
546 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
547 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
548 strcpy(aop->aopu.aop_immd,sym->rname);
549 aop->size = FPTRSIZE;
550 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
555 /* only remaining is far space */
556 /* in which case DPTR gets the address */
557 sym->aop = aop = newAsmop(AOP_PCODE);
559 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
560 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
561 PCOI(aop->aopu.pcop)->index = 0;
563 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
564 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
566 pic16_allocDirReg (IC_LEFT(ic));
568 aop->size = FPTRSIZE;
570 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
571 sym->aop = aop = newAsmop(AOP_DPTR);
572 pic16_emitcode ("mov","dptr,#%s", sym->rname);
573 aop->size = getSize(sym->type);
575 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
578 /* if it is in code space */
579 if (IN_CODESPACE(space))
585 /*-----------------------------------------------------------------*/
586 /* aopForRemat - rematerialzes an object */
587 /*-----------------------------------------------------------------*/
588 static asmop *aopForRemat (operand *op) // x symbol *sym)
590 symbol *sym = OP_SYMBOL(op);
592 asmop *aop = newAsmop(AOP_PCODE);
596 ic = sym->rematiCode;
598 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
599 if(IS_OP_POINTER(op)) {
600 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
604 val += (int) operandLitValue(IC_RIGHT(ic));
605 } else if (ic->op == '-') {
606 val -= (int) operandLitValue(IC_RIGHT(ic));
610 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
613 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
614 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
616 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
618 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
620 PCOI(aop->aopu.pcop)->index = val;
622 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
623 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
625 val, IS_PTR_CONST(operandType(op)));
627 val, IS_CODEPTR(operandType(op)));
630 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
632 pic16_allocDirReg (IC_LEFT(ic));
637 static int aopIdx (asmop *aop, int offset)
642 if(aop->type != AOP_REG)
645 return aop->aopu.aop_reg[offset]->rIdx;
648 /*-----------------------------------------------------------------*/
649 /* regsInCommon - two operands have some registers in common */
650 /*-----------------------------------------------------------------*/
651 static bool regsInCommon (operand *op1, operand *op2)
656 /* if they have registers in common */
657 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
660 sym1 = OP_SYMBOL(op1);
661 sym2 = OP_SYMBOL(op2);
663 if (sym1->nRegs == 0 || sym2->nRegs == 0)
666 for (i = 0 ; i < sym1->nRegs ; i++) {
671 for (j = 0 ; j < sym2->nRegs ;j++ ) {
675 if (sym2->regs[j] == sym1->regs[i])
683 /*-----------------------------------------------------------------*/
684 /* operandsEqu - equivalent */
685 /*-----------------------------------------------------------------*/
686 static bool operandsEqu ( operand *op1, operand *op2)
690 /* if they not symbols */
691 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
694 sym1 = OP_SYMBOL(op1);
695 sym2 = OP_SYMBOL(op2);
697 /* if both are itemps & one is spilt
698 and the other is not then false */
699 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
700 sym1->isspilt != sym2->isspilt )
703 /* if they are the same */
707 if (strcmp(sym1->rname,sym2->rname) == 0)
711 /* if left is a tmp & right is not */
715 (sym1->usl.spillLoc == sym2))
722 (sym2->usl.spillLoc == sym1))
728 /*-----------------------------------------------------------------*/
729 /* pic16_sameRegs - two asmops have the same registers */
730 /*-----------------------------------------------------------------*/
731 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
738 if (aop1->type != AOP_REG ||
739 aop2->type != AOP_REG )
742 if (aop1->size != aop2->size )
745 for (i = 0 ; i < aop1->size ; i++ )
746 if (aop1->aopu.aop_reg[i] !=
747 aop2->aopu.aop_reg[i] )
753 /*-----------------------------------------------------------------*/
754 /* pic16_aopOp - allocates an asmop for an operand : */
755 /*-----------------------------------------------------------------*/
756 void pic16_aopOp (operand *op, iCode *ic, bool result)
765 DEBUGpic16_emitcode(";","%d",__LINE__);
766 /* if this a literal */
767 if (IS_OP_LITERAL(op)) {
768 op->aop = aop = newAsmop(AOP_LIT);
769 aop->aopu.aop_lit = op->operand.valOperand;
770 aop->size = getSize(operandType(op));
775 sym_link *type = operandType(op);
777 if(IS_PTR_CONST(type))
781 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
784 /* if already has a asmop then continue */
788 /* if the underlying symbol has a aop */
789 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
790 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
791 op->aop = OP_SYMBOL(op)->aop;
795 /* if this is a true symbol */
796 if (IS_TRUE_SYMOP(op)) {
797 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
798 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
802 /* this is a temporary : this has
808 e) can be a return use only */
812 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
813 /* if the type is a conditional */
814 if (sym->regType == REG_CND) {
815 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
820 /* if it is spilt then two situations
822 b) has a spill location */
823 if (sym->isspilt || sym->nRegs == 0) {
825 DEBUGpic16_emitcode(";","%d",__LINE__);
826 /* rematerialize it NOW */
829 sym->aop = op->aop = aop =
831 aop->size = getSize(sym->type);
832 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
838 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
839 aop->size = getSize(sym->type);
840 for ( i = 0 ; i < 2 ; i++ )
841 aop->aopu.aop_str[i] = accUse[i];
842 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
848 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
849 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
850 //pic16_allocDirReg (IC_LEFT(ic));
851 aop->size = getSize(sym->type);
856 aop = op->aop = sym->aop = newAsmop(AOP_STR);
857 aop->size = getSize(sym->type);
858 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
859 aop->aopu.aop_str[i] = fReturn[i];
861 DEBUGpic16_emitcode(";","%d",__LINE__);
865 /* else spill location */
866 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
867 /* force a new aop if sizes differ */
868 sym->usl.spillLoc->aop = NULL;
870 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
871 __FUNCTION__,__LINE__,
872 sym->usl.spillLoc->rname,
873 sym->rname, sym->usl.spillLoc->offset);
875 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
876 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
877 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
879 sym->usl.spillLoc->offset);
880 aop->size = getSize(sym->type);
886 sym_link *type = operandType(op);
888 if(IS_PTR_CONST(type))
892 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
895 /* must be in a register */
896 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
897 sym->aop = op->aop = aop = newAsmop(AOP_REG);
898 aop->size = sym->nRegs;
899 for ( i = 0 ; i < sym->nRegs ;i++)
900 aop->aopu.aop_reg[i] = sym->regs[i];
903 /*-----------------------------------------------------------------*/
904 /* pic16_freeAsmop - free up the asmop given to an operand */
905 /*----------------------------------------------------------------*/
906 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
923 /* depending on the asmop type only three cases need work AOP_RO
924 , AOP_R1 && AOP_STK */
930 pic16_emitcode ("pop","ar0");
934 bitVectUnSetBit(ic->rUsed,R0_IDX);
940 pic16_emitcode ("pop","ar1");
944 bitVectUnSetBit(ic->rUsed,R1_IDX);
950 int stk = aop->aopu.aop_stk + aop->size;
951 bitVectUnSetBit(ic->rUsed,R0_IDX);
952 bitVectUnSetBit(ic->rUsed,R1_IDX);
954 getFreePtr(ic,&aop,FALSE);
956 if (options.stack10bit)
958 /* I'm not sure what to do here yet... */
961 "*** Warning: probably generating bad code for "
962 "10 bit stack mode.\n");
966 pic16_emitcode ("mov","a,_bp");
967 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
968 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
970 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
974 pic16_emitcode("pop","acc");
975 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
977 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
980 pic16_freeAsmop(op,NULL,ic,TRUE);
982 pic16_emitcode("pop","ar0");
987 pic16_emitcode("pop","ar1");
995 /* all other cases just dealloc */
999 OP_SYMBOL(op)->aop = NULL;
1000 /* if the symbol has a spill */
1002 SPIL_LOC(op)->aop = NULL;
1007 /*-----------------------------------------------------------------*/
1008 /* pic16_aopGet - for fetching value of the aop */
1009 /*-----------------------------------------------------------------*/
1010 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1015 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1016 /* offset is greater than
1018 if (offset > (aop->size - 1) &&
1019 aop->type != AOP_LIT)
1022 /* depending on type */
1023 switch (aop->type) {
1027 DEBUGpic16_emitcode(";","%d",__LINE__);
1028 /* if we need to increment it */
1029 while (offset > aop->coff) {
1030 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1034 while (offset < aop->coff) {
1035 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1039 aop->coff = offset ;
1041 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1042 return (dname ? "acc" : "a");
1044 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1045 rs = Safe_calloc(1,strlen(s)+1);
1051 DEBUGpic16_emitcode(";","%d",__LINE__);
1052 if (aop->type == AOP_DPTR2)
1057 while (offset > aop->coff) {
1058 pic16_emitcode ("inc","dptr");
1062 while (offset < aop->coff) {
1063 pic16_emitcode("lcall","__decdptr");
1069 pic16_emitcode("clr","a");
1070 pic16_emitcode("movc","a,@a+dptr");
1073 pic16_emitcode("movx","a,@dptr");
1076 if (aop->type == AOP_DPTR2)
1081 return (dname ? "acc" : "a");
1086 sprintf (s,"%s",aop->aopu.aop_immd);
1089 sprintf(s,"(%s >> %d)",
1094 aop->aopu.aop_immd);
1095 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1096 rs = Safe_calloc(1,strlen(s)+1);
1102 sprintf(s,"(%s + %d)",
1105 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1107 sprintf(s,"%s",aop->aopu.aop_dir);
1108 rs = Safe_calloc(1,strlen(s)+1);
1114 // return aop->aopu.aop_reg[offset]->dname;
1116 return aop->aopu.aop_reg[offset]->name;
1119 //pic16_emitcode(";","%d",__LINE__);
1120 return aop->aopu.aop_dir;
1123 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1124 return "AOP_accumulator_bug";
1127 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1128 rs = Safe_calloc(1,strlen(s)+1);
1133 aop->coff = offset ;
1134 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1137 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1139 return aop->aopu.aop_str[offset];
1143 pCodeOp *pcop = aop->aopu.pcop;
1144 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1146 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1147 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1148 sprintf(s,"%s", pcop->name);
1150 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1153 rs = Safe_calloc(1,strlen(s)+1);
1159 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1160 "aopget got unsupported aop->type");
1165 /*-----------------------------------------------------------------*/
1166 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1167 /*-----------------------------------------------------------------*/
1168 pCodeOp *pic16_popGetTempReg(void)
1173 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1174 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1175 PCOR(pcop)->r->wasUsed=1;
1176 PCOR(pcop)->r->isFree=0;
1182 /*-----------------------------------------------------------------*/
1183 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1184 /*-----------------------------------------------------------------*/
1185 void pic16_popReleaseTempReg(pCodeOp *pcop)
1188 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1189 PCOR(pcop)->r->isFree = 1;
1192 /*-----------------------------------------------------------------*/
1193 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1194 /*-----------------------------------------------------------------*/
1195 pCodeOp *pic16_popGetLabel(unsigned int key)
1198 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1203 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1206 /*-----------------------------------------------------------------*/
1207 /* pic16_popCopyReg - copy a pcode operator */
1208 /*-----------------------------------------------------------------*/
1209 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1213 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1214 pcor->pcop.type = pc->pcop.type;
1216 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1217 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1219 pcor->pcop.name = NULL;
1222 pcor->rIdx = pc->rIdx;
1225 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1229 /*-----------------------------------------------------------------*/
1230 /* pic16_popGet - asm operator to pcode operator conversion */
1231 /*-----------------------------------------------------------------*/
1232 pCodeOp *pic16_popGetLit(unsigned int lit)
1235 return pic16_newpCodeOpLit(lit);
1239 /*-----------------------------------------------------------------*/
1240 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1241 /*-----------------------------------------------------------------*/
1242 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1245 return pic16_newpCodeOpImmd(name, offset,index, 0);
1249 /*-----------------------------------------------------------------*/
1250 /* pic16_popGet - asm operator to pcode operator conversion */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *pic16_popGetWithString(char *str)
1258 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1262 pcop = pic16_newpCodeOp(str,PO_STR);
1267 /*-----------------------------------------------------------------*/
1268 /* popRegFromString - */
1269 /*-----------------------------------------------------------------*/
1270 static pCodeOp *popRegFromString(char *str, int size, int offset)
1273 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1274 pcop->type = PO_DIR;
1276 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1277 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1282 pcop->name = Safe_calloc(1,strlen(str)+1);
1283 strcpy(pcop->name,str);
1285 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1287 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1288 if(PCOR(pcop)->r == NULL) {
1289 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1290 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1292 //fprintf(stderr, "allocating new register -> %s\n", str);
1294 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1296 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1298 PCOR(pcop)->instance = offset;
1303 static pCodeOp *popRegFromIdx(int rIdx)
1307 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1308 __FUNCTION__,__LINE__,rIdx);
1310 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1312 PCOR(pcop)->rIdx = rIdx;
1313 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1314 PCOR(pcop)->r->isFree = 0;
1315 PCOR(pcop)->r->wasUsed = 1;
1317 pcop->type = PCOR(pcop)->r->pc_type;
1323 /*---------------------------------------------------------------------------------*/
1324 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1326 /*---------------------------------------------------------------------------------*/
1327 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1332 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1333 temp = pic16_popGet(aop_dst, offset);
1334 pcop2->pcop2 = temp;
1340 /*-----------------------------------------------------------------*/
1341 /* pic16_popGet - asm operator to pcode operator conversion */
1342 /*-----------------------------------------------------------------*/
1343 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1345 //char *s = buffer ;
1350 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1351 /* offset is greater than
1354 if (offset > (aop->size - 1) &&
1355 aop->type != AOP_LIT)
1356 return NULL; //zero;
1358 /* depending on type */
1359 switch (aop->type) {
1366 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1370 DEBUGpic16_emitcode(";","%d",__LINE__);
1371 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1374 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1377 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1378 pcop->type = PO_DIR;
1382 sprintf(s,"(%s + %d)",
1386 sprintf(s,"%s",aop->aopu.aop_dir);
1387 pcop->name = Safe_calloc(1,strlen(s)+1);
1388 strcpy(pcop->name,s);
1390 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1391 strcpy(pcop->name,aop->aopu.aop_dir);
1392 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1393 if(PCOR(pcop)->r == NULL) {
1394 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1395 PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1396 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1398 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1400 PCOR(pcop)->instance = offset;
1407 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1409 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1410 PCOR(pcop)->rIdx = rIdx;
1411 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1412 PCOR(pcop)->r->wasUsed=1;
1413 PCOR(pcop)->r->isFree=0;
1415 PCOR(pcop)->instance = offset;
1416 pcop->type = PCOR(pcop)->r->pc_type;
1417 //rs = aop->aopu.aop_reg[offset]->name;
1418 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1423 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1424 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1425 //if(PCOR(pcop)->r == NULL)
1426 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1430 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1433 DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1434 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1436 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1437 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1438 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1439 pcop->type = PCOR(pcop)->r->pc_type;
1440 pcop->name = PCOR(pcop)->r->name;
1446 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1448 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1449 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1450 PCOI(pcop)->offset = offset;
1454 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1455 "pic16_popGet got unsupported aop->type");
1458 /*-----------------------------------------------------------------*/
1459 /* pic16_aopPut - puts a string for a aop */
1460 /*-----------------------------------------------------------------*/
1461 void pic16_aopPut (asmop *aop, char *s, int offset)
1466 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1468 if (aop->size && offset > ( aop->size - 1)) {
1469 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1470 "pic16_aopPut got offset > aop->size");
1474 /* will assign value to value */
1475 /* depending on where it is ofcourse */
1476 switch (aop->type) {
1479 sprintf(d,"(%s + %d)",
1480 aop->aopu.aop_dir,offset);
1481 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1484 sprintf(d,"%s",aop->aopu.aop_dir);
1487 DEBUGpic16_emitcode(";","%d",__LINE__);
1489 pic16_emitcode("movf","%s,w",s);
1490 pic16_emitcode("movwf","%s",d);
1493 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1494 if(offset >= aop->size) {
1495 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1498 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1501 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1508 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1509 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1512 strcmp(s,"r0") == 0 ||
1513 strcmp(s,"r1") == 0 ||
1514 strcmp(s,"r2") == 0 ||
1515 strcmp(s,"r3") == 0 ||
1516 strcmp(s,"r4") == 0 ||
1517 strcmp(s,"r5") == 0 ||
1518 strcmp(s,"r6") == 0 ||
1519 strcmp(s,"r7") == 0 )
1520 pic16_emitcode("mov","%s,%s ; %d",
1521 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1525 if(strcmp(s,"W")==0 )
1526 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1528 pic16_emitcode("movwf","%s",
1529 aop->aopu.aop_reg[offset]->name);
1531 if(strcmp(s,zero)==0) {
1532 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1534 } else if(strcmp(s,"W")==0) {
1535 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1536 pcop->type = PO_GPR_REGISTER;
1538 PCOR(pcop)->rIdx = -1;
1539 PCOR(pcop)->r = NULL;
1541 DEBUGpic16_emitcode(";","%d",__LINE__);
1542 pcop->name = Safe_strdup(s);
1543 pic16_emitpcode(POC_MOVFW,pcop);
1544 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1545 } else if(strcmp(s,one)==0) {
1546 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1547 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1549 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1557 if (aop->type == AOP_DPTR2)
1563 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1564 "pic16_aopPut writting to code space");
1568 while (offset > aop->coff) {
1570 pic16_emitcode ("inc","dptr");
1573 while (offset < aop->coff) {
1575 pic16_emitcode("lcall","__decdptr");
1580 /* if not in accumulater */
1583 pic16_emitcode ("movx","@dptr,a");
1585 if (aop->type == AOP_DPTR2)
1593 while (offset > aop->coff) {
1595 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1597 while (offset < aop->coff) {
1599 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1605 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1610 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1612 if (strcmp(s,"r0") == 0 ||
1613 strcmp(s,"r1") == 0 ||
1614 strcmp(s,"r2") == 0 ||
1615 strcmp(s,"r3") == 0 ||
1616 strcmp(s,"r4") == 0 ||
1617 strcmp(s,"r5") == 0 ||
1618 strcmp(s,"r6") == 0 ||
1619 strcmp(s,"r7") == 0 ) {
1621 sprintf(buffer,"a%s",s);
1622 pic16_emitcode("mov","@%s,%s",
1623 aop->aopu.aop_ptr->name,buffer);
1625 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1630 if (strcmp(s,"a") == 0)
1631 pic16_emitcode("push","acc");
1633 pic16_emitcode("push","%s",s);
1638 /* if bit variable */
1639 if (!aop->aopu.aop_dir) {
1640 pic16_emitcode("clr","a");
1641 pic16_emitcode("rlc","a");
1644 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1647 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1650 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1652 lbl = newiTempLabel(NULL);
1654 if (strcmp(s,"a")) {
1657 pic16_emitcode("clr","c");
1658 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1659 pic16_emitcode("cpl","c");
1660 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1661 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1668 if (strcmp(aop->aopu.aop_str[offset],s))
1669 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1674 if (!offset && (strcmp(s,"acc") == 0))
1677 if (strcmp(aop->aopu.aop_str[offset],s))
1678 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1682 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1683 "pic16_aopPut got unsupported aop->type");
1689 /*-----------------------------------------------------------------*/
1690 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1691 /*-----------------------------------------------------------------*/
1692 static void mov2w (asmop *aop, int offset)
1698 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1700 if ( aop->type == AOP_PCODE ||
1701 aop->type == AOP_LIT )
1702 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1704 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1708 /*-----------------------------------------------------------------*/
1709 /* reAdjustPreg - points a register back to where it should */
1710 /*-----------------------------------------------------------------*/
1711 static void reAdjustPreg (asmop *aop)
1715 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1717 if ((size = aop->size) <= 1)
1720 switch (aop->type) {
1724 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1728 if (aop->type == AOP_DPTR2)
1734 pic16_emitcode("lcall","__decdptr");
1737 if (aop->type == AOP_DPTR2)
1749 /*-----------------------------------------------------------------*/
1750 /* opIsGptr: returns non-zero if the passed operand is */
1751 /* a generic pointer type. */
1752 /*-----------------------------------------------------------------*/
1753 static int opIsGptr(operand *op)
1755 sym_link *type = operandType(op);
1757 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1758 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1766 /*-----------------------------------------------------------------*/
1767 /* pic16_getDataSize - get the operand data size */
1768 /*-----------------------------------------------------------------*/
1769 int pic16_getDataSize(operand *op)
1771 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1774 return AOP_SIZE(op);
1776 // tsd- in the pic port, the genptr size is 1, so this code here
1777 // fails. ( in the 8051 port, the size was 4).
1780 size = AOP_SIZE(op);
1781 if (size == GPTRSIZE)
1783 sym_link *type = operandType(op);
1784 if (IS_GENPTR(type))
1786 /* generic pointer; arithmetic operations
1787 * should ignore the high byte (pointer type).
1790 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1797 /*-----------------------------------------------------------------*/
1798 /* pic16_outAcc - output Acc */
1799 /*-----------------------------------------------------------------*/
1800 void pic16_outAcc(operand *result)
1803 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1804 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1807 size = pic16_getDataSize(result);
1809 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1812 /* unsigned or positive */
1814 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1819 /*-----------------------------------------------------------------*/
1820 /* pic16_outBitC - output a bit C */
1821 /*-----------------------------------------------------------------*/
1822 void pic16_outBitC(operand *result)
1825 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1826 /* if the result is bit */
1827 if (AOP_TYPE(result) == AOP_CRY)
1828 pic16_aopPut(AOP(result),"c",0);
1830 pic16_emitcode("clr","a ; %d", __LINE__);
1831 pic16_emitcode("rlc","a");
1832 pic16_outAcc(result);
1836 /*-----------------------------------------------------------------*/
1837 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1838 /*-----------------------------------------------------------------*/
1839 void pic16_toBoolean(operand *oper)
1841 int size = AOP_SIZE(oper) - 1;
1844 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1846 if ( AOP_TYPE(oper) != AOP_ACC) {
1847 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1850 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1855 /*-----------------------------------------------------------------*/
1856 /* genNot - generate code for ! operation */
1857 /*-----------------------------------------------------------------*/
1858 static void genNot (iCode *ic)
1863 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1864 /* assign asmOps to operand & result */
1865 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1866 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1868 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1869 /* if in bit space then a special case */
1870 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1871 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1872 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1873 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1875 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1876 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1877 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1882 size = AOP_SIZE(IC_LEFT(ic));
1884 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1885 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1886 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1889 pic16_toBoolean(IC_LEFT(ic));
1891 tlbl = newiTempLabel(NULL);
1892 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1893 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1894 pic16_outBitC(IC_RESULT(ic));
1897 /* release the aops */
1898 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1903 /*-----------------------------------------------------------------*/
1904 /* genCpl - generate code for complement */
1905 /*-----------------------------------------------------------------*/
1906 static void genCpl (iCode *ic)
1912 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1913 /* assign asmOps to operand & result */
1914 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1915 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1917 /* if both are in bit space then
1919 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1920 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1922 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1923 pic16_emitcode("cpl","c");
1924 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1928 size = AOP_SIZE(IC_RESULT(ic));
1931 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1933 pic16_emitcode("cpl","a");
1934 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1936 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1937 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
1939 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1940 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1948 /* release the aops */
1949 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1950 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1953 /*-----------------------------------------------------------------*/
1954 /* genUminusFloat - unary minus for floating points */
1955 /*-----------------------------------------------------------------*/
1956 static void genUminusFloat(operand *op,operand *result)
1958 int size ,offset =0 ;
1961 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1962 /* for this we just need to flip the
1963 first it then copy the rest in place */
1964 size = AOP_SIZE(op) - 1;
1965 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1969 pic16_emitcode("cpl","acc.7");
1970 pic16_aopPut(AOP(result),"a",3);
1973 pic16_aopPut(AOP(result),
1974 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1980 /*-----------------------------------------------------------------*/
1981 /* genUminus - unary minus code generation */
1982 /*-----------------------------------------------------------------*/
1983 static void genUminus (iCode *ic)
1986 sym_link *optype, *rtype;
1989 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1991 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1992 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1994 /* if both in bit space then special
1996 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1997 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1999 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2000 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2001 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2006 optype = operandType(IC_LEFT(ic));
2007 rtype = operandType(IC_RESULT(ic));
2009 /* if float then do float stuff */
2010 if (IS_FLOAT(optype)) {
2011 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2015 /* otherwise subtract from zero by taking the 2's complement */
2016 size = AOP_SIZE(IC_LEFT(ic));
2018 for(i=0; i<size; i++) {
2019 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2020 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2022 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2023 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2027 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2028 for(i=1; i<size; i++) {
2030 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2034 /* release the aops */
2035 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2036 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2039 /*-----------------------------------------------------------------*/
2040 /* saveRegisters - will look for a call and save the registers */
2041 /*-----------------------------------------------------------------*/
2042 static void saveRegisters(iCode *lic)
2049 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2051 for (ic = lic ; ic ; ic = ic->next)
2052 if (ic->op == CALL || ic->op == PCALL)
2056 fprintf(stderr,"found parameter push with no function call\n");
2060 /* if the registers have been saved already then
2062 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2065 /* find the registers in use at this time
2066 and push them away to safety */
2067 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2071 if (options.useXstack) {
2072 if (bitVectBitValue(rsave,R0_IDX))
2073 pic16_emitcode("mov","b,r0");
2074 pic16_emitcode("mov","r0,%s",spname);
2075 for (i = 0 ; i < pic16_nRegs ; i++) {
2076 if (bitVectBitValue(rsave,i)) {
2078 pic16_emitcode("mov","a,b");
2080 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2081 pic16_emitcode("movx","@r0,a");
2082 pic16_emitcode("inc","r0");
2085 pic16_emitcode("mov","%s,r0",spname);
2086 if (bitVectBitValue(rsave,R0_IDX))
2087 pic16_emitcode("mov","r0,b");
2089 //for (i = 0 ; i < pic16_nRegs ; i++) {
2090 // if (bitVectBitValue(rsave,i))
2091 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2094 dtype = operandType(IC_LEFT(ic));
2095 if (currFunc && dtype &&
2096 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2097 IFFUNC_ISISR(currFunc->type) &&
2100 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2103 /*-----------------------------------------------------------------*/
2104 /* unsaveRegisters - pop the pushed registers */
2105 /*-----------------------------------------------------------------*/
2106 static void unsaveRegisters (iCode *ic)
2111 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2112 /* find the registers in use at this time
2113 and push them away to safety */
2114 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2117 if (options.useXstack) {
2118 pic16_emitcode("mov","r0,%s",spname);
2119 for (i = pic16_nRegs ; i >= 0 ; i--) {
2120 if (bitVectBitValue(rsave,i)) {
2121 pic16_emitcode("dec","r0");
2122 pic16_emitcode("movx","a,@r0");
2124 pic16_emitcode("mov","b,a");
2126 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2130 pic16_emitcode("mov","%s,r0",spname);
2131 if (bitVectBitValue(rsave,R0_IDX))
2132 pic16_emitcode("mov","r0,b");
2134 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2135 // if (bitVectBitValue(rsave,i))
2136 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2142 /*-----------------------------------------------------------------*/
2144 /*-----------------------------------------------------------------*/
2145 static void pushSide(operand * oper, int size)
2149 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2151 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2152 if (AOP_TYPE(oper) != AOP_REG &&
2153 AOP_TYPE(oper) != AOP_DIR &&
2155 pic16_emitcode("mov","a,%s",l);
2156 pic16_emitcode("push","acc");
2158 pic16_emitcode("push","%s",l);
2163 /*-----------------------------------------------------------------*/
2164 /* assignResultValue - */
2165 /*-----------------------------------------------------------------*/
2166 static void assignResultValue(operand * oper)
2168 int size = AOP_SIZE(oper);
2170 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2172 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2174 if(!GpsuedoStkPtr) {
2175 /* The last byte in the assignment is in W */
2177 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2182 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2184 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2189 /*-----------------------------------------------------------------*/
2190 /* genIpush - genrate code for pushing this gets a little complex */
2191 /*-----------------------------------------------------------------*/
2192 static void genIpush (iCode *ic)
2195 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2197 int size, offset = 0 ;
2201 /* if this is not a parm push : ie. it is spill push
2202 and spill push is always done on the local stack */
2203 if (!ic->parmPush) {
2205 /* and the item is spilt then do nothing */
2206 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2209 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2210 size = AOP_SIZE(IC_LEFT(ic));
2211 /* push it on the stack */
2213 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2218 pic16_emitcode("push","%s",l);
2223 /* this is a paramter push: in this case we call
2224 the routine to find the call and save those
2225 registers that need to be saved */
2228 /* then do the push */
2229 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2232 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2233 size = AOP_SIZE(IC_LEFT(ic));
2236 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2237 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2238 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2240 pic16_emitcode("mov","a,%s",l);
2241 pic16_emitcode("push","acc");
2243 pic16_emitcode("push","%s",l);
2246 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2250 /*-----------------------------------------------------------------*/
2251 /* genIpop - recover the registers: can happen only for spilling */
2252 /*-----------------------------------------------------------------*/
2253 static void genIpop (iCode *ic)
2255 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2260 /* if the temp was not pushed then */
2261 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2264 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2265 size = AOP_SIZE(IC_LEFT(ic));
2268 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2271 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2275 /*-----------------------------------------------------------------*/
2276 /* unsaverbank - restores the resgister bank from stack */
2277 /*-----------------------------------------------------------------*/
2278 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2280 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2286 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2288 if (options.useXstack) {
2290 r = getFreePtr(ic,&aop,FALSE);
2293 pic16_emitcode("mov","%s,_spx",r->name);
2294 pic16_emitcode("movx","a,@%s",r->name);
2295 pic16_emitcode("mov","psw,a");
2296 pic16_emitcode("dec","%s",r->name);
2299 pic16_emitcode ("pop","psw");
2302 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2303 if (options.useXstack) {
2304 pic16_emitcode("movx","a,@%s",r->name);
2305 //pic16_emitcode("mov","(%s+%d),a",
2306 // regspic16[i].base,8*bank+regspic16[i].offset);
2307 pic16_emitcode("dec","%s",r->name);
2310 pic16_emitcode("pop",""); //"(%s+%d)",
2311 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2314 if (options.useXstack) {
2316 pic16_emitcode("mov","_spx,%s",r->name);
2317 pic16_freeAsmop(NULL,aop,ic,TRUE);
2323 /*-----------------------------------------------------------------*/
2324 /* saverbank - saves an entire register bank on the stack */
2325 /*-----------------------------------------------------------------*/
2326 static void saverbank (int bank, iCode *ic, bool pushPsw)
2328 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2334 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2335 if (options.useXstack) {
2338 r = getFreePtr(ic,&aop,FALSE);
2339 pic16_emitcode("mov","%s,_spx",r->name);
2343 for (i = 0 ; i < pic16_nRegs ;i++) {
2344 if (options.useXstack) {
2345 pic16_emitcode("inc","%s",r->name);
2346 //pic16_emitcode("mov","a,(%s+%d)",
2347 // regspic16[i].base,8*bank+regspic16[i].offset);
2348 pic16_emitcode("movx","@%s,a",r->name);
2350 pic16_emitcode("push","");// "(%s+%d)",
2351 //regspic16[i].base,8*bank+regspic16[i].offset);
2355 if (options.useXstack) {
2356 pic16_emitcode("mov","a,psw");
2357 pic16_emitcode("movx","@%s,a",r->name);
2358 pic16_emitcode("inc","%s",r->name);
2359 pic16_emitcode("mov","_spx,%s",r->name);
2360 pic16_freeAsmop (NULL,aop,ic,TRUE);
2363 pic16_emitcode("push","psw");
2365 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2371 /*-----------------------------------------------------------------*/
2372 /* genCall - generates a call statement */
2373 /*-----------------------------------------------------------------*/
2374 static void genCall (iCode *ic)
2378 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2380 /* if caller saves & we have not saved then */
2384 /* if we are calling a function that is not using
2385 the same register bank then we need to save the
2386 destination registers on the stack */
2387 dtype = operandType(IC_LEFT(ic));
2388 if (currFunc && dtype &&
2389 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2390 IFFUNC_ISISR(currFunc->type) &&
2393 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2395 /* if send set is not empty the assign */
2398 /* For the Pic port, there is no data stack.
2399 * So parameters passed to functions are stored
2400 * in registers. (The pCode optimizer will get
2401 * rid of most of these :).
2403 int psuedoStkPtr=-1;
2404 int firstTimeThruLoop = 1;
2406 _G.sendSet = reverseSet(_G.sendSet);
2408 /* First figure how many parameters are getting passed */
2409 for (sic = setFirstItem(_G.sendSet) ; sic ;
2410 sic = setNextItem(_G.sendSet)) {
2412 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2413 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2414 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2417 for (sic = setFirstItem(_G.sendSet) ; sic ;
2418 sic = setNextItem(_G.sendSet)) {
2419 int size, offset = 0;
2421 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2422 size = AOP_SIZE(IC_LEFT(sic));
2425 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2426 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2428 if(!firstTimeThruLoop) {
2429 /* If this is not the first time we've been through the loop
2430 * then we need to save the parameter in a temporary
2431 * register. The last byte of the last parameter is
2433 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2436 firstTimeThruLoop=0;
2438 //if (strcmp(l,fReturn[offset])) {
2439 mov2w (AOP(IC_LEFT(sic)), offset);
2441 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2442 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2443 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2445 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2450 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2455 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2456 OP_SYMBOL(IC_LEFT(ic))->rname :
2457 OP_SYMBOL(IC_LEFT(ic))->name));
2460 /* if we need assign a result value */
2461 if ((IS_ITEMP(IC_RESULT(ic)) &&
2462 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2463 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2464 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2467 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2470 assignResultValue(IC_RESULT(ic));
2472 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2473 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2475 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2478 /* adjust the stack for parameters if
2480 if (ic->parmBytes) {
2482 if (ic->parmBytes > 3) {
2483 pic16_emitcode("mov","a,%s",spname);
2484 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2485 pic16_emitcode("mov","%s,a",spname);
2487 for ( i = 0 ; i < ic->parmBytes ;i++)
2488 pic16_emitcode("dec","%s",spname);
2492 /* if register bank was saved then pop them */
2494 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2496 /* if we hade saved some registers then unsave them */
2497 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2498 unsaveRegisters (ic);
2503 /*-----------------------------------------------------------------*/
2504 /* genPcall - generates a call by pointer statement */
2505 /*-----------------------------------------------------------------*/
2506 static void genPcall (iCode *ic)
2509 symbol *rlbl = newiTempLabel(NULL);
2512 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2513 /* if caller saves & we have not saved then */
2517 /* if we are calling a function that is not using
2518 the same register bank then we need to save the
2519 destination registers on the stack */
2520 dtype = operandType(IC_LEFT(ic));
2521 if (currFunc && dtype &&
2522 IFFUNC_ISISR(currFunc->type) &&
2523 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2524 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2527 /* push the return address on to the stack */
2528 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2529 pic16_emitcode("push","acc");
2530 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2531 pic16_emitcode("push","acc");
2533 if (options.model == MODEL_FLAT24)
2535 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2536 pic16_emitcode("push","acc");
2539 /* now push the calling address */
2540 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2542 pushSide(IC_LEFT(ic), FPTRSIZE);
2544 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2546 /* if send set is not empty the assign */
2550 for (sic = setFirstItem(_G.sendSet) ; sic ;
2551 sic = setNextItem(_G.sendSet)) {
2552 int size, offset = 0;
2553 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2554 size = AOP_SIZE(IC_LEFT(sic));
2556 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2558 if (strcmp(l,fReturn[offset]))
2559 pic16_emitcode("mov","%s,%s",
2564 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2569 pic16_emitcode("ret","");
2570 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2573 /* if we need assign a result value */
2574 if ((IS_ITEMP(IC_RESULT(ic)) &&
2575 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2576 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2577 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2580 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2583 assignResultValue(IC_RESULT(ic));
2585 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2588 /* adjust the stack for parameters if
2590 if (ic->parmBytes) {
2592 if (ic->parmBytes > 3) {
2593 pic16_emitcode("mov","a,%s",spname);
2594 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2595 pic16_emitcode("mov","%s,a",spname);
2597 for ( i = 0 ; i < ic->parmBytes ;i++)
2598 pic16_emitcode("dec","%s",spname);
2602 /* if register bank was saved then unsave them */
2603 if (currFunc && dtype &&
2604 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2605 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2607 /* if we hade saved some registers then
2610 unsaveRegisters (ic);
2614 /*-----------------------------------------------------------------*/
2615 /* resultRemat - result is rematerializable */
2616 /*-----------------------------------------------------------------*/
2617 static int resultRemat (iCode *ic)
2619 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2620 if (SKIP_IC(ic) || ic->op == IFX)
2623 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2624 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2625 if (sym->remat && !POINTER_SET(ic))
2632 #if defined(__BORLANDC__) || defined(_MSC_VER)
2633 #define STRCASECMP stricmp
2635 #define STRCASECMP strcasecmp
2639 /*-----------------------------------------------------------------*/
2640 /* inExcludeList - return 1 if the string is in exclude Reg list */
2641 /*-----------------------------------------------------------------*/
2642 static bool inExcludeList(char *s)
2644 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2647 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2648 if (options.excludeRegs[i] &&
2649 STRCASECMP(options.excludeRegs[i],"none") == 0)
2652 for ( i = 0 ; options.excludeRegs[i]; i++) {
2653 if (options.excludeRegs[i] &&
2654 STRCASECMP(s,options.excludeRegs[i]) == 0)
2661 /*-----------------------------------------------------------------*/
2662 /* genFunction - generated code for function entry */
2663 /*-----------------------------------------------------------------*/
2664 static void genFunction (iCode *ic)
2669 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2671 labelOffset += (max_key+4);
2675 /* create the function header */
2676 pic16_emitcode(";","-----------------------------------------");
2677 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2678 pic16_emitcode(";","-----------------------------------------");
2680 pic16_emitcode("","%s:",sym->rname);
2681 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2683 ftype = operandType(IC_LEFT(ic));
2685 /* if critical function then turn interrupts off */
2686 if (IFFUNC_ISCRITICAL(ftype))
2687 pic16_emitcode("clr","ea");
2689 /* here we need to generate the equates for the
2690 register bank if required */
2692 if (FUNC_REGBANK(ftype) != rbank) {
2695 rbank = FUNC_REGBANK(ftype);
2696 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2697 if (strcmp(regspic16[i].base,"0") == 0)
2698 pic16_emitcode("","%s = 0x%02x",
2700 8*rbank+regspic16[i].offset);
2702 pic16_emitcode ("","%s = %s + 0x%02x",
2705 8*rbank+regspic16[i].offset);
2710 /* if this is an interrupt service routine then
2711 save acc, b, dpl, dph */
2712 if (IFFUNC_ISISR(sym->type)) {
2715 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2717 /* what is the reason of having these 3 NOPS? VR - 030701 */
2718 pic16_emitpcodeNULLop(POC_NOP);
2719 pic16_emitpcodeNULLop(POC_NOP);
2720 pic16_emitpcodeNULLop(POC_NOP);
2723 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2724 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2725 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2726 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2728 pic16_pBlockConvert2ISR(pb);
2730 if (!inExcludeList("acc"))
2731 pic16_emitcode ("push","acc");
2732 if (!inExcludeList("b"))
2733 pic16_emitcode ("push","b");
2734 if (!inExcludeList("dpl"))
2735 pic16_emitcode ("push","dpl");
2736 if (!inExcludeList("dph"))
2737 pic16_emitcode ("push","dph");
2738 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2740 pic16_emitcode ("push", "dpx");
2741 /* Make sure we're using standard DPTR */
2742 pic16_emitcode ("push", "dps");
2743 pic16_emitcode ("mov", "dps, #0x00");
2744 if (options.stack10bit)
2746 /* This ISR could conceivably use DPTR2. Better save it. */
2747 pic16_emitcode ("push", "dpl1");
2748 pic16_emitcode ("push", "dph1");
2749 pic16_emitcode ("push", "dpx1");
2752 /* if this isr has no bank i.e. is going to
2753 run with bank 0 , then we need to save more
2755 if (!FUNC_REGBANK(sym->type)) {
2757 /* if this function does not call any other
2758 function then we can be economical and
2759 save only those registers that are used */
2760 if (! IFFUNC_HASFCALL(sym->type)) {
2763 /* if any registers used */
2764 if (sym->regsUsed) {
2765 /* save the registers used */
2766 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2767 if (bitVectBitValue(sym->regsUsed,i) ||
2768 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2769 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2774 /* this function has a function call cannot
2775 determines register usage so we will have the
2777 saverbank(0,ic,FALSE);
2782 /* if callee-save to be used for this function
2783 then save the registers being used in this function */
2784 if (IFFUNC_CALLEESAVES(sym->type)) {
2787 /* if any registers used */
2788 if (sym->regsUsed) {
2789 /* save the registers used */
2790 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2791 if (bitVectBitValue(sym->regsUsed,i) ||
2792 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2793 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2801 /* set the register bank to the desired value */
2802 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2803 pic16_emitcode("push","psw");
2804 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2807 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2809 if (options.useXstack) {
2810 pic16_emitcode("mov","r0,%s",spname);
2811 pic16_emitcode("mov","a,_bp");
2812 pic16_emitcode("movx","@r0,a");
2813 pic16_emitcode("inc","%s",spname);
2817 /* set up the stack */
2818 pic16_emitcode ("push","_bp"); /* save the callers stack */
2820 pic16_emitcode ("mov","_bp,%s",spname);
2823 /* adjust the stack for the function */
2828 werror(W_STACK_OVERFLOW,sym->name);
2830 if (i > 3 && sym->recvSize < 4) {
2832 pic16_emitcode ("mov","a,sp");
2833 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2834 pic16_emitcode ("mov","sp,a");
2839 pic16_emitcode("inc","sp");
2844 pic16_emitcode ("mov","a,_spx");
2845 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2846 pic16_emitcode ("mov","_spx,a");
2851 /*-----------------------------------------------------------------*/
2852 /* genEndFunction - generates epilogue for functions */
2853 /*-----------------------------------------------------------------*/
2854 static void genEndFunction (iCode *ic)
2856 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2858 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2860 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2862 pic16_emitcode ("mov","%s,_bp",spname);
2865 /* if use external stack but some variables were
2866 added to the local stack then decrement the
2868 if (options.useXstack && sym->stack) {
2869 pic16_emitcode("mov","a,sp");
2870 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2871 pic16_emitcode("mov","sp,a");
2875 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2876 if (options.useXstack) {
2877 pic16_emitcode("mov","r0,%s",spname);
2878 pic16_emitcode("movx","a,@r0");
2879 pic16_emitcode("mov","_bp,a");
2880 pic16_emitcode("dec","%s",spname);
2884 pic16_emitcode ("pop","_bp");
2888 /* restore the register bank */
2889 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2890 pic16_emitcode ("pop","psw");
2892 if (IFFUNC_ISISR(sym->type)) {
2894 /* now we need to restore the registers */
2895 /* if this isr has no bank i.e. is going to
2896 run with bank 0 , then we need to save more
2898 if (!FUNC_REGBANK(sym->type)) {
2900 /* if this function does not call any other
2901 function then we can be economical and
2902 save only those registers that are used */
2903 if (! IFFUNC_HASFCALL(sym->type)) {
2906 /* if any registers used */
2907 if (sym->regsUsed) {
2908 /* save the registers used */
2909 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2910 if (bitVectBitValue(sym->regsUsed,i) ||
2911 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2912 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2917 /* this function has a function call cannot
2918 determines register usage so we will have the
2920 unsaverbank(0,ic,FALSE);
2924 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2926 if (options.stack10bit)
2928 pic16_emitcode ("pop", "dpx1");
2929 pic16_emitcode ("pop", "dph1");
2930 pic16_emitcode ("pop", "dpl1");
2932 pic16_emitcode ("pop", "dps");
2933 pic16_emitcode ("pop", "dpx");
2935 if (!inExcludeList("dph"))
2936 pic16_emitcode ("pop","dph");
2937 if (!inExcludeList("dpl"))
2938 pic16_emitcode ("pop","dpl");
2939 if (!inExcludeList("b"))
2940 pic16_emitcode ("pop","b");
2941 if (!inExcludeList("acc"))
2942 pic16_emitcode ("pop","acc");
2944 if (IFFUNC_ISCRITICAL(sym->type))
2945 pic16_emitcode("setb","ea");
2948 /* if debug then send end of function */
2949 /* if (options.debug && currFunc) { */
2952 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2953 FileBaseName(ic->filename),currFunc->lastLine,
2954 ic->level,ic->block);
2955 if (IS_STATIC(currFunc->etype))
2956 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2958 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2962 // pic16_emitcode ("reti","");
2964 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2965 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2966 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
2967 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
2968 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2971 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2974 pic16_emitpcodeNULLop(POC_RETFIE);
2978 if (IFFUNC_ISCRITICAL(sym->type))
2979 pic16_emitcode("setb","ea");
2981 if (IFFUNC_CALLEESAVES(sym->type)) {
2984 /* if any registers used */
2985 if (sym->regsUsed) {
2986 /* save the registers used */
2987 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2988 if (bitVectBitValue(sym->regsUsed,i) ||
2989 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2990 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2996 /* if debug then send end of function */
2999 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3000 FileBaseName(ic->filename),currFunc->lastLine,
3001 ic->level,ic->block);
3002 if (IS_STATIC(currFunc->etype))
3003 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3005 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3009 pic16_emitcode ("return","");
3010 pic16_emitpcodeNULLop(POC_RETURN);
3012 /* Mark the end of a function */
3013 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3018 /*-----------------------------------------------------------------*/
3019 /* genRet - generate code for return statement */
3020 /*-----------------------------------------------------------------*/
3021 static void genRet (iCode *ic)
3023 int size,offset = 0 , pushed = 0;
3025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3026 /* if we have no return value then
3027 just generate the "ret" */
3031 /* we have something to return then
3032 move the return value into place */
3033 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3034 size = AOP_SIZE(IC_LEFT(ic));
3038 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3040 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3042 pic16_emitcode("push","%s",l);
3045 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3047 if (strcmp(fReturn[offset],l)) {
3048 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3049 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3050 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3052 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3055 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3065 if (strcmp(fReturn[pushed],"a"))
3066 pic16_emitcode("pop",fReturn[pushed]);
3068 pic16_emitcode("pop","acc");
3071 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3074 /* generate a jump to the return label
3075 if the next is not the return statement */
3076 if (!(ic->next && ic->next->op == LABEL &&
3077 IC_LABEL(ic->next) == returnLabel)) {
3079 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3080 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3085 /*-----------------------------------------------------------------*/
3086 /* genLabel - generates a label */
3087 /*-----------------------------------------------------------------*/
3088 static void genLabel (iCode *ic)
3090 /* special case never generate */
3091 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3092 if (IC_LABEL(ic) == entryLabel)
3095 pic16_emitpLabel(IC_LABEL(ic)->key);
3096 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3099 /*-----------------------------------------------------------------*/
3100 /* genGoto - generates a goto */
3101 /*-----------------------------------------------------------------*/
3103 static void genGoto (iCode *ic)
3105 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3106 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3110 /*-----------------------------------------------------------------*/
3111 /* genMultbits :- multiplication of bits */
3112 /*-----------------------------------------------------------------*/
3113 static void genMultbits (operand *left,
3117 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3119 if(!pic16_sameRegs(AOP(result),AOP(right)))
3120 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3122 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3123 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3124 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3129 /*-----------------------------------------------------------------*/
3130 /* genMultOneByte : 8 bit multiplication & division */
3131 /*-----------------------------------------------------------------*/
3132 static void genMultOneByte (operand *left,
3136 sym_link *opetype = operandType(result);
3141 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3142 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3143 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3145 /* (if two literals, the value is computed before) */
3146 /* if one literal, literal on the right */
3147 if (AOP_TYPE(left) == AOP_LIT){
3153 size = AOP_SIZE(result);
3156 if (AOP_TYPE(right) == AOP_LIT){
3157 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3158 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3159 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3160 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3161 pic16_emitcode("call","genMultLit");
3163 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3164 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3165 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3166 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3167 pic16_emitcode("call","pic16_genMult8X8_8");
3170 pic16_genMult8X8_8 (left, right,result);
3173 /* signed or unsigned */
3174 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3175 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3177 //pic16_emitcode("mul","ab");
3178 /* if result size = 1, mul signed = mul unsigned */
3179 //pic16_aopPut(AOP(result),"a",0);
3181 } else { // (size > 1)
3183 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3184 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3185 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3186 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3188 if (SPEC_USIGN(opetype)){
3189 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3190 pic16_genUMult8X8_16 (left, right, result, NULL);
3193 /* for filling the MSBs */
3194 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3195 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3199 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3201 pic16_emitcode("mov","a,b");
3203 /* adjust the MSB if left or right neg */
3205 /* if one literal */
3206 if (AOP_TYPE(right) == AOP_LIT){
3207 pic16_emitcode("multiply ","right is a lit");
3208 /* AND literal negative */
3209 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3210 /* adjust MSB (c==0 after mul) */
3211 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3215 pic16_genSMult8X8_16 (left, right, result, NULL);
3219 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3221 pic16_emitcode("rlc","a");
3222 pic16_emitcode("subb","a,acc");
3230 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3231 //pic16_aopPut(AOP(result),"a",offset++);
3235 /*-----------------------------------------------------------------*/
3236 /* genMult - generates code for multiplication */
3237 /*-----------------------------------------------------------------*/
3238 static void genMult (iCode *ic)
3240 operand *left = IC_LEFT(ic);
3241 operand *right = IC_RIGHT(ic);
3242 operand *result= IC_RESULT(ic);
3244 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3245 /* assign the amsops */
3246 pic16_aopOp (left,ic,FALSE);
3247 pic16_aopOp (right,ic,FALSE);
3248 pic16_aopOp (result,ic,TRUE);
3250 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3252 /* special cases first */
3254 if (AOP_TYPE(left) == AOP_CRY &&
3255 AOP_TYPE(right)== AOP_CRY) {
3256 genMultbits(left,right,result);
3260 /* if both are of size == 1 */
3261 if (AOP_SIZE(left) == 1 &&
3262 AOP_SIZE(right) == 1 ) {
3263 genMultOneByte(left,right,result);
3267 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3269 /* should have been converted to function call */
3273 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3274 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3275 pic16_freeAsmop(result,NULL,ic,TRUE);
3278 /*-----------------------------------------------------------------*/
3279 /* genDivbits :- division of bits */
3280 /*-----------------------------------------------------------------*/
3281 static void genDivbits (operand *left,
3288 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3289 /* the result must be bit */
3290 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3291 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3295 pic16_emitcode("div","ab");
3296 pic16_emitcode("rrc","a");
3297 pic16_aopPut(AOP(result),"c",0);
3300 /*-----------------------------------------------------------------*/
3301 /* genDivOneByte : 8 bit division */
3302 /*-----------------------------------------------------------------*/
3303 static void genDivOneByte (operand *left,
3307 sym_link *opetype = operandType(result);
3312 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3313 size = AOP_SIZE(result) - 1;
3315 /* signed or unsigned */
3316 if (SPEC_USIGN(opetype)) {
3317 /* unsigned is easy */
3318 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3319 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3321 pic16_emitcode("div","ab");
3322 pic16_aopPut(AOP(result),"a",0);
3324 pic16_aopPut(AOP(result),zero,offset++);
3328 /* signed is a little bit more difficult */
3330 /* save the signs of the operands */
3331 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3333 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3334 pic16_emitcode("push","acc"); /* save it on the stack */
3336 /* now sign adjust for both left & right */
3337 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3339 lbl = newiTempLabel(NULL);
3340 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3341 pic16_emitcode("cpl","a");
3342 pic16_emitcode("inc","a");
3343 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3344 pic16_emitcode("mov","b,a");
3346 /* sign adjust left side */
3347 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3350 lbl = newiTempLabel(NULL);
3351 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3352 pic16_emitcode("cpl","a");
3353 pic16_emitcode("inc","a");
3354 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3356 /* now the division */
3357 pic16_emitcode("div","ab");
3358 /* we are interested in the lower order
3360 pic16_emitcode("mov","b,a");
3361 lbl = newiTempLabel(NULL);
3362 pic16_emitcode("pop","acc");
3363 /* if there was an over flow we don't
3364 adjust the sign of the result */
3365 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3366 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3368 pic16_emitcode("clr","a");
3369 pic16_emitcode("subb","a,b");
3370 pic16_emitcode("mov","b,a");
3371 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3373 /* now we are done */
3374 pic16_aopPut(AOP(result),"b",0);
3376 pic16_emitcode("mov","c,b.7");
3377 pic16_emitcode("subb","a,acc");
3380 pic16_aopPut(AOP(result),"a",offset++);
3384 /*-----------------------------------------------------------------*/
3385 /* genDiv - generates code for division */
3386 /*-----------------------------------------------------------------*/
3387 static void genDiv (iCode *ic)
3389 operand *left = IC_LEFT(ic);
3390 operand *right = IC_RIGHT(ic);
3391 operand *result= IC_RESULT(ic);
3393 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3394 /* assign the amsops */
3395 pic16_aopOp (left,ic,FALSE);
3396 pic16_aopOp (right,ic,FALSE);
3397 pic16_aopOp (result,ic,TRUE);
3399 /* special cases first */
3401 if (AOP_TYPE(left) == AOP_CRY &&
3402 AOP_TYPE(right)== AOP_CRY) {
3403 genDivbits(left,right,result);
3407 /* if both are of size == 1 */
3408 if (AOP_SIZE(left) == 1 &&
3409 AOP_SIZE(right) == 1 ) {
3410 genDivOneByte(left,right,result);
3414 /* should have been converted to function call */
3417 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3418 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3419 pic16_freeAsmop(result,NULL,ic,TRUE);
3422 /*-----------------------------------------------------------------*/
3423 /* genModbits :- modulus of bits */
3424 /*-----------------------------------------------------------------*/
3425 static void genModbits (operand *left,
3432 /* the result must be bit */
3433 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3434 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3438 pic16_emitcode("div","ab");
3439 pic16_emitcode("mov","a,b");
3440 pic16_emitcode("rrc","a");
3441 pic16_aopPut(AOP(result),"c",0);
3444 /*-----------------------------------------------------------------*/
3445 /* genModOneByte : 8 bit modulus */
3446 /*-----------------------------------------------------------------*/
3447 static void genModOneByte (operand *left,
3451 sym_link *opetype = operandType(result);
3455 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3456 /* signed or unsigned */
3457 if (SPEC_USIGN(opetype)) {
3458 /* unsigned is easy */
3459 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3460 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3462 pic16_emitcode("div","ab");
3463 pic16_aopPut(AOP(result),"b",0);
3467 /* signed is a little bit more difficult */
3469 /* save the signs of the operands */
3470 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3473 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3474 pic16_emitcode("push","acc"); /* save it on the stack */
3476 /* now sign adjust for both left & right */
3477 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3480 lbl = newiTempLabel(NULL);
3481 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3482 pic16_emitcode("cpl","a");
3483 pic16_emitcode("inc","a");
3484 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3485 pic16_emitcode("mov","b,a");
3487 /* sign adjust left side */
3488 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3491 lbl = newiTempLabel(NULL);
3492 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3493 pic16_emitcode("cpl","a");
3494 pic16_emitcode("inc","a");
3495 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3497 /* now the multiplication */
3498 pic16_emitcode("div","ab");
3499 /* we are interested in the lower order
3501 lbl = newiTempLabel(NULL);
3502 pic16_emitcode("pop","acc");
3503 /* if there was an over flow we don't
3504 adjust the sign of the result */
3505 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3506 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3508 pic16_emitcode("clr","a");
3509 pic16_emitcode("subb","a,b");
3510 pic16_emitcode("mov","b,a");
3511 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3513 /* now we are done */
3514 pic16_aopPut(AOP(result),"b",0);
3518 /*-----------------------------------------------------------------*/
3519 /* genMod - generates code for division */
3520 /*-----------------------------------------------------------------*/
3521 static void genMod (iCode *ic)
3523 operand *left = IC_LEFT(ic);
3524 operand *right = IC_RIGHT(ic);
3525 operand *result= IC_RESULT(ic);
3527 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3528 /* assign the amsops */
3529 pic16_aopOp (left,ic,FALSE);
3530 pic16_aopOp (right,ic,FALSE);
3531 pic16_aopOp (result,ic,TRUE);
3533 /* special cases first */
3535 if (AOP_TYPE(left) == AOP_CRY &&
3536 AOP_TYPE(right)== AOP_CRY) {
3537 genModbits(left,right,result);
3541 /* if both are of size == 1 */
3542 if (AOP_SIZE(left) == 1 &&
3543 AOP_SIZE(right) == 1 ) {
3544 genModOneByte(left,right,result);
3548 /* should have been converted to function call */
3552 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3553 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3554 pic16_freeAsmop(result,NULL,ic,TRUE);
3557 /*-----------------------------------------------------------------*/
3558 /* genIfxJump :- will create a jump depending on the ifx */
3559 /*-----------------------------------------------------------------*/
3561 note: May need to add parameter to indicate when a variable is in bit space.
3563 static void genIfxJump (iCode *ic, char *jval)
3566 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3567 /* if true label then we jump if condition
3569 if ( IC_TRUE(ic) ) {
3571 if(strcmp(jval,"a") == 0)
3573 else if (strcmp(jval,"c") == 0)
3576 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3577 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3580 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3581 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3585 /* false label is present */
3586 if(strcmp(jval,"a") == 0)
3588 else if (strcmp(jval,"c") == 0)
3591 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3592 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3595 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3596 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3601 /* mark the icode as generated */
3605 /*-----------------------------------------------------------------*/
3607 /*-----------------------------------------------------------------*/
3608 static void genSkip(iCode *ifx,int status_bit)
3613 if ( IC_TRUE(ifx) ) {
3614 switch(status_bit) {
3629 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3630 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3634 switch(status_bit) {
3648 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3649 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3655 /*-----------------------------------------------------------------*/
3657 /*-----------------------------------------------------------------*/
3658 static void genSkipc(resolvedIfx *rifx)
3668 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3669 rifx->generated = 1;
3672 /*-----------------------------------------------------------------*/
3674 /*-----------------------------------------------------------------*/
3675 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3680 if( (rifx->condition ^ invert_condition) & 1)
3685 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3686 rifx->generated = 1;
3689 /*-----------------------------------------------------------------*/
3691 /*-----------------------------------------------------------------*/
3692 static void genSkipz(iCode *ifx, int condition)
3703 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3705 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3708 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3710 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3713 /*-----------------------------------------------------------------*/
3715 /*-----------------------------------------------------------------*/
3716 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3722 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3724 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3727 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3728 rifx->generated = 1;
3732 /*-----------------------------------------------------------------*/
3733 /* genChkZeroes :- greater or less than comparison */
3734 /* For each byte in a literal that is zero, inclusive or the */
3735 /* the corresponding byte in the operand with W */
3736 /* returns true if any of the bytes are zero */
3737 /*-----------------------------------------------------------------*/
3738 static int genChkZeroes(operand *op, int lit, int size)
3745 i = (lit >> (size*8)) & 0xff;
3749 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3751 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3760 /*-----------------------------------------------------------------*/
3761 /* genCmp :- greater or less than comparison */
3762 /*-----------------------------------------------------------------*/
3763 static void genCmp (operand *left,operand *right,
3764 operand *result, iCode *ifx, int sign)
3766 int size; //, offset = 0 ;
3767 unsigned long lit = 0L,i = 0;
3768 resolvedIfx rFalseIfx;
3769 // resolvedIfx rTrueIfx;
3771 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3774 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3775 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3779 resolveIfx(&rFalseIfx,ifx);
3780 truelbl = newiTempLabel(NULL);
3781 size = max(AOP_SIZE(left),AOP_SIZE(right));
3783 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3787 /* if literal is on the right then swap with left */
3788 if ((AOP_TYPE(right) == AOP_LIT)) {
3789 operand *tmp = right ;
3790 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3791 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3794 lit = (lit - 1) & mask;
3797 rFalseIfx.condition ^= 1;
3800 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3801 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3805 //if(IC_TRUE(ifx) == NULL)
3806 /* if left & right are bit variables */
3807 if (AOP_TYPE(left) == AOP_CRY &&
3808 AOP_TYPE(right) == AOP_CRY ) {
3809 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3810 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3812 /* subtract right from left if at the
3813 end the carry flag is set then we know that
3814 left is greater than right */
3818 symbol *lbl = newiTempLabel(NULL);
3821 if(AOP_TYPE(right) == AOP_LIT) {
3823 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3825 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3832 genSkipCond(&rFalseIfx,left,size-1,7);
3834 /* no need to compare to 0...*/
3835 /* NOTE: this is a de-generate compare that most certainly
3836 * creates some dead code. */
3837 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3839 if(ifx) ifx->generated = 1;
3846 //i = (lit >> (size*8)) & 0xff;
3847 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3849 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3851 i = ((0-lit) & 0xff);
3854 /* lit is 0x7f, all signed chars are less than
3855 * this except for 0x7f itself */
3856 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3857 genSkipz2(&rFalseIfx,0);
3859 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3860 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3861 genSkipc(&rFalseIfx);
3866 genSkipz2(&rFalseIfx,1);
3868 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3869 genSkipc(&rFalseIfx);
3873 if(ifx) ifx->generated = 1;
3877 /* chars are out of the way. now do ints and longs */
3880 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3887 genSkipCond(&rFalseIfx,left,size,7);
3888 if(ifx) ifx->generated = 1;
3893 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3895 //rFalseIfx.condition ^= 1;
3896 //genSkipCond(&rFalseIfx,left,size,7);
3897 //rFalseIfx.condition ^= 1;
3899 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3900 if(rFalseIfx.condition)
3901 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3903 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3905 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3906 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3907 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3910 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3912 if(rFalseIfx.condition) {
3914 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3920 genSkipc(&rFalseIfx);
3921 pic16_emitpLabel(truelbl->key);
3922 if(ifx) ifx->generated = 1;
3929 if( (lit & 0xff) == 0) {
3930 /* lower byte is zero */
3931 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3932 i = ((lit >> 8) & 0xff) ^0x80;
3933 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3934 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3935 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3936 genSkipc(&rFalseIfx);
3939 if(ifx) ifx->generated = 1;
3944 /* Special cases for signed longs */
3945 if( (lit & 0xffffff) == 0) {
3946 /* lower byte is zero */
3947 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3948 i = ((lit >> 8*3) & 0xff) ^0x80;
3949 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3950 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3951 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3952 genSkipc(&rFalseIfx);
3955 if(ifx) ifx->generated = 1;
3963 if(lit & (0x80 << (size*8))) {
3964 /* lit is negative */
3965 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3967 //genSkipCond(&rFalseIfx,left,size,7);
3969 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3971 if(rFalseIfx.condition)
3972 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3974 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3978 /* lit is positive */
3979 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3980 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3981 if(rFalseIfx.condition)
3982 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3984 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3989 This works, but is only good for ints.
3990 It also requires a "known zero" register.
3991 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3992 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3993 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
3994 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3995 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3996 genSkipc(&rFalseIfx);
3998 pic16_emitpLabel(truelbl->key);
3999 if(ifx) ifx->generated = 1;
4003 /* There are no more special cases, so perform a general compare */
4005 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4006 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4010 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4012 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4014 //rFalseIfx.condition ^= 1;
4015 genSkipc(&rFalseIfx);
4017 pic16_emitpLabel(truelbl->key);
4019 if(ifx) ifx->generated = 1;
4026 /* sign is out of the way. So now do an unsigned compare */
4027 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4030 /* General case - compare to an unsigned literal on the right.*/
4032 i = (lit >> (size*8)) & 0xff;
4033 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4034 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4036 i = (lit >> (size*8)) & 0xff;
4039 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4041 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4043 /* this byte of the lit is zero,
4044 *if it's not the last then OR in the variable */
4046 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4051 pic16_emitpLabel(lbl->key);
4052 //if(emitFinalCheck)
4053 genSkipc(&rFalseIfx);
4055 pic16_emitpLabel(truelbl->key);
4057 if(ifx) ifx->generated = 1;
4064 if(AOP_TYPE(left) == AOP_LIT) {
4065 //symbol *lbl = newiTempLabel(NULL);
4067 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4070 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4073 if((lit == 0) && (sign == 0)){
4076 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4078 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4080 genSkipz2(&rFalseIfx,0);
4081 if(ifx) ifx->generated = 1;
4088 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4089 /* degenerate compare can never be true */
4090 if(rFalseIfx.condition == 0)
4091 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4093 if(ifx) ifx->generated = 1;
4098 /* signed comparisons to a literal byte */
4100 int lp1 = (lit+1) & 0xff;
4102 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4105 rFalseIfx.condition ^= 1;
4106 genSkipCond(&rFalseIfx,right,0,7);
4109 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4110 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4111 genSkipz2(&rFalseIfx,1);
4114 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4115 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4116 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4117 rFalseIfx.condition ^= 1;
4118 genSkipc(&rFalseIfx);
4122 /* unsigned comparisons to a literal byte */
4124 switch(lit & 0xff ) {
4126 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4127 genSkipz2(&rFalseIfx,0);
4130 rFalseIfx.condition ^= 1;
4131 genSkipCond(&rFalseIfx,right,0,7);
4135 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4136 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4137 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4138 rFalseIfx.condition ^= 1;
4139 if (AOP_TYPE(result) == AOP_CRY)
4140 genSkipc(&rFalseIfx);
4142 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4143 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4149 if(ifx) ifx->generated = 1;
4155 /* Size is greater than 1 */
4163 /* this means lit = 0xffffffff, or -1 */
4166 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4167 rFalseIfx.condition ^= 1;
4168 genSkipCond(&rFalseIfx,right,size,7);
4169 if(ifx) ifx->generated = 1;
4176 if(rFalseIfx.condition) {
4177 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4178 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4181 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4183 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4187 if(rFalseIfx.condition) {
4188 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4189 pic16_emitpLabel(truelbl->key);
4191 rFalseIfx.condition ^= 1;
4192 genSkipCond(&rFalseIfx,right,s,7);
4195 if(ifx) ifx->generated = 1;
4199 if((size == 1) && (0 == (lp1&0xff))) {
4200 /* lower byte of signed word is zero */
4201 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4202 i = ((lp1 >> 8) & 0xff) ^0x80;
4203 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4204 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4205 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4206 rFalseIfx.condition ^= 1;
4207 genSkipc(&rFalseIfx);
4210 if(ifx) ifx->generated = 1;
4214 if(lit & (0x80 << (size*8))) {
4215 /* Lit is less than zero */
4216 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4217 //rFalseIfx.condition ^= 1;
4218 //genSkipCond(&rFalseIfx,left,size,7);
4219 //rFalseIfx.condition ^= 1;
4220 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4221 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4223 if(rFalseIfx.condition)
4224 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4226 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4230 /* Lit is greater than or equal to zero */
4231 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4232 //rFalseIfx.condition ^= 1;
4233 //genSkipCond(&rFalseIfx,right,size,7);
4234 //rFalseIfx.condition ^= 1;
4236 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4237 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4239 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4240 if(rFalseIfx.condition)
4241 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4243 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4248 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4249 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4253 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4255 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4257 rFalseIfx.condition ^= 1;
4258 //rFalseIfx.condition = 1;
4259 genSkipc(&rFalseIfx);
4261 pic16_emitpLabel(truelbl->key);
4263 if(ifx) ifx->generated = 1;
4268 /* compare word or long to an unsigned literal on the right.*/
4273 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4276 break; /* handled above */
4279 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4281 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4282 genSkipz2(&rFalseIfx,0);
4286 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4288 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4291 if(rFalseIfx.condition)
4292 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4294 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4297 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4298 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4300 rFalseIfx.condition ^= 1;
4301 genSkipc(&rFalseIfx);
4304 pic16_emitpLabel(truelbl->key);
4306 if(ifx) ifx->generated = 1;
4312 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4313 i = (lit >> (size*8)) & 0xff;
4315 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4316 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4319 i = (lit >> (size*8)) & 0xff;
4322 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4324 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4326 /* this byte of the lit is zero,
4327 *if it's not the last then OR in the variable */
4329 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4334 pic16_emitpLabel(lbl->key);
4336 rFalseIfx.condition ^= 1;
4337 genSkipc(&rFalseIfx);
4341 pic16_emitpLabel(truelbl->key);
4342 if(ifx) ifx->generated = 1;
4346 /* Compare two variables */
4348 DEBUGpic16_emitcode(";sign","%d",sign);
4352 /* Sigh. thus sucks... */
4354 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4355 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4356 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4357 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4358 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4359 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4361 /* Signed char comparison */
4362 /* Special thanks to Nikolai Golovchenko for this snippet */
4363 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4364 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4365 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4366 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4367 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4368 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4370 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4371 genSkipc(&rFalseIfx);
4373 if(ifx) ifx->generated = 1;
4379 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4380 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4384 /* The rest of the bytes of a multi-byte compare */
4388 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4391 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4392 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4397 pic16_emitpLabel(lbl->key);
4399 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4400 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4401 (AOP_TYPE(result) == AOP_REG)) {
4402 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4403 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4405 genSkipc(&rFalseIfx);
4407 //genSkipc(&rFalseIfx);
4408 if(ifx) ifx->generated = 1;
4415 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4416 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4417 pic16_outBitC(result);
4419 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4420 /* if the result is used in the next
4421 ifx conditional branch then generate
4422 code a little differently */
4424 genIfxJump (ifx,"c");
4426 pic16_outBitC(result);
4427 /* leave the result in acc */
4432 /*-----------------------------------------------------------------*/
4433 /* genCmpGt :- greater than comparison */
4434 /*-----------------------------------------------------------------*/
4435 static void genCmpGt (iCode *ic, iCode *ifx)
4437 operand *left, *right, *result;
4438 sym_link *letype , *retype;
4441 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4443 right= IC_RIGHT(ic);
4444 result = IC_RESULT(ic);
4446 letype = getSpec(operandType(left));
4447 retype =getSpec(operandType(right));
4448 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4449 /* assign the amsops */
4450 pic16_aopOp (left,ic,FALSE);
4451 pic16_aopOp (right,ic,FALSE);
4452 pic16_aopOp (result,ic,TRUE);
4454 genCmp(right, left, result, ifx, sign);
4456 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4457 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4458 pic16_freeAsmop(result,NULL,ic,TRUE);
4461 /*-----------------------------------------------------------------*/
4462 /* genCmpLt - less than comparisons */
4463 /*-----------------------------------------------------------------*/
4464 static void genCmpLt (iCode *ic, iCode *ifx)
4466 operand *left, *right, *result;
4467 sym_link *letype , *retype;
4470 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4472 right= IC_RIGHT(ic);
4473 result = IC_RESULT(ic);
4475 letype = getSpec(operandType(left));
4476 retype =getSpec(operandType(right));
4477 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4479 /* assign the amsops */
4480 pic16_aopOp (left,ic,FALSE);
4481 pic16_aopOp (right,ic,FALSE);
4482 pic16_aopOp (result,ic,TRUE);
4484 genCmp(left, right, result, ifx, sign);
4486 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4487 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4488 pic16_freeAsmop(result,NULL,ic,TRUE);
4491 /*-----------------------------------------------------------------*/
4492 /* genc16bit2lit - compare a 16 bit value to a literal */
4493 /*-----------------------------------------------------------------*/
4494 static void genc16bit2lit(operand *op, int lit, int offset)
4498 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4499 if( (lit&0xff) == 0)
4504 switch( BYTEofLONG(lit,i)) {
4506 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4509 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4512 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4515 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4516 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4521 switch( BYTEofLONG(lit,i)) {
4523 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4527 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4531 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4534 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4536 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4542 /*-----------------------------------------------------------------*/
4543 /* gencjneshort - compare and jump if not equal */
4544 /*-----------------------------------------------------------------*/
4545 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4547 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4549 int res_offset = 0; /* the result may be a different size then left or right */
4550 int res_size = AOP_SIZE(result);
4554 unsigned long lit = 0L;
4555 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4556 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4558 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4559 resolveIfx(&rIfx,ifx);
4560 lbl = newiTempLabel(NULL);
4563 /* if the left side is a literal or
4564 if the right is in a pointer register and left
4566 if ((AOP_TYPE(left) == AOP_LIT) ||
4567 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4572 if(AOP_TYPE(right) == AOP_LIT)
4573 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4575 /* if the right side is a literal then anything goes */
4576 if (AOP_TYPE(right) == AOP_LIT &&
4577 AOP_TYPE(left) != AOP_DIR ) {
4580 genc16bit2lit(left, lit, 0);
4582 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4587 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4588 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4590 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4594 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4596 if(res_offset < res_size-1)
4604 /* if the right side is in a register or in direct space or
4605 if the left is a pointer register & right is not */
4606 else if (AOP_TYPE(right) == AOP_REG ||
4607 AOP_TYPE(right) == AOP_DIR ||
4608 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4609 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4610 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4611 int lbl_key = lbl->key;
4614 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4615 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4617 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4618 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4619 __FUNCTION__,__LINE__);
4623 /* switch(size) { */
4625 /* genc16bit2lit(left, lit, 0); */
4627 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4632 if((AOP_TYPE(left) == AOP_DIR) &&
4633 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4635 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4636 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4638 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4640 switch (lit & 0xff) {
4642 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4645 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4646 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4647 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4651 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4652 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4653 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4654 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4658 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4659 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4664 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4667 if(AOP_TYPE(result) == AOP_CRY) {
4668 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4673 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4675 /* fix me. probably need to check result size too */
4676 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4681 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4682 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4689 if(res_offset < res_size-1)
4694 } else if(AOP_TYPE(right) == AOP_REG &&
4695 AOP_TYPE(left) != AOP_DIR){
4698 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4699 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4700 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4705 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4707 if(res_offset < res_size-1)
4712 /* right is a pointer reg need both a & b */
4714 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4716 pic16_emitcode("mov","b,%s",l);
4717 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4718 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4723 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4725 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4727 pic16_emitpLabel(lbl->key);
4729 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4736 /*-----------------------------------------------------------------*/
4737 /* gencjne - compare and jump if not equal */
4738 /*-----------------------------------------------------------------*/
4739 static void gencjne(operand *left, operand *right, iCode *ifx)
4741 symbol *tlbl = newiTempLabel(NULL);
4743 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4744 gencjneshort(left, right, lbl);
4746 pic16_emitcode("mov","a,%s",one);
4747 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4748 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4749 pic16_emitcode("clr","a");
4750 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4752 pic16_emitpLabel(lbl->key);
4753 pic16_emitpLabel(tlbl->key);
4758 /*-----------------------------------------------------------------*/
4759 /* genCmpEq - generates code for equal to */
4760 /*-----------------------------------------------------------------*/
4761 static void genCmpEq (iCode *ic, iCode *ifx)
4763 operand *left, *right, *result;
4764 unsigned long lit = 0L;
4767 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4770 DEBUGpic16_emitcode ("; ifx is non-null","");
4772 DEBUGpic16_emitcode ("; ifx is null","");
4774 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4775 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4776 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4778 size = max(AOP_SIZE(left),AOP_SIZE(right));
4780 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4782 /* if literal, literal on the right or
4783 if the right is in a pointer register and left
4785 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4786 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4787 operand *tmp = right ;
4793 if(ifx && !AOP_SIZE(result)){
4795 /* if they are both bit variables */
4796 if (AOP_TYPE(left) == AOP_CRY &&
4797 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4798 if(AOP_TYPE(right) == AOP_LIT){
4799 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4801 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4802 pic16_emitcode("cpl","c");
4803 } else if(lit == 1L) {
4804 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4806 pic16_emitcode("clr","c");
4808 /* AOP_TYPE(right) == AOP_CRY */
4810 symbol *lbl = newiTempLabel(NULL);
4811 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4812 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4813 pic16_emitcode("cpl","c");
4814 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4816 /* if true label then we jump if condition
4818 tlbl = newiTempLabel(NULL);
4819 if ( IC_TRUE(ifx) ) {
4820 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4821 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4823 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4824 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4826 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4829 /* left and right are both bit variables, result is carry */
4832 resolveIfx(&rIfx,ifx);
4834 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4835 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4836 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4837 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4842 /* They're not both bit variables. Is the right a literal? */
4843 if(AOP_TYPE(right) == AOP_LIT) {
4844 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4849 switch(lit & 0xff) {
4851 if ( IC_TRUE(ifx) ) {
4852 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4854 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4856 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4857 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4861 if ( IC_TRUE(ifx) ) {
4862 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4864 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4866 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4867 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4871 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4873 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4878 /* end of size == 1 */
4882 genc16bit2lit(left,lit,offset);
4885 /* end of size == 2 */
4890 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4891 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4892 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4893 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4897 /* search for patterns that can be optimized */
4899 genc16bit2lit(left,lit,0);
4902 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4904 genc16bit2lit(left,lit,2);
4906 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4907 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4920 } else if(AOP_TYPE(right) == AOP_CRY ) {
4921 /* we know the left is not a bit, but that the right is */
4922 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4923 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4924 pic16_popGet(AOP(right),offset));
4925 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4927 /* if the two are equal, then W will be 0 and the Z bit is set
4928 * we could test Z now, or go ahead and check the high order bytes if
4929 * the variable we're comparing is larger than a byte. */
4932 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4934 if ( IC_TRUE(ifx) ) {
4936 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4937 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4940 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4941 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4945 /* They're both variables that are larger than bits */
4948 tlbl = newiTempLabel(NULL);
4951 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4952 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4954 if ( IC_TRUE(ifx) ) {
4957 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4958 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4961 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4962 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4966 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4967 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4971 if(s>1 && IC_TRUE(ifx)) {
4972 pic16_emitpLabel(tlbl->key);
4973 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4977 /* mark the icode as generated */
4982 /* if they are both bit variables */
4983 if (AOP_TYPE(left) == AOP_CRY &&
4984 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4985 if(AOP_TYPE(right) == AOP_LIT){
4986 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4988 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4989 pic16_emitcode("cpl","c");
4990 } else if(lit == 1L) {
4991 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4993 pic16_emitcode("clr","c");
4995 /* AOP_TYPE(right) == AOP_CRY */
4997 symbol *lbl = newiTempLabel(NULL);
4998 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4999 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5000 pic16_emitcode("cpl","c");
5001 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5004 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5005 pic16_outBitC(result);
5009 genIfxJump (ifx,"c");
5012 /* if the result is used in an arithmetic operation
5013 then put the result in place */
5014 pic16_outBitC(result);
5017 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5018 gencjne(left,right,result,ifx);
5021 gencjne(left,right,newiTempLabel(NULL));
5023 if(IC_TRUE(ifx)->key)
5024 gencjne(left,right,IC_TRUE(ifx)->key);
5026 gencjne(left,right,IC_FALSE(ifx)->key);
5030 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5031 pic16_aopPut(AOP(result),"a",0);
5036 genIfxJump (ifx,"a");
5040 /* if the result is used in an arithmetic operation
5041 then put the result in place */
5043 if (AOP_TYPE(result) != AOP_CRY)
5044 pic16_outAcc(result);
5046 /* leave the result in acc */
5050 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5051 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5052 pic16_freeAsmop(result,NULL,ic,TRUE);
5055 /*-----------------------------------------------------------------*/
5056 /* ifxForOp - returns the icode containing the ifx for operand */
5057 /*-----------------------------------------------------------------*/
5058 static iCode *ifxForOp ( operand *op, iCode *ic )
5060 /* if true symbol then needs to be assigned */
5061 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5062 if (IS_TRUE_SYMOP(op))
5065 /* if this has register type condition and
5066 the next instruction is ifx with the same operand
5067 and live to of the operand is upto the ifx only then */
5069 ic->next->op == IFX &&
5070 IC_COND(ic->next)->key == op->key &&
5071 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5075 ic->next->op == IFX &&
5076 IC_COND(ic->next)->key == op->key) {
5077 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5081 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5083 ic->next->op == IFX)
5084 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5087 ic->next->op == IFX &&
5088 IC_COND(ic->next)->key == op->key) {
5089 DEBUGpic16_emitcode ("; "," key is okay");
5090 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5091 OP_SYMBOL(op)->liveTo,
5098 /*-----------------------------------------------------------------*/
5099 /* genAndOp - for && operation */
5100 /*-----------------------------------------------------------------*/
5101 static void genAndOp (iCode *ic)
5103 operand *left,*right, *result;
5106 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5107 /* note here that && operations that are in an
5108 if statement are taken away by backPatchLabels
5109 only those used in arthmetic operations remain */
5110 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5111 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5112 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5114 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5116 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5117 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5118 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5120 /* if both are bit variables */
5121 /* if (AOP_TYPE(left) == AOP_CRY && */
5122 /* AOP_TYPE(right) == AOP_CRY ) { */
5123 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5124 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5125 /* pic16_outBitC(result); */
5127 /* tlbl = newiTempLabel(NULL); */
5128 /* pic16_toBoolean(left); */
5129 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5130 /* pic16_toBoolean(right); */
5131 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5132 /* pic16_outBitAcc(result); */
5135 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5136 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5137 pic16_freeAsmop(result,NULL,ic,TRUE);
5141 /*-----------------------------------------------------------------*/
5142 /* genOrOp - for || operation */
5143 /*-----------------------------------------------------------------*/
5146 modified this code, but it doesn't appear to ever get called
5149 static void genOrOp (iCode *ic)
5151 operand *left,*right, *result;
5154 /* note here that || operations that are in an
5155 if statement are taken away by backPatchLabels
5156 only those used in arthmetic operations remain */
5157 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5158 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5159 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5160 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5162 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5164 /* if both are bit variables */
5165 if (AOP_TYPE(left) == AOP_CRY &&
5166 AOP_TYPE(right) == AOP_CRY ) {
5167 pic16_emitcode("clrc","");
5168 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5169 AOP(left)->aopu.aop_dir,
5170 AOP(left)->aopu.aop_dir);
5171 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5172 AOP(right)->aopu.aop_dir,
5173 AOP(right)->aopu.aop_dir);
5174 pic16_emitcode("setc","");
5177 tlbl = newiTempLabel(NULL);
5178 pic16_toBoolean(left);
5180 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5181 pic16_toBoolean(right);
5182 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5184 pic16_outBitAcc(result);
5187 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5188 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5189 pic16_freeAsmop(result,NULL,ic,TRUE);
5192 /*-----------------------------------------------------------------*/
5193 /* isLiteralBit - test if lit == 2^n */
5194 /*-----------------------------------------------------------------*/
5195 static int isLiteralBit(unsigned long lit)
5197 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5198 0x100L,0x200L,0x400L,0x800L,
5199 0x1000L,0x2000L,0x4000L,0x8000L,
5200 0x10000L,0x20000L,0x40000L,0x80000L,
5201 0x100000L,0x200000L,0x400000L,0x800000L,
5202 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5203 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5206 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5207 for(idx = 0; idx < 32; idx++)
5213 /*-----------------------------------------------------------------*/
5214 /* continueIfTrue - */
5215 /*-----------------------------------------------------------------*/
5216 static void continueIfTrue (iCode *ic)
5218 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5220 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5224 /*-----------------------------------------------------------------*/
5226 /*-----------------------------------------------------------------*/
5227 static void jumpIfTrue (iCode *ic)
5229 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5231 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5235 /*-----------------------------------------------------------------*/
5236 /* jmpTrueOrFalse - */
5237 /*-----------------------------------------------------------------*/
5238 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5240 // ugly but optimized by peephole
5241 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5243 symbol *nlbl = newiTempLabel(NULL);
5244 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5245 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5246 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5247 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5250 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5251 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5256 /*-----------------------------------------------------------------*/
5257 /* genAnd - code for and */
5258 /*-----------------------------------------------------------------*/
5259 static void genAnd (iCode *ic, iCode *ifx)
5261 operand *left, *right, *result;
5263 unsigned long lit = 0L;
5268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5269 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5270 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5271 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5273 resolveIfx(&rIfx,ifx);
5275 /* if left is a literal & right is not then exchange them */
5276 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5277 AOP_NEEDSACC(left)) {
5278 operand *tmp = right ;
5283 /* if result = right then exchange them */
5284 if(pic16_sameRegs(AOP(result),AOP(right))){
5285 operand *tmp = right ;
5290 /* if right is bit then exchange them */
5291 if (AOP_TYPE(right) == AOP_CRY &&
5292 AOP_TYPE(left) != AOP_CRY){
5293 operand *tmp = right ;
5297 if(AOP_TYPE(right) == AOP_LIT)
5298 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5300 size = AOP_SIZE(result);
5302 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5305 // result = bit & yy;
5306 if (AOP_TYPE(left) == AOP_CRY){
5307 // c = bit & literal;
5308 if(AOP_TYPE(right) == AOP_LIT){
5310 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5313 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5316 if(size && (AOP_TYPE(result) == AOP_CRY)){
5317 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5320 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5324 pic16_emitcode("clr","c");
5327 if (AOP_TYPE(right) == AOP_CRY){
5329 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5330 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5333 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5335 pic16_emitcode("rrc","a");
5336 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5342 pic16_outBitC(result);
5344 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5345 genIfxJump(ifx, "c");
5349 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5350 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5351 if((AOP_TYPE(right) == AOP_LIT) &&
5352 (AOP_TYPE(result) == AOP_CRY) &&
5353 (AOP_TYPE(left) != AOP_CRY)){
5354 int posbit = isLiteralBit(lit);
5358 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5361 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5367 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5368 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5370 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5371 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5374 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5375 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5376 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5383 symbol *tlbl = newiTempLabel(NULL);
5384 int sizel = AOP_SIZE(left);
5386 pic16_emitcode("setb","c");
5388 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5389 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5391 if((posbit = isLiteralBit(bytelit)) != 0)
5392 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5394 if(bytelit != 0x0FFL)
5395 pic16_emitcode("anl","a,%s",
5396 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5397 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5402 // bit = left & literal
5404 pic16_emitcode("clr","c");
5405 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5407 // if(left & literal)
5410 jmpTrueOrFalse(ifx, tlbl);
5414 pic16_outBitC(result);
5418 /* if left is same as result */
5419 if(pic16_sameRegs(AOP(result),AOP(left))){
5421 for(;size--; offset++,lit>>=8) {
5422 if(AOP_TYPE(right) == AOP_LIT){
5423 switch(lit & 0xff) {
5425 /* and'ing with 0 has clears the result */
5426 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5427 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5430 /* and'ing with 0xff is a nop when the result and left are the same */
5435 int p = my_powof2( (~lit) & 0xff );
5437 /* only one bit is set in the literal, so use a bcf instruction */
5438 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5439 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5442 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5443 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5444 if(know_W != (lit&0xff))
5445 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5447 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5452 if (AOP_TYPE(left) == AOP_ACC) {
5453 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5455 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5456 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5463 // left & result in different registers
5464 if(AOP_TYPE(result) == AOP_CRY){
5466 // if(size), result in bit
5467 // if(!size && ifx), conditional oper: if(left & right)
5468 symbol *tlbl = newiTempLabel(NULL);
5469 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5471 pic16_emitcode("setb","c");
5473 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5474 pic16_emitcode("anl","a,%s",
5475 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5476 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5481 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5482 pic16_outBitC(result);
5484 jmpTrueOrFalse(ifx, tlbl);
5486 for(;(size--);offset++) {
5488 // result = left & right
5489 if(AOP_TYPE(right) == AOP_LIT){
5490 int t = (lit >> (offset*8)) & 0x0FFL;
5493 pic16_emitcode("clrf","%s",
5494 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5495 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5498 pic16_emitcode("movf","%s,w",
5499 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5500 pic16_emitcode("movwf","%s",
5501 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5502 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5503 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5506 pic16_emitcode("movlw","0x%x",t);
5507 pic16_emitcode("andwf","%s,w",
5508 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5509 pic16_emitcode("movwf","%s",
5510 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5512 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5513 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5514 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5519 if (AOP_TYPE(left) == AOP_ACC) {
5520 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5521 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5523 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5524 pic16_emitcode("andwf","%s,w",
5525 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5526 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5527 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5529 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5530 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5536 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5537 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5538 pic16_freeAsmop(result,NULL,ic,TRUE);
5541 /*-----------------------------------------------------------------*/
5542 /* genOr - code for or */
5543 /*-----------------------------------------------------------------*/
5544 static void genOr (iCode *ic, iCode *ifx)
5546 operand *left, *right, *result;
5548 unsigned long lit = 0L;
5550 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5552 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5553 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5554 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5556 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5558 /* if left is a literal & right is not then exchange them */
5559 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5560 AOP_NEEDSACC(left)) {
5561 operand *tmp = right ;
5566 /* if result = right then exchange them */
5567 if(pic16_sameRegs(AOP(result),AOP(right))){
5568 operand *tmp = right ;
5573 /* if right is bit then exchange them */
5574 if (AOP_TYPE(right) == AOP_CRY &&
5575 AOP_TYPE(left) != AOP_CRY){
5576 operand *tmp = right ;
5581 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5583 if(AOP_TYPE(right) == AOP_LIT)
5584 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5586 size = AOP_SIZE(result);
5590 if (AOP_TYPE(left) == AOP_CRY){
5591 if(AOP_TYPE(right) == AOP_LIT){
5592 // c = bit & literal;
5594 // lit != 0 => result = 1
5595 if(AOP_TYPE(result) == AOP_CRY){
5597 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5598 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5599 // AOP(result)->aopu.aop_dir,
5600 // AOP(result)->aopu.aop_dir);
5602 continueIfTrue(ifx);
5606 // lit == 0 => result = left
5607 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5609 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5612 if (AOP_TYPE(right) == AOP_CRY){
5613 if(pic16_sameRegs(AOP(result),AOP(left))){
5615 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5616 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5617 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5619 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5620 AOP(result)->aopu.aop_dir,
5621 AOP(result)->aopu.aop_dir);
5622 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5623 AOP(right)->aopu.aop_dir,
5624 AOP(right)->aopu.aop_dir);
5625 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5626 AOP(result)->aopu.aop_dir,
5627 AOP(result)->aopu.aop_dir);
5629 if( AOP_TYPE(result) == AOP_ACC) {
5630 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5631 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5632 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5633 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5637 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5638 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5639 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5640 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5642 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5643 AOP(result)->aopu.aop_dir,
5644 AOP(result)->aopu.aop_dir);
5645 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5646 AOP(right)->aopu.aop_dir,
5647 AOP(right)->aopu.aop_dir);
5648 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5649 AOP(left)->aopu.aop_dir,
5650 AOP(left)->aopu.aop_dir);
5651 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5652 AOP(result)->aopu.aop_dir,
5653 AOP(result)->aopu.aop_dir);
5658 symbol *tlbl = newiTempLabel(NULL);
5659 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5662 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5663 if( AOP_TYPE(right) == AOP_ACC) {
5664 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5666 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5667 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5672 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5673 pic16_emitcode(";XXX setb","c");
5674 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5675 AOP(left)->aopu.aop_dir,tlbl->key+100);
5676 pic16_toBoolean(right);
5677 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5678 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5679 jmpTrueOrFalse(ifx, tlbl);
5683 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5690 pic16_outBitC(result);
5692 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5693 genIfxJump(ifx, "c");
5697 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5698 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5699 if((AOP_TYPE(right) == AOP_LIT) &&
5700 (AOP_TYPE(result) == AOP_CRY) &&
5701 (AOP_TYPE(left) != AOP_CRY)){
5703 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5706 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5708 continueIfTrue(ifx);
5711 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5712 // lit = 0, result = boolean(left)
5714 pic16_emitcode(";XXX setb","c");
5715 pic16_toBoolean(right);
5717 symbol *tlbl = newiTempLabel(NULL);
5718 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5720 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5722 genIfxJump (ifx,"a");
5726 pic16_outBitC(result);
5730 /* if left is same as result */
5731 if(pic16_sameRegs(AOP(result),AOP(left))){
5733 for(;size--; offset++,lit>>=8) {
5734 if(AOP_TYPE(right) == AOP_LIT){
5735 if((lit & 0xff) == 0)
5736 /* or'ing with 0 has no effect */
5739 int p = my_powof2(lit & 0xff);
5741 /* only one bit is set in the literal, so use a bsf instruction */
5742 pic16_emitpcode(POC_BSF,
5743 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5745 if(know_W != (lit & 0xff))
5746 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5747 know_W = lit & 0xff;
5748 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5753 if (AOP_TYPE(left) == AOP_ACC) {
5754 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5755 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5757 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5758 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5760 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5761 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5767 // left & result in different registers
5768 if(AOP_TYPE(result) == AOP_CRY){
5770 // if(size), result in bit
5771 // if(!size && ifx), conditional oper: if(left | right)
5772 symbol *tlbl = newiTempLabel(NULL);
5773 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5774 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5778 pic16_emitcode(";XXX setb","c");
5780 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5781 pic16_emitcode(";XXX orl","a,%s",
5782 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5783 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5788 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5789 pic16_outBitC(result);
5791 jmpTrueOrFalse(ifx, tlbl);
5792 } else for(;(size--);offset++){
5794 // result = left & right
5795 if(AOP_TYPE(right) == AOP_LIT){
5796 int t = (lit >> (offset*8)) & 0x0FFL;
5799 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5800 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5802 pic16_emitcode("movf","%s,w",
5803 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5804 pic16_emitcode("movwf","%s",
5805 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5808 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5809 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5810 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5812 pic16_emitcode("movlw","0x%x",t);
5813 pic16_emitcode("iorwf","%s,w",
5814 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5815 pic16_emitcode("movwf","%s",
5816 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5822 // faster than result <- left, anl result,right
5823 // and better if result is SFR
5824 if (AOP_TYPE(left) == AOP_ACC) {
5825 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5826 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5828 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5829 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5831 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5832 pic16_emitcode("iorwf","%s,w",
5833 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5835 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5836 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5841 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5842 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5843 pic16_freeAsmop(result,NULL,ic,TRUE);
5846 /*-----------------------------------------------------------------*/
5847 /* genXor - code for xclusive or */
5848 /*-----------------------------------------------------------------*/
5849 static void genXor (iCode *ic, iCode *ifx)
5851 operand *left, *right, *result;
5853 unsigned long lit = 0L;
5855 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5857 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5858 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5859 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5861 /* if left is a literal & right is not ||
5862 if left needs acc & right does not */
5863 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5864 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5865 operand *tmp = right ;
5870 /* if result = right then exchange them */
5871 if(pic16_sameRegs(AOP(result),AOP(right))){
5872 operand *tmp = right ;
5877 /* if right is bit then exchange them */
5878 if (AOP_TYPE(right) == AOP_CRY &&
5879 AOP_TYPE(left) != AOP_CRY){
5880 operand *tmp = right ;
5884 if(AOP_TYPE(right) == AOP_LIT)
5885 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5887 size = AOP_SIZE(result);
5891 if (AOP_TYPE(left) == AOP_CRY){
5892 if(AOP_TYPE(right) == AOP_LIT){
5893 // c = bit & literal;
5895 // lit>>1 != 0 => result = 1
5896 if(AOP_TYPE(result) == AOP_CRY){
5898 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
5899 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5901 continueIfTrue(ifx);
5904 pic16_emitcode("setb","c");
5908 // lit == 0, result = left
5909 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5911 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5913 // lit == 1, result = not(left)
5914 if(size && pic16_sameRegs(AOP(result),AOP(left))){
5915 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
5916 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
5917 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5920 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5921 pic16_emitcode("cpl","c");
5928 symbol *tlbl = newiTempLabel(NULL);
5929 if (AOP_TYPE(right) == AOP_CRY){
5931 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5934 int sizer = AOP_SIZE(right);
5936 // if val>>1 != 0, result = 1
5937 pic16_emitcode("setb","c");
5939 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5941 // test the msb of the lsb
5942 pic16_emitcode("anl","a,#0xfe");
5943 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5947 pic16_emitcode("rrc","a");
5949 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5950 pic16_emitcode("cpl","c");
5951 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5956 pic16_outBitC(result);
5958 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5959 genIfxJump(ifx, "c");
5963 if(pic16_sameRegs(AOP(result),AOP(left))){
5964 /* if left is same as result */
5965 for(;size--; offset++) {
5966 if(AOP_TYPE(right) == AOP_LIT){
5967 int t = (lit >> (offset*8)) & 0x0FFL;
5971 if (IS_AOP_PREG(left)) {
5972 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5973 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5974 pic16_aopPut(AOP(result),"a",offset);
5976 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5977 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5978 pic16_emitcode("xrl","%s,%s",
5979 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5980 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5983 if (AOP_TYPE(left) == AOP_ACC)
5984 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5986 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5987 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5989 if (IS_AOP_PREG(left)) {
5990 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5991 pic16_aopPut(AOP(result),"a",offset);
5993 pic16_emitcode("xrl","%s,a",
5994 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6000 // left & result in different registers
6001 if(AOP_TYPE(result) == AOP_CRY){
6003 // if(size), result in bit
6004 // if(!size && ifx), conditional oper: if(left ^ right)
6005 symbol *tlbl = newiTempLabel(NULL);
6006 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6008 pic16_emitcode("setb","c");
6010 if((AOP_TYPE(right) == AOP_LIT) &&
6011 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6012 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6014 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6015 pic16_emitcode("xrl","a,%s",
6016 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6018 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6023 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6024 pic16_outBitC(result);
6026 jmpTrueOrFalse(ifx, tlbl);
6027 } else for(;(size--);offset++){
6029 // result = left & right
6030 if(AOP_TYPE(right) == AOP_LIT){
6031 int t = (lit >> (offset*8)) & 0x0FFL;
6034 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6035 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6036 pic16_emitcode("movf","%s,w",
6037 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6038 pic16_emitcode("movwf","%s",
6039 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6042 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6043 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6044 pic16_emitcode("comf","%s,w",
6045 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6046 pic16_emitcode("movwf","%s",
6047 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6050 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6051 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6052 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6053 pic16_emitcode("movlw","0x%x",t);
6054 pic16_emitcode("xorwf","%s,w",
6055 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6056 pic16_emitcode("movwf","%s",
6057 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6063 // faster than result <- left, anl result,right
6064 // and better if result is SFR
6065 if (AOP_TYPE(left) == AOP_ACC) {
6066 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6067 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6069 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6070 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6071 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6072 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6074 if ( AOP_TYPE(result) != AOP_ACC){
6075 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6076 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6082 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6083 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6084 pic16_freeAsmop(result,NULL,ic,TRUE);
6087 /*-----------------------------------------------------------------*/
6088 /* genInline - write the inline code out */
6089 /*-----------------------------------------------------------------*/
6090 static void genInline (iCode *ic)
6092 char *buffer, *bp, *bp1;
6094 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6096 _G.inLine += (!options.asmpeep);
6098 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6099 strcpy(buffer,IC_INLINE(ic));
6101 /* emit each line as a code */
6107 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6114 pic16_emitcode(bp1,"");
6120 if ((bp1 != bp) && *bp1)
6121 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6125 _G.inLine -= (!options.asmpeep);
6128 /*-----------------------------------------------------------------*/
6129 /* genRRC - rotate right with carry */
6130 /*-----------------------------------------------------------------*/
6131 static void genRRC (iCode *ic)
6133 operand *left , *result ;
6134 int size, offset = 0, same;
6136 /* rotate right with carry */
6138 result=IC_RESULT(ic);
6139 pic16_aopOp (left,ic,FALSE);
6140 pic16_aopOp (result,ic,FALSE);
6142 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6144 same = pic16_sameRegs(AOP(result),AOP(left));
6146 size = AOP_SIZE(result);
6148 /* get the lsb and put it into the carry */
6149 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6156 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6158 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6159 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6165 pic16_freeAsmop(left,NULL,ic,TRUE);
6166 pic16_freeAsmop(result,NULL,ic,TRUE);
6169 /*-----------------------------------------------------------------*/
6170 /* genRLC - generate code for rotate left with carry */
6171 /*-----------------------------------------------------------------*/
6172 static void genRLC (iCode *ic)
6174 operand *left , *result ;
6175 int size, offset = 0;
6178 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6179 /* rotate right with carry */
6181 result=IC_RESULT(ic);
6182 pic16_aopOp (left,ic,FALSE);
6183 pic16_aopOp (result,ic,FALSE);
6185 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6187 same = pic16_sameRegs(AOP(result),AOP(left));
6189 /* move it to the result */
6190 size = AOP_SIZE(result);
6192 /* get the msb and put it into the carry */
6193 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6200 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6202 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6203 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6210 pic16_freeAsmop(left,NULL,ic,TRUE);
6211 pic16_freeAsmop(result,NULL,ic,TRUE);
6214 /*-----------------------------------------------------------------*/
6215 /* genGetHbit - generates code get highest order bit */
6216 /*-----------------------------------------------------------------*/
6217 static void genGetHbit (iCode *ic)
6219 operand *left, *result;
6221 result=IC_RESULT(ic);
6222 pic16_aopOp (left,ic,FALSE);
6223 pic16_aopOp (result,ic,FALSE);
6225 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6226 /* get the highest order byte into a */
6227 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6228 if(AOP_TYPE(result) == AOP_CRY){
6229 pic16_emitcode("rlc","a");
6230 pic16_outBitC(result);
6233 pic16_emitcode("rl","a");
6234 pic16_emitcode("anl","a,#0x01");
6235 pic16_outAcc(result);
6239 pic16_freeAsmop(left,NULL,ic,TRUE);
6240 pic16_freeAsmop(result,NULL,ic,TRUE);
6243 /*-----------------------------------------------------------------*/
6244 /* AccRol - rotate left accumulator by known count */
6245 /*-----------------------------------------------------------------*/
6246 static void AccRol (int shCount)
6248 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6249 shCount &= 0x0007; // shCount : 0..7
6254 pic16_emitcode("rl","a");
6257 pic16_emitcode("rl","a");
6258 pic16_emitcode("rl","a");
6261 pic16_emitcode("swap","a");
6262 pic16_emitcode("rr","a");
6265 pic16_emitcode("swap","a");
6268 pic16_emitcode("swap","a");
6269 pic16_emitcode("rl","a");
6272 pic16_emitcode("rr","a");
6273 pic16_emitcode("rr","a");
6276 pic16_emitcode("rr","a");
6281 /*-----------------------------------------------------------------*/
6282 /* AccLsh - left shift accumulator by known count */
6283 /*-----------------------------------------------------------------*/
6284 static void AccLsh (int shCount)
6286 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6289 pic16_emitcode("add","a,acc");
6292 pic16_emitcode("add","a,acc");
6293 pic16_emitcode("add","a,acc");
6295 /* rotate left accumulator */
6297 /* and kill the lower order bits */
6298 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6303 /*-----------------------------------------------------------------*/
6304 /* AccRsh - right shift accumulator by known count */
6305 /*-----------------------------------------------------------------*/
6306 static void AccRsh (int shCount)
6308 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6312 pic16_emitcode("rrc","a");
6314 /* rotate right accumulator */
6315 AccRol(8 - shCount);
6316 /* and kill the higher order bits */
6317 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6323 /*-----------------------------------------------------------------*/
6324 /* AccSRsh - signed right shift accumulator by known count */
6325 /*-----------------------------------------------------------------*/
6326 static void AccSRsh (int shCount)
6329 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6332 pic16_emitcode("mov","c,acc.7");
6333 pic16_emitcode("rrc","a");
6334 } else if(shCount == 2){
6335 pic16_emitcode("mov","c,acc.7");
6336 pic16_emitcode("rrc","a");
6337 pic16_emitcode("mov","c,acc.7");
6338 pic16_emitcode("rrc","a");
6340 tlbl = newiTempLabel(NULL);
6341 /* rotate right accumulator */
6342 AccRol(8 - shCount);
6343 /* and kill the higher order bits */
6344 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6345 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6346 pic16_emitcode("orl","a,#0x%02x",
6347 (unsigned char)~SRMask[shCount]);
6348 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6353 /*-----------------------------------------------------------------*/
6354 /* shiftR1Left2Result - shift right one byte from left to result */
6355 /*-----------------------------------------------------------------*/
6356 static void shiftR1Left2ResultSigned (operand *left, int offl,
6357 operand *result, int offr,
6362 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6364 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6368 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6370 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6372 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6373 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6379 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6381 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6383 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6384 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6386 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6387 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6393 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6395 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6396 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6399 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6400 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6401 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6403 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6404 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6406 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6410 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6411 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6412 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6413 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6414 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6418 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6420 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6421 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6423 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6424 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6425 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6426 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6427 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6432 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6433 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6434 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6435 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6436 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6437 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6439 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6440 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6441 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6442 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6443 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6449 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6450 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6451 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6452 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6454 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6455 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6456 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6464 /*-----------------------------------------------------------------*/
6465 /* shiftR1Left2Result - shift right one byte from left to result */
6466 /*-----------------------------------------------------------------*/
6467 static void shiftR1Left2Result (operand *left, int offl,
6468 operand *result, int offr,
6469 int shCount, int sign)
6473 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6475 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6477 /* Copy the msb into the carry if signed. */
6479 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6489 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6491 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6492 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6498 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6500 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6501 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6504 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6509 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6511 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6512 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6515 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6516 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6517 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6518 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6522 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6523 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6524 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6528 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6529 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6530 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6532 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6537 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6538 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6539 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6540 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6541 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6546 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6547 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6548 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6557 /*-----------------------------------------------------------------*/
6558 /* shiftL1Left2Result - shift left one byte from left to result */
6559 /*-----------------------------------------------------------------*/
6560 static void shiftL1Left2Result (operand *left, int offl,
6561 operand *result, int offr, int shCount)
6566 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6568 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6569 DEBUGpic16_emitcode ("; ***","same = %d",same);
6570 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6572 /* shift left accumulator */
6573 //AccLsh(shCount); // don't comment out just yet...
6574 // pic16_aopPut(AOP(result),"a",offr);
6578 /* Shift left 1 bit position */
6579 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6581 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6583 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6584 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6588 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6589 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6590 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6591 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6594 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6595 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6596 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6597 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6598 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6601 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6602 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6603 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6606 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6607 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6608 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6609 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6612 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6613 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6614 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6615 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6616 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6619 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6620 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6621 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6625 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6630 /*-----------------------------------------------------------------*/
6631 /* movLeft2Result - move byte from left to result */
6632 /*-----------------------------------------------------------------*/
6633 static void movLeft2Result (operand *left, int offl,
6634 operand *result, int offr)
6637 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6638 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6639 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6641 if (*l == '@' && (IS_AOP_PREG(result))) {
6642 pic16_emitcode("mov","a,%s",l);
6643 pic16_aopPut(AOP(result),"a",offr);
6645 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6646 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6651 /*-----------------------------------------------------------------*/
6652 /* shiftL2Left2Result - shift left two bytes from left to result */
6653 /*-----------------------------------------------------------------*/
6654 static void shiftL2Left2Result (operand *left, int offl,
6655 operand *result, int offr, int shCount)
6659 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6661 if(pic16_sameRegs(AOP(result), AOP(left))) {
6669 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6670 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6671 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6675 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6676 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6682 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6683 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6684 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6685 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6686 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6687 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6688 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6690 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6691 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6695 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6696 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6697 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6698 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6699 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6700 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6701 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6702 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6703 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6704 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6707 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6708 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6709 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6710 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6711 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6721 /* note, use a mov/add for the shift since the mov has a
6722 chance of getting optimized out */
6723 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6724 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6725 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6726 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6727 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6731 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6732 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6738 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6739 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6740 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6741 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6742 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6743 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6744 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6745 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6749 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6750 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6754 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6755 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6756 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6757 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6759 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6760 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6761 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6762 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6763 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6764 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6765 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6766 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6769 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6770 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6771 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6772 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6773 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6778 /*-----------------------------------------------------------------*/
6779 /* shiftR2Left2Result - shift right two bytes from left to result */
6780 /*-----------------------------------------------------------------*/
6781 static void shiftR2Left2Result (operand *left, int offl,
6782 operand *result, int offr,
6783 int shCount, int sign)
6787 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6788 same = pic16_sameRegs(AOP(result), AOP(left));
6790 if(same && ((offl + MSB16) == offr)){
6792 /* don't crash result[offr] */
6793 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6794 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6797 movLeft2Result(left,offl, result, offr);
6798 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6801 /* a:x >> shCount (x = lsb(result))*/
6804 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6806 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6815 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6820 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6821 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6823 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6824 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6825 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6826 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6831 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6834 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6835 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6842 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6843 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6844 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6846 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6847 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6848 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6849 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6851 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6852 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6853 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6855 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6856 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6857 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6858 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6859 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6863 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6864 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6868 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6869 pic16_emitpcode(POC_BTFSC,
6870 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6871 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6879 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6880 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6882 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6883 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6884 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6885 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6887 pic16_emitpcode(POC_BTFSC,
6888 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6889 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6891 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6892 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6893 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6894 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6896 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6897 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6898 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6899 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6900 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6901 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6902 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6903 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6905 pic16_emitpcode(POC_BTFSC,
6906 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6907 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6909 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6910 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6917 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6918 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6919 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6920 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6923 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6925 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6930 /*-----------------------------------------------------------------*/
6931 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6932 /*-----------------------------------------------------------------*/
6933 static void shiftLLeftOrResult (operand *left, int offl,
6934 operand *result, int offr, int shCount)
6936 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6937 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6938 /* shift left accumulator */
6940 /* or with result */
6941 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6942 /* back to result */
6943 pic16_aopPut(AOP(result),"a",offr);
6946 /*-----------------------------------------------------------------*/
6947 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6948 /*-----------------------------------------------------------------*/
6949 static void shiftRLeftOrResult (operand *left, int offl,
6950 operand *result, int offr, int shCount)
6952 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6953 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6954 /* shift right accumulator */
6956 /* or with result */
6957 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6958 /* back to result */
6959 pic16_aopPut(AOP(result),"a",offr);
6962 /*-----------------------------------------------------------------*/
6963 /* genlshOne - left shift a one byte quantity by known count */
6964 /*-----------------------------------------------------------------*/
6965 static void genlshOne (operand *result, operand *left, int shCount)
6967 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6968 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6971 /*-----------------------------------------------------------------*/
6972 /* genlshTwo - left shift two bytes by known amount != 0 */
6973 /*-----------------------------------------------------------------*/
6974 static void genlshTwo (operand *result,operand *left, int shCount)
6978 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6979 size = pic16_getDataSize(result);
6981 /* if shCount >= 8 */
6987 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6989 movLeft2Result(left, LSB, result, MSB16);
6991 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6994 /* 1 <= shCount <= 7 */
6997 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6999 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7003 /*-----------------------------------------------------------------*/
7004 /* shiftLLong - shift left one long from left to result */
7005 /* offl = LSB or MSB16 */
7006 /*-----------------------------------------------------------------*/
7007 static void shiftLLong (operand *left, operand *result, int offr )
7010 int size = AOP_SIZE(result);
7012 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7013 if(size >= LSB+offr){
7014 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7016 pic16_emitcode("add","a,acc");
7017 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7018 size >= MSB16+offr && offr != LSB )
7019 pic16_emitcode("xch","a,%s",
7020 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7022 pic16_aopPut(AOP(result),"a",LSB+offr);
7025 if(size >= MSB16+offr){
7026 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7027 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7030 pic16_emitcode("rlc","a");
7031 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7032 size >= MSB24+offr && offr != LSB)
7033 pic16_emitcode("xch","a,%s",
7034 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7036 pic16_aopPut(AOP(result),"a",MSB16+offr);
7039 if(size >= MSB24+offr){
7040 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7041 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7044 pic16_emitcode("rlc","a");
7045 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7046 size >= MSB32+offr && offr != LSB )
7047 pic16_emitcode("xch","a,%s",
7048 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7050 pic16_aopPut(AOP(result),"a",MSB24+offr);
7053 if(size > MSB32+offr){
7054 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7055 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7058 pic16_emitcode("rlc","a");
7059 pic16_aopPut(AOP(result),"a",MSB32+offr);
7062 pic16_aopPut(AOP(result),zero,LSB);
7065 /*-----------------------------------------------------------------*/
7066 /* genlshFour - shift four byte by a known amount != 0 */
7067 /*-----------------------------------------------------------------*/
7068 static void genlshFour (operand *result, operand *left, int shCount)
7072 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7073 size = AOP_SIZE(result);
7075 /* if shifting more that 3 bytes */
7076 if (shCount >= 24 ) {
7079 /* lowest order of left goes to the highest
7080 order of the destination */
7081 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7083 movLeft2Result(left, LSB, result, MSB32);
7084 pic16_aopPut(AOP(result),zero,LSB);
7085 pic16_aopPut(AOP(result),zero,MSB16);
7086 pic16_aopPut(AOP(result),zero,MSB32);
7090 /* more than two bytes */
7091 else if ( shCount >= 16 ) {
7092 /* lower order two bytes goes to higher order two bytes */
7094 /* if some more remaining */
7096 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7098 movLeft2Result(left, MSB16, result, MSB32);
7099 movLeft2Result(left, LSB, result, MSB24);
7101 pic16_aopPut(AOP(result),zero,MSB16);
7102 pic16_aopPut(AOP(result),zero,LSB);
7106 /* if more than 1 byte */
7107 else if ( shCount >= 8 ) {
7108 /* lower order three bytes goes to higher order three bytes */
7112 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7114 movLeft2Result(left, LSB, result, MSB16);
7116 else{ /* size = 4 */
7118 movLeft2Result(left, MSB24, result, MSB32);
7119 movLeft2Result(left, MSB16, result, MSB24);
7120 movLeft2Result(left, LSB, result, MSB16);
7121 pic16_aopPut(AOP(result),zero,LSB);
7123 else if(shCount == 1)
7124 shiftLLong(left, result, MSB16);
7126 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7127 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7128 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7129 pic16_aopPut(AOP(result),zero,LSB);
7134 /* 1 <= shCount <= 7 */
7135 else if(shCount <= 2){
7136 shiftLLong(left, result, LSB);
7138 shiftLLong(result, result, LSB);
7140 /* 3 <= shCount <= 7, optimize */
7142 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7143 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7144 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7148 /*-----------------------------------------------------------------*/
7149 /* genLeftShiftLiteral - left shifting by known count */
7150 /*-----------------------------------------------------------------*/
7151 static void genLeftShiftLiteral (operand *left,
7156 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7159 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7160 pic16_freeAsmop(right,NULL,ic,TRUE);
7162 pic16_aopOp(left,ic,FALSE);
7163 pic16_aopOp(result,ic,FALSE);
7165 size = getSize(operandType(result));
7168 pic16_emitcode("; shift left ","result %d, left %d",size,
7172 /* I suppose that the left size >= result size */
7175 movLeft2Result(left, size, result, size);
7179 else if(shCount >= (size * 8))
7181 pic16_aopPut(AOP(result),zero,size);
7185 genlshOne (result,left,shCount);
7190 genlshTwo (result,left,shCount);
7194 genlshFour (result,left,shCount);
7198 pic16_freeAsmop(left,NULL,ic,TRUE);
7199 pic16_freeAsmop(result,NULL,ic,TRUE);
7202 /*-----------------------------------------------------------------*
7203 * genMultiAsm - repeat assembly instruction for size of register.
7204 * if endian == 1, then the high byte (i.e base address + size of
7205 * register) is used first else the low byte is used first;
7206 *-----------------------------------------------------------------*/
7207 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7212 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7225 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7230 /*-----------------------------------------------------------------*/
7231 /* genLeftShift - generates code for left shifting */
7232 /*-----------------------------------------------------------------*/
7233 static void genLeftShift (iCode *ic)
7235 operand *left,*right, *result;
7238 symbol *tlbl , *tlbl1;
7241 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7243 right = IC_RIGHT(ic);
7245 result = IC_RESULT(ic);
7247 pic16_aopOp(right,ic,FALSE);
7249 /* if the shift count is known then do it
7250 as efficiently as possible */
7251 if (AOP_TYPE(right) == AOP_LIT) {
7252 genLeftShiftLiteral (left,right,result,ic);
7256 /* shift count is unknown then we have to form
7257 a loop get the loop count in B : Note: we take
7258 only the lower order byte since shifting
7259 more that 32 bits make no sense anyway, ( the
7260 largest size of an object can be only 32 bits ) */
7263 pic16_aopOp(left,ic,FALSE);
7264 pic16_aopOp(result,ic,FALSE);
7266 /* now move the left to the result if they are not the
7268 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7269 AOP_SIZE(result) > 1) {
7271 size = AOP_SIZE(result);
7274 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7275 if (*l == '@' && (IS_AOP_PREG(result))) {
7277 pic16_emitcode("mov","a,%s",l);
7278 pic16_aopPut(AOP(result),"a",offset);
7280 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7281 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7282 //pic16_aopPut(AOP(result),l,offset);
7288 size = AOP_SIZE(result);
7290 /* if it is only one byte then */
7292 if(optimized_for_speed) {
7293 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7294 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7295 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7296 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7297 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7298 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7299 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7300 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7301 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7302 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7303 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7304 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7307 tlbl = newiTempLabel(NULL);
7308 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7309 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7310 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7313 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7314 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7315 pic16_emitpLabel(tlbl->key);
7316 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7317 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7319 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7324 if (pic16_sameRegs(AOP(left),AOP(result))) {
7326 tlbl = newiTempLabel(NULL);
7327 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7328 genMultiAsm(POC_RRCF, result, size,1);
7329 pic16_emitpLabel(tlbl->key);
7330 genMultiAsm(POC_RLCF, result, size,0);
7331 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7333 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7337 //tlbl = newiTempLabel(NULL);
7339 //tlbl1 = newiTempLabel(NULL);
7341 //reAdjustPreg(AOP(result));
7343 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7344 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7345 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7347 //pic16_emitcode("add","a,acc");
7348 //pic16_aopPut(AOP(result),"a",offset++);
7350 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7352 // pic16_emitcode("rlc","a");
7353 // pic16_aopPut(AOP(result),"a",offset++);
7355 //reAdjustPreg(AOP(result));
7357 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7358 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7361 tlbl = newiTempLabel(NULL);
7362 tlbl1= newiTempLabel(NULL);
7364 size = AOP_SIZE(result);
7367 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7369 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7371 /* offset should be 0, 1 or 3 */
7372 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7374 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7376 pic16_emitpcode(POC_MOVWF, pctemp);
7379 pic16_emitpLabel(tlbl->key);
7382 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7384 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7386 pic16_emitpcode(POC_DECFSZ, pctemp);
7387 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7388 pic16_emitpLabel(tlbl1->key);
7390 pic16_popReleaseTempReg(pctemp);
7394 pic16_freeAsmop (right,NULL,ic,TRUE);
7395 pic16_freeAsmop(left,NULL,ic,TRUE);
7396 pic16_freeAsmop(result,NULL,ic,TRUE);
7399 /*-----------------------------------------------------------------*/
7400 /* genrshOne - right shift a one byte quantity by known count */
7401 /*-----------------------------------------------------------------*/
7402 static void genrshOne (operand *result, operand *left,
7403 int shCount, int sign)
7405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7406 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7409 /*-----------------------------------------------------------------*/
7410 /* genrshTwo - right shift two bytes by known amount != 0 */
7411 /*-----------------------------------------------------------------*/
7412 static void genrshTwo (operand *result,operand *left,
7413 int shCount, int sign)
7415 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7416 /* if shCount >= 8 */
7420 shiftR1Left2Result(left, MSB16, result, LSB,
7423 movLeft2Result(left, MSB16, result, LSB);
7425 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7428 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7429 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7433 /* 1 <= shCount <= 7 */
7435 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7438 /*-----------------------------------------------------------------*/
7439 /* shiftRLong - shift right one long from left to result */
7440 /* offl = LSB or MSB16 */
7441 /*-----------------------------------------------------------------*/
7442 static void shiftRLong (operand *left, int offl,
7443 operand *result, int sign)
7445 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7447 pic16_emitcode("clr","c");
7448 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7450 pic16_emitcode("mov","c,acc.7");
7451 pic16_emitcode("rrc","a");
7452 pic16_aopPut(AOP(result),"a",MSB32-offl);
7454 /* add sign of "a" */
7455 pic16_addSign(result, MSB32, sign);
7457 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7458 pic16_emitcode("rrc","a");
7459 pic16_aopPut(AOP(result),"a",MSB24-offl);
7461 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7462 pic16_emitcode("rrc","a");
7463 pic16_aopPut(AOP(result),"a",MSB16-offl);
7466 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7467 pic16_emitcode("rrc","a");
7468 pic16_aopPut(AOP(result),"a",LSB);
7472 /*-----------------------------------------------------------------*/
7473 /* genrshFour - shift four byte by a known amount != 0 */
7474 /*-----------------------------------------------------------------*/
7475 static void genrshFour (operand *result, operand *left,
7476 int shCount, int sign)
7478 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7479 /* if shifting more that 3 bytes */
7480 if(shCount >= 24 ) {
7483 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7485 movLeft2Result(left, MSB32, result, LSB);
7487 pic16_addSign(result, MSB16, sign);
7489 else if(shCount >= 16){
7492 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7494 movLeft2Result(left, MSB24, result, LSB);
7495 movLeft2Result(left, MSB32, result, MSB16);
7497 pic16_addSign(result, MSB24, sign);
7499 else if(shCount >= 8){
7502 shiftRLong(left, MSB16, result, sign);
7503 else if(shCount == 0){
7504 movLeft2Result(left, MSB16, result, LSB);
7505 movLeft2Result(left, MSB24, result, MSB16);
7506 movLeft2Result(left, MSB32, result, MSB24);
7507 pic16_addSign(result, MSB32, sign);
7510 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7511 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7512 /* the last shift is signed */
7513 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7514 pic16_addSign(result, MSB32, sign);
7517 else{ /* 1 <= shCount <= 7 */
7519 shiftRLong(left, LSB, result, sign);
7521 shiftRLong(result, LSB, result, sign);
7524 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7525 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7526 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7531 /*-----------------------------------------------------------------*/
7532 /* genRightShiftLiteral - right shifting by known count */
7533 /*-----------------------------------------------------------------*/
7534 static void genRightShiftLiteral (operand *left,
7540 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7543 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7544 pic16_freeAsmop(right,NULL,ic,TRUE);
7546 pic16_aopOp(left,ic,FALSE);
7547 pic16_aopOp(result,ic,FALSE);
7550 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7554 lsize = pic16_getDataSize(left);
7555 res_size = pic16_getDataSize(result);
7556 /* test the LEFT size !!! */
7558 /* I suppose that the left size >= result size */
7561 movLeft2Result(left, lsize, result, res_size);
7564 else if(shCount >= (lsize * 8)){
7567 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7569 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7570 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7575 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7576 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7577 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7579 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7584 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7591 genrshOne (result,left,shCount,sign);
7595 genrshTwo (result,left,shCount,sign);
7599 genrshFour (result,left,shCount,sign);
7607 pic16_freeAsmop(left,NULL,ic,TRUE);
7608 pic16_freeAsmop(result,NULL,ic,TRUE);
7611 /*-----------------------------------------------------------------*/
7612 /* genSignedRightShift - right shift of signed number */
7613 /*-----------------------------------------------------------------*/
7614 static void genSignedRightShift (iCode *ic)
7616 operand *right, *left, *result;
7619 symbol *tlbl, *tlbl1 ;
7622 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7624 /* we do it the hard way put the shift count in b
7625 and loop thru preserving the sign */
7626 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7628 right = IC_RIGHT(ic);
7630 result = IC_RESULT(ic);
7632 pic16_aopOp(right,ic,FALSE);
7633 pic16_aopOp(left,ic,FALSE);
7634 pic16_aopOp(result,ic,FALSE);
7637 if ( AOP_TYPE(right) == AOP_LIT) {
7638 genRightShiftLiteral (left,right,result,ic,1);
7641 /* shift count is unknown then we have to form
7642 a loop get the loop count in B : Note: we take
7643 only the lower order byte since shifting
7644 more that 32 bits make no sense anyway, ( the
7645 largest size of an object can be only 32 bits ) */
7647 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7648 //pic16_emitcode("inc","b");
7649 //pic16_freeAsmop (right,NULL,ic,TRUE);
7650 //pic16_aopOp(left,ic,FALSE);
7651 //pic16_aopOp(result,ic,FALSE);
7653 /* now move the left to the result if they are not the
7655 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7656 AOP_SIZE(result) > 1) {
7658 size = AOP_SIZE(result);
7662 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7663 if (*l == '@' && IS_AOP_PREG(result)) {
7665 pic16_emitcode("mov","a,%s",l);
7666 pic16_aopPut(AOP(result),"a",offset);
7668 pic16_aopPut(AOP(result),l,offset);
7670 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7671 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7677 /* mov the highest order bit to OVR */
7678 tlbl = newiTempLabel(NULL);
7679 tlbl1= newiTempLabel(NULL);
7681 size = AOP_SIZE(result);
7684 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7686 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7688 /* offset should be 0, 1 or 3 */
7689 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7691 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7693 pic16_emitpcode(POC_MOVWF, pctemp);
7696 pic16_emitpLabel(tlbl->key);
7698 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7699 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7702 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7705 pic16_emitpcode(POC_DECFSZ, pctemp);
7706 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7707 pic16_emitpLabel(tlbl1->key);
7709 pic16_popReleaseTempReg(pctemp);
7711 size = AOP_SIZE(result);
7713 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7714 pic16_emitcode("rlc","a");
7715 pic16_emitcode("mov","ov,c");
7716 /* if it is only one byte then */
7718 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7720 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7721 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7722 pic16_emitcode("mov","c,ov");
7723 pic16_emitcode("rrc","a");
7724 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7725 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7726 pic16_aopPut(AOP(result),"a",0);
7730 reAdjustPreg(AOP(result));
7731 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7732 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7733 pic16_emitcode("mov","c,ov");
7735 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7737 pic16_emitcode("rrc","a");
7738 pic16_aopPut(AOP(result),"a",offset--);
7740 reAdjustPreg(AOP(result));
7741 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7742 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7747 pic16_freeAsmop(left,NULL,ic,TRUE);
7748 pic16_freeAsmop(result,NULL,ic,TRUE);
7749 pic16_freeAsmop(right,NULL,ic,TRUE);
7752 /*-----------------------------------------------------------------*/
7753 /* genRightShift - generate code for right shifting */
7754 /*-----------------------------------------------------------------*/
7755 static void genRightShift (iCode *ic)
7757 operand *right, *left, *result;
7761 symbol *tlbl, *tlbl1 ;
7763 /* if signed then we do it the hard way preserve the
7764 sign bit moving it inwards */
7765 retype = getSpec(operandType(IC_RESULT(ic)));
7766 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7768 if (!SPEC_USIGN(retype)) {
7769 genSignedRightShift (ic);
7773 /* signed & unsigned types are treated the same : i.e. the
7774 signed is NOT propagated inwards : quoting from the
7775 ANSI - standard : "for E1 >> E2, is equivalent to division
7776 by 2**E2 if unsigned or if it has a non-negative value,
7777 otherwise the result is implementation defined ", MY definition
7778 is that the sign does not get propagated */
7780 right = IC_RIGHT(ic);
7782 result = IC_RESULT(ic);
7784 pic16_aopOp(right,ic,FALSE);
7786 /* if the shift count is known then do it
7787 as efficiently as possible */
7788 if (AOP_TYPE(right) == AOP_LIT) {
7789 genRightShiftLiteral (left,right,result,ic, 0);
7793 /* shift count is unknown then we have to form
7794 a loop get the loop count in B : Note: we take
7795 only the lower order byte since shifting
7796 more that 32 bits make no sense anyway, ( the
7797 largest size of an object can be only 32 bits ) */
7799 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7800 pic16_emitcode("inc","b");
7801 pic16_aopOp(left,ic,FALSE);
7802 pic16_aopOp(result,ic,FALSE);
7804 /* now move the left to the result if they are not the
7806 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7807 AOP_SIZE(result) > 1) {
7809 size = AOP_SIZE(result);
7812 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7813 if (*l == '@' && IS_AOP_PREG(result)) {
7815 pic16_emitcode("mov","a,%s",l);
7816 pic16_aopPut(AOP(result),"a",offset);
7818 pic16_aopPut(AOP(result),l,offset);
7823 tlbl = newiTempLabel(NULL);
7824 tlbl1= newiTempLabel(NULL);
7825 size = AOP_SIZE(result);
7828 /* if it is only one byte then */
7831 tlbl = newiTempLabel(NULL);
7832 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7833 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7834 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7837 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7838 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7839 pic16_emitpLabel(tlbl->key);
7840 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7841 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7843 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7848 reAdjustPreg(AOP(result));
7849 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7850 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7853 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7855 pic16_emitcode("rrc","a");
7856 pic16_aopPut(AOP(result),"a",offset--);
7858 reAdjustPreg(AOP(result));
7860 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7861 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7864 pic16_freeAsmop(left,NULL,ic,TRUE);
7865 pic16_freeAsmop (right,NULL,ic,TRUE);
7866 pic16_freeAsmop(result,NULL,ic,TRUE);
7869 /*-----------------------------------------------------------------*/
7870 /* genUnpackBits - generates code for unpacking bits */
7871 /*-----------------------------------------------------------------*/
7872 static void genUnpackBits (operand *result, char *rname, int ptype)
7879 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7880 etype = getSpec(operandType(result));
7882 /* read the first byte */
7887 pic16_emitcode("mov","a,@%s",rname);
7891 pic16_emitcode("movx","a,@%s",rname);
7895 pic16_emitcode("movx","a,@dptr");
7899 pic16_emitcode("clr","a");
7900 pic16_emitcode("movc","a","@a+dptr");
7904 pic16_emitcode("lcall","__gptrget");
7908 /* if we have bitdisplacement then it fits */
7909 /* into this byte completely or if length is */
7910 /* less than a byte */
7911 if ((shCnt = SPEC_BSTR(etype)) ||
7912 (SPEC_BLEN(etype) <= 8)) {
7914 /* shift right acc */
7917 pic16_emitcode("anl","a,#0x%02x",
7918 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7919 pic16_aopPut(AOP(result),"a",offset);
7923 /* bit field did not fit in a byte */
7924 rlen = SPEC_BLEN(etype) - 8;
7925 pic16_aopPut(AOP(result),"a",offset++);
7932 pic16_emitcode("inc","%s",rname);
7933 pic16_emitcode("mov","a,@%s",rname);
7937 pic16_emitcode("inc","%s",rname);
7938 pic16_emitcode("movx","a,@%s",rname);
7942 pic16_emitcode("inc","dptr");
7943 pic16_emitcode("movx","a,@dptr");
7947 pic16_emitcode("clr","a");
7948 pic16_emitcode("inc","dptr");
7949 pic16_emitcode("movc","a","@a+dptr");
7953 pic16_emitcode("inc","dptr");
7954 pic16_emitcode("lcall","__gptrget");
7959 /* if we are done */
7963 pic16_aopPut(AOP(result),"a",offset++);
7968 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7969 pic16_aopPut(AOP(result),"a",offset);
7976 /*-----------------------------------------------------------------*/
7977 /* genDataPointerGet - generates code when ptr offset is known */
7978 /*-----------------------------------------------------------------*/
7979 static void genDataPointerGet (operand *left,
7983 int size , offset = 0;
7986 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7989 /* optimization - most of the time, left and result are the same
7990 * address, but different types. for the pic code, we could omit
7994 pic16_aopOp(result,ic,TRUE);
7996 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7998 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8000 size = AOP_SIZE(result);
8003 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8007 pic16_freeAsmop(left,NULL,ic,TRUE);
8008 pic16_freeAsmop(result,NULL,ic,TRUE);
8011 /*-----------------------------------------------------------------*/
8012 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8013 /*-----------------------------------------------------------------*/
8014 static void genNearPointerGet (operand *left,
8019 //regs *preg = NULL ;
8021 sym_link *rtype, *retype;
8022 sym_link *ltype = operandType(left);
8025 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8027 rtype = operandType(result);
8028 retype= getSpec(rtype);
8030 pic16_aopOp(left,ic,FALSE);
8032 /* if left is rematerialisable and
8033 result is not bit variable type and
8034 the left is pointer to data space i.e
8035 lower 128 bytes of space */
8036 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8037 !IS_BITVAR(retype) &&
8038 DCL_TYPE(ltype) == POINTER) {
8039 //genDataPointerGet (left,result,ic);
8043 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8045 /* if the value is already in a pointer register
8046 then don't need anything more */
8047 if (!AOP_INPREG(AOP(left))) {
8048 /* otherwise get a free pointer register */
8049 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8052 preg = getFreePtr(ic,&aop,FALSE);
8053 pic16_emitcode("mov","%s,%s",
8055 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8056 rname = preg->name ;
8060 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8062 pic16_aopOp (result,ic,FALSE);
8064 /* if bitfield then unpack the bits */
8065 if (IS_BITVAR(retype))
8066 genUnpackBits (result,rname,POINTER);
8068 /* we have can just get the values */
8069 int size = AOP_SIZE(result);
8072 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8074 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8075 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8077 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8078 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8080 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8084 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8086 pic16_emitcode("mov","a,@%s",rname);
8087 pic16_aopPut(AOP(result),"a",offset);
8089 sprintf(buffer,"@%s",rname);
8090 pic16_aopPut(AOP(result),buffer,offset);
8094 pic16_emitcode("inc","%s",rname);
8099 /* now some housekeeping stuff */
8101 /* we had to allocate for this iCode */
8102 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8103 pic16_freeAsmop(NULL,aop,ic,TRUE);
8105 /* we did not allocate which means left
8106 already in a pointer register, then
8107 if size > 0 && this could be used again
8108 we have to point it back to where it
8110 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8111 if (AOP_SIZE(result) > 1 &&
8112 !OP_SYMBOL(left)->remat &&
8113 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8115 int size = AOP_SIZE(result) - 1;
8117 pic16_emitcode("dec","%s",rname);
8122 pic16_freeAsmop(left,NULL,ic,TRUE);
8123 pic16_freeAsmop(result,NULL,ic,TRUE);
8127 /*-----------------------------------------------------------------*/
8128 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8129 /*-----------------------------------------------------------------*/
8130 static void genPagedPointerGet (operand *left,
8137 sym_link *rtype, *retype;
8139 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8141 rtype = operandType(result);
8142 retype= getSpec(rtype);
8144 pic16_aopOp(left,ic,FALSE);
8146 /* if the value is already in a pointer register
8147 then don't need anything more */
8148 if (!AOP_INPREG(AOP(left))) {
8149 /* otherwise get a free pointer register */
8151 preg = getFreePtr(ic,&aop,FALSE);
8152 pic16_emitcode("mov","%s,%s",
8154 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8155 rname = preg->name ;
8157 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8159 pic16_freeAsmop(left,NULL,ic,TRUE);
8160 pic16_aopOp (result,ic,FALSE);
8162 /* if bitfield then unpack the bits */
8163 if (IS_BITVAR(retype))
8164 genUnpackBits (result,rname,PPOINTER);
8166 /* we have can just get the values */
8167 int size = AOP_SIZE(result);
8172 pic16_emitcode("movx","a,@%s",rname);
8173 pic16_aopPut(AOP(result),"a",offset);
8178 pic16_emitcode("inc","%s",rname);
8182 /* now some housekeeping stuff */
8184 /* we had to allocate for this iCode */
8185 pic16_freeAsmop(NULL,aop,ic,TRUE);
8187 /* we did not allocate which means left
8188 already in a pointer register, then
8189 if size > 0 && this could be used again
8190 we have to point it back to where it
8192 if (AOP_SIZE(result) > 1 &&
8193 !OP_SYMBOL(left)->remat &&
8194 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8196 int size = AOP_SIZE(result) - 1;
8198 pic16_emitcode("dec","%s",rname);
8203 pic16_freeAsmop(result,NULL,ic,TRUE);
8208 /*-----------------------------------------------------------------*/
8209 /* genFarPointerGet - gget value from far space */
8210 /*-----------------------------------------------------------------*/
8211 static void genFarPointerGet (operand *left,
8212 operand *result, iCode *ic)
8215 sym_link *retype = getSpec(operandType(result));
8217 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8219 pic16_aopOp(left,ic,FALSE);
8221 /* if the operand is already in dptr
8222 then we do nothing else we move the value to dptr */
8223 if (AOP_TYPE(left) != AOP_STR) {
8224 /* if this is remateriazable */
8225 if (AOP_TYPE(left) == AOP_IMMD)
8226 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8227 else { /* we need to get it byte by byte */
8228 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8229 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8230 if (options.model == MODEL_FLAT24)
8232 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8236 /* so dptr know contains the address */
8237 pic16_freeAsmop(left,NULL,ic,TRUE);
8238 pic16_aopOp(result,ic,FALSE);
8240 /* if bit then unpack */
8241 if (IS_BITVAR(retype))
8242 genUnpackBits(result,"dptr",FPOINTER);
8244 size = AOP_SIZE(result);
8248 pic16_emitcode("movx","a,@dptr");
8249 pic16_aopPut(AOP(result),"a",offset++);
8251 pic16_emitcode("inc","dptr");
8255 pic16_freeAsmop(result,NULL,ic,TRUE);
8258 /*-----------------------------------------------------------------*/
8259 /* genCodePointerGet - get value from code space */
8260 /*-----------------------------------------------------------------*/
8261 static void genCodePointerGet (operand *left,
8262 operand *result, iCode *ic)
8265 sym_link *retype = getSpec(operandType(result));
8267 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8269 pic16_aopOp(left,ic,FALSE);
8271 /* if the operand is already in dptr
8272 then we do nothing else we move the value to dptr */
8273 if (AOP_TYPE(left) != AOP_STR) {
8274 /* if this is remateriazable */
8275 if (AOP_TYPE(left) == AOP_IMMD)
8276 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8277 else { /* we need to get it byte by byte */
8278 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8279 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8280 if (options.model == MODEL_FLAT24)
8282 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8286 /* so dptr know contains the address */
8287 pic16_freeAsmop(left,NULL,ic,TRUE);
8288 pic16_aopOp(result,ic,FALSE);
8290 /* if bit then unpack */
8291 if (IS_BITVAR(retype))
8292 genUnpackBits(result,"dptr",CPOINTER);
8294 size = AOP_SIZE(result);
8298 pic16_emitcode("clr","a");
8299 pic16_emitcode("movc","a,@a+dptr");
8300 pic16_aopPut(AOP(result),"a",offset++);
8302 pic16_emitcode("inc","dptr");
8306 pic16_freeAsmop(result,NULL,ic,TRUE);
8309 /*-----------------------------------------------------------------*/
8310 /* genGenPointerGet - gget value from generic pointer space */
8311 /*-----------------------------------------------------------------*/
8312 static void genGenPointerGet (operand *left,
8313 operand *result, iCode *ic)
8316 sym_link *retype = getSpec(operandType(result));
8318 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8319 pic16_aopOp(left,ic,FALSE);
8320 pic16_aopOp(result,ic,FALSE);
8323 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8325 /* if the operand is already in dptr
8326 then we do nothing else we move the value to dptr */
8327 // if (AOP_TYPE(left) != AOP_STR) {
8328 /* if this is remateriazable */
8329 if (AOP_TYPE(left) == AOP_IMMD) {
8330 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8331 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8333 else { /* we need to get it byte by byte */
8335 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8336 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8338 size = AOP_SIZE(result);
8342 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8343 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8345 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8350 /* so dptr know contains the address */
8352 /* if bit then unpack */
8353 //if (IS_BITVAR(retype))
8354 // genUnpackBits(result,"dptr",GPOINTER);
8357 pic16_freeAsmop(left,NULL,ic,TRUE);
8358 pic16_freeAsmop(result,NULL,ic,TRUE);
8362 /*-----------------------------------------------------------------*/
8363 /* genConstPointerGet - get value from const generic pointer space */
8364 /*-----------------------------------------------------------------*/
8365 static void genConstPointerGet (operand *left,
8366 operand *result, iCode *ic)
8368 //sym_link *retype = getSpec(operandType(result));
8369 symbol *albl = newiTempLabel(NULL);
8370 symbol *blbl = newiTempLabel(NULL);
8373 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8374 pic16_aopOp(left,ic,FALSE);
8375 pic16_aopOp(result,ic,FALSE);
8378 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8380 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8382 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8383 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8384 pic16_emitpLabel(albl->key);
8386 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8388 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8389 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8390 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8391 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8393 pic16_emitpLabel(blbl->key);
8395 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8398 pic16_freeAsmop(left,NULL,ic,TRUE);
8399 pic16_freeAsmop(result,NULL,ic,TRUE);
8402 /*-----------------------------------------------------------------*/
8403 /* genPointerGet - generate code for pointer get */
8404 /*-----------------------------------------------------------------*/
8405 static void genPointerGet (iCode *ic)
8407 operand *left, *result ;
8408 sym_link *type, *etype;
8411 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8414 result = IC_RESULT(ic) ;
8416 /* depending on the type of pointer we need to
8417 move it to the correct pointer register */
8418 type = operandType(left);
8419 etype = getSpec(type);
8422 if (IS_PTR_CONST(type))
8424 if (IS_CODEPTR(type))
8426 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8428 /* if left is of type of pointer then it is simple */
8429 if (IS_PTR(type) && !IS_FUNC(type->next))
8430 p_type = DCL_TYPE(type);
8432 /* we have to go by the storage class */
8433 p_type = PTR_TYPE(SPEC_OCLS(etype));
8435 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8437 if (SPEC_OCLS(etype)->codesp ) {
8438 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8439 //p_type = CPOINTER ;
8442 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8443 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8444 /*p_type = FPOINTER ;*/
8446 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8447 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8448 /* p_type = PPOINTER; */
8450 if (SPEC_OCLS(etype) == idata )
8451 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8452 /* p_type = IPOINTER; */
8454 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8455 /* p_type = POINTER ; */
8458 /* now that we have the pointer type we assign
8459 the pointer values */
8464 genNearPointerGet (left,result,ic);
8468 genPagedPointerGet(left,result,ic);
8472 genFarPointerGet (left,result,ic);
8476 genConstPointerGet (left,result,ic);
8477 //pic16_emitcodePointerGet (left,result,ic);
8482 if (IS_PTR_CONST(type))
8483 genConstPointerGet (left,result,ic);
8486 genGenPointerGet (left,result,ic);
8492 /*-----------------------------------------------------------------*/
8493 /* genPackBits - generates code for packed bit storage */
8494 /*-----------------------------------------------------------------*/
8495 static void genPackBits (sym_link *etype ,
8497 char *rname, int p_type)
8505 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8506 blen = SPEC_BLEN(etype);
8507 bstr = SPEC_BSTR(etype);
8509 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8512 /* if the bit lenth is less than or */
8513 /* it exactly fits a byte then */
8514 if (SPEC_BLEN(etype) <= 8 ) {
8515 shCount = SPEC_BSTR(etype) ;
8517 /* shift left acc */
8520 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8525 pic16_emitcode ("mov","b,a");
8526 pic16_emitcode("mov","a,@%s",rname);
8530 pic16_emitcode ("mov","b,a");
8531 pic16_emitcode("movx","a,@dptr");
8535 pic16_emitcode ("push","b");
8536 pic16_emitcode ("push","acc");
8537 pic16_emitcode ("lcall","__gptrget");
8538 pic16_emitcode ("pop","b");
8542 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8543 ((unsigned char)(0xFF << (blen+bstr)) |
8544 (unsigned char)(0xFF >> (8-bstr)) ) );
8545 pic16_emitcode ("orl","a,b");
8546 if (p_type == GPOINTER)
8547 pic16_emitcode("pop","b");
8553 pic16_emitcode("mov","@%s,a",rname);
8557 pic16_emitcode("movx","@dptr,a");
8561 DEBUGpic16_emitcode(";lcall","__gptrput");
8566 if ( SPEC_BLEN(etype) <= 8 )
8569 pic16_emitcode("inc","%s",rname);
8570 rLen = SPEC_BLEN(etype) ;
8572 /* now generate for lengths greater than one byte */
8575 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8585 pic16_emitcode("mov","@%s,a",rname);
8587 pic16_emitcode("mov","@%s,%s",rname,l);
8592 pic16_emitcode("movx","@dptr,a");
8597 DEBUGpic16_emitcode(";lcall","__gptrput");
8600 pic16_emitcode ("inc","%s",rname);
8605 /* last last was not complete */
8607 /* save the byte & read byte */
8610 pic16_emitcode ("mov","b,a");
8611 pic16_emitcode("mov","a,@%s",rname);
8615 pic16_emitcode ("mov","b,a");
8616 pic16_emitcode("movx","a,@dptr");
8620 pic16_emitcode ("push","b");
8621 pic16_emitcode ("push","acc");
8622 pic16_emitcode ("lcall","__gptrget");
8623 pic16_emitcode ("pop","b");
8627 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8628 pic16_emitcode ("orl","a,b");
8631 if (p_type == GPOINTER)
8632 pic16_emitcode("pop","b");
8637 pic16_emitcode("mov","@%s,a",rname);
8641 pic16_emitcode("movx","@dptr,a");
8645 DEBUGpic16_emitcode(";lcall","__gptrput");
8649 /*-----------------------------------------------------------------*/
8650 /* genDataPointerSet - remat pointer to data space */
8651 /*-----------------------------------------------------------------*/
8652 static void genDataPointerSet(operand *right,
8656 int size, offset = 0 ;
8657 char *l, buffer[256];
8659 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8660 pic16_aopOp(right,ic,FALSE);
8662 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8663 size = AOP_SIZE(right);
8665 if ( AOP_TYPE(result) == AOP_PCODE) {
8666 fprintf(stderr,"genDataPointerSet %s, %d\n",
8667 AOP(result)->aopu.pcop->name,
8668 PCOI(AOP(result)->aopu.pcop)->offset);
8672 // tsd, was l+1 - the underline `_' prefix was being stripped
8675 sprintf(buffer,"(%s + %d)",l,offset);
8676 fprintf(stderr,"oops %s\n",buffer);
8678 sprintf(buffer,"%s",l);
8680 if (AOP_TYPE(right) == AOP_LIT) {
8681 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8682 lit = lit >> (8*offset);
8684 pic16_emitcode("movlw","%d",lit);
8685 pic16_emitcode("movwf","%s",buffer);
8687 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8688 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8689 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8692 pic16_emitcode("clrf","%s",buffer);
8693 //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8694 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8697 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8698 pic16_emitcode("movwf","%s",buffer);
8700 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8701 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8702 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8709 pic16_freeAsmop(right,NULL,ic,TRUE);
8710 pic16_freeAsmop(result,NULL,ic,TRUE);
8713 /*-----------------------------------------------------------------*/
8714 /* genNearPointerSet - pic16_emitcode for near pointer put */
8715 /*-----------------------------------------------------------------*/
8716 static void genNearPointerSet (operand *right,
8723 sym_link *ptype = operandType(result);
8726 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8727 retype= getSpec(operandType(right));
8729 pic16_aopOp(result,ic,FALSE);
8732 /* if the result is rematerializable &
8733 in data space & not a bit variable */
8734 //if (AOP_TYPE(result) == AOP_IMMD &&
8735 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8736 DCL_TYPE(ptype) == POINTER &&
8737 !IS_BITVAR(retype)) {
8738 genDataPointerSet (right,result,ic);
8739 pic16_freeAsmop(result,NULL,ic,TRUE);
8743 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8744 pic16_aopOp(right,ic,FALSE);
8745 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8747 /* if the value is already in a pointer register
8748 then don't need anything more */
8749 if (!AOP_INPREG(AOP(result))) {
8750 /* otherwise get a free pointer register */
8751 //aop = newAsmop(0);
8752 //preg = getFreePtr(ic,&aop,FALSE);
8753 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8754 //pic16_emitcode("mov","%s,%s",
8756 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8757 //rname = preg->name ;
8758 //pic16_emitcode("movwf","fsr0");
8759 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8760 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8761 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8762 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8766 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8769 /* if bitfield then unpack the bits */
8770 if (IS_BITVAR(retype)) {
8771 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8772 "The programmer is obviously confused");
8773 //genPackBits (retype,right,rname,POINTER);
8777 /* we have can just get the values */
8778 int size = AOP_SIZE(right);
8781 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8783 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8786 //pic16_emitcode("mov","@%s,a",rname);
8787 pic16_emitcode("movf","indf0,w ;1");
8790 if (AOP_TYPE(right) == AOP_LIT) {
8791 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8793 pic16_emitcode("movlw","%s",l);
8794 pic16_emitcode("movwf","indf0 ;2");
8796 pic16_emitcode("clrf","indf0");
8798 pic16_emitcode("movf","%s,w",l);
8799 pic16_emitcode("movwf","indf0 ;2");
8801 //pic16_emitcode("mov","@%s,%s",rname,l);
8804 pic16_emitcode("incf","fsr0,f ;3");
8805 //pic16_emitcode("inc","%s",rname);
8810 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8811 /* now some housekeeping stuff */
8813 /* we had to allocate for this iCode */
8814 pic16_freeAsmop(NULL,aop,ic,TRUE);
8816 /* we did not allocate which means left
8817 already in a pointer register, then
8818 if size > 0 && this could be used again
8819 we have to point it back to where it
8821 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8822 if (AOP_SIZE(right) > 1 &&
8823 !OP_SYMBOL(result)->remat &&
8824 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8826 int size = AOP_SIZE(right) - 1;
8828 pic16_emitcode("decf","fsr0,f");
8829 //pic16_emitcode("dec","%s",rname);
8833 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8836 pic16_freeAsmop(right,NULL,ic,TRUE);
8837 pic16_freeAsmop(result,NULL,ic,TRUE);
8840 /*-----------------------------------------------------------------*/
8841 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8842 /*-----------------------------------------------------------------*/
8843 static void genPagedPointerSet (operand *right,
8852 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8854 retype= getSpec(operandType(right));
8856 pic16_aopOp(result,ic,FALSE);
8858 /* if the value is already in a pointer register
8859 then don't need anything more */
8860 if (!AOP_INPREG(AOP(result))) {
8861 /* otherwise get a free pointer register */
8863 preg = getFreePtr(ic,&aop,FALSE);
8864 pic16_emitcode("mov","%s,%s",
8866 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8867 rname = preg->name ;
8869 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8871 pic16_freeAsmop(result,NULL,ic,TRUE);
8872 pic16_aopOp (right,ic,FALSE);
8874 /* if bitfield then unpack the bits */
8875 if (IS_BITVAR(retype))
8876 genPackBits (retype,right,rname,PPOINTER);
8878 /* we have can just get the values */
8879 int size = AOP_SIZE(right);
8883 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8886 pic16_emitcode("movx","@%s,a",rname);
8889 pic16_emitcode("inc","%s",rname);
8895 /* now some housekeeping stuff */
8897 /* we had to allocate for this iCode */
8898 pic16_freeAsmop(NULL,aop,ic,TRUE);
8900 /* we did not allocate which means left
8901 already in a pointer register, then
8902 if size > 0 && this could be used again
8903 we have to point it back to where it
8905 if (AOP_SIZE(right) > 1 &&
8906 !OP_SYMBOL(result)->remat &&
8907 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8909 int size = AOP_SIZE(right) - 1;
8911 pic16_emitcode("dec","%s",rname);
8916 pic16_freeAsmop(right,NULL,ic,TRUE);
8921 /*-----------------------------------------------------------------*/
8922 /* genFarPointerSet - set value from far space */
8923 /*-----------------------------------------------------------------*/
8924 static void genFarPointerSet (operand *right,
8925 operand *result, iCode *ic)
8928 sym_link *retype = getSpec(operandType(right));
8930 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8931 pic16_aopOp(result,ic,FALSE);
8933 /* if the operand is already in dptr
8934 then we do nothing else we move the value to dptr */
8935 if (AOP_TYPE(result) != AOP_STR) {
8936 /* if this is remateriazable */
8937 if (AOP_TYPE(result) == AOP_IMMD)
8938 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8939 else { /* we need to get it byte by byte */
8940 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8941 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8942 if (options.model == MODEL_FLAT24)
8944 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8948 /* so dptr know contains the address */
8949 pic16_freeAsmop(result,NULL,ic,TRUE);
8950 pic16_aopOp(right,ic,FALSE);
8952 /* if bit then unpack */
8953 if (IS_BITVAR(retype))
8954 genPackBits(retype,right,"dptr",FPOINTER);
8956 size = AOP_SIZE(right);
8960 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8962 pic16_emitcode("movx","@dptr,a");
8964 pic16_emitcode("inc","dptr");
8968 pic16_freeAsmop(right,NULL,ic,TRUE);
8971 /*-----------------------------------------------------------------*/
8972 /* genGenPointerSet - set value from generic pointer space */
8973 /*-----------------------------------------------------------------*/
8974 static void genGenPointerSet (operand *right,
8975 operand *result, iCode *ic)
8978 sym_link *retype = getSpec(operandType(right));
8980 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8982 pic16_aopOp(result,ic,FALSE);
8983 pic16_aopOp(right,ic,FALSE);
8984 size = AOP_SIZE(right);
8986 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8988 /* if the operand is already in dptr
8989 then we do nothing else we move the value to dptr */
8990 if (AOP_TYPE(result) != AOP_STR) {
8991 /* if this is remateriazable */
8992 if (AOP_TYPE(result) == AOP_IMMD) {
8993 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8994 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8996 else { /* we need to get it byte by byte */
8997 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8998 size = AOP_SIZE(right);
9001 /* hack hack! see if this the FSR. If so don't load W */
9002 if(AOP_TYPE(right) != AOP_ACC) {
9005 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9006 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9008 if(AOP_SIZE(result) > 1) {
9009 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9010 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9011 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9016 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9018 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9019 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9023 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9024 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9027 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9034 if(aopIdx(AOP(result),0) != 4) {
9036 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9040 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9045 /* so dptr know contains the address */
9048 /* if bit then unpack */
9049 if (IS_BITVAR(retype))
9050 genPackBits(retype,right,"dptr",GPOINTER);
9052 size = AOP_SIZE(right);
9055 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9059 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9060 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9062 if (AOP_TYPE(right) == AOP_LIT)
9063 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9065 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9067 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9074 pic16_freeAsmop(right,NULL,ic,TRUE);
9075 pic16_freeAsmop(result,NULL,ic,TRUE);
9078 /*-----------------------------------------------------------------*/
9079 /* genPointerSet - stores the value into a pointer location */
9080 /*-----------------------------------------------------------------*/
9081 static void genPointerSet (iCode *ic)
9083 operand *right, *result ;
9084 sym_link *type, *etype;
9087 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9089 right = IC_RIGHT(ic);
9090 result = IC_RESULT(ic) ;
9092 /* depending on the type of pointer we need to
9093 move it to the correct pointer register */
9094 type = operandType(result);
9095 etype = getSpec(type);
9096 /* if left is of type of pointer then it is simple */
9097 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9098 p_type = DCL_TYPE(type);
9101 /* we have to go by the storage class */
9102 p_type = PTR_TYPE(SPEC_OCLS(etype));
9104 /* if (SPEC_OCLS(etype)->codesp ) { */
9105 /* p_type = CPOINTER ; */
9108 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9109 /* p_type = FPOINTER ; */
9111 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9112 /* p_type = PPOINTER ; */
9114 /* if (SPEC_OCLS(etype) == idata ) */
9115 /* p_type = IPOINTER ; */
9117 /* p_type = POINTER ; */
9120 /* now that we have the pointer type we assign
9121 the pointer values */
9126 genNearPointerSet (right,result,ic);
9130 genPagedPointerSet (right,result,ic);
9134 genFarPointerSet (right,result,ic);
9138 genGenPointerSet (right,result,ic);
9142 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9143 "genPointerSet: illegal pointer type");
9147 /*-----------------------------------------------------------------*/
9148 /* genIfx - generate code for Ifx statement */
9149 /*-----------------------------------------------------------------*/
9150 static void genIfx (iCode *ic, iCode *popIc)
9152 operand *cond = IC_COND(ic);
9155 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9157 pic16_aopOp(cond,ic,FALSE);
9159 /* get the value into acc */
9160 if (AOP_TYPE(cond) != AOP_CRY)
9161 pic16_toBoolean(cond);
9164 /* the result is now in the accumulator */
9165 pic16_freeAsmop(cond,NULL,ic,TRUE);
9167 /* if there was something to be popped then do it */
9171 /* if the condition is a bit variable */
9172 if (isbit && IS_ITEMP(cond) &&
9174 genIfxJump(ic,SPIL_LOC(cond)->rname);
9175 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9178 if (isbit && !IS_ITEMP(cond))
9179 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9187 /*-----------------------------------------------------------------*/
9188 /* genAddrOf - generates code for address of */
9189 /*-----------------------------------------------------------------*/
9190 static void genAddrOf (iCode *ic)
9192 operand *right, *result, *left;
9195 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9198 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9200 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9201 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9202 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9204 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9206 size = AOP_SIZE(IC_RESULT(ic));
9211 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9212 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9217 pic16_freeAsmop(left,NULL,ic,FALSE);
9218 pic16_freeAsmop(result,NULL,ic,TRUE);
9223 /*-----------------------------------------------------------------*/
9224 /* genFarFarAssign - assignment when both are in far space */
9225 /*-----------------------------------------------------------------*/
9226 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9228 int size = AOP_SIZE(right);
9231 /* first push the right side on to the stack */
9233 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9235 pic16_emitcode ("push","acc");
9238 pic16_freeAsmop(right,NULL,ic,FALSE);
9239 /* now assign DPTR to result */
9240 pic16_aopOp(result,ic,FALSE);
9241 size = AOP_SIZE(result);
9243 pic16_emitcode ("pop","acc");
9244 pic16_aopPut(AOP(result),"a",--offset);
9246 pic16_freeAsmop(result,NULL,ic,FALSE);
9251 /*-----------------------------------------------------------------*/
9252 /* genAssign - generate code for assignment */
9253 /*-----------------------------------------------------------------*/
9254 static void genAssign (iCode *ic)
9256 operand *result, *right;
9257 int size, offset,know_W;
9258 unsigned long lit = 0L;
9260 result = IC_RESULT(ic);
9261 right = IC_RIGHT(ic) ;
9263 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9265 /* if they are the same */
9266 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9269 pic16_aopOp(right,ic,FALSE);
9270 pic16_aopOp(result,ic,TRUE);
9272 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9274 /* if they are the same registers */
9275 if (pic16_sameRegs(AOP(right),AOP(result)))
9278 /* if the result is a bit */
9279 if (AOP_TYPE(result) == AOP_CRY) {
9280 /* if the right size is a literal then
9281 we know what the value is */
9282 if (AOP_TYPE(right) == AOP_LIT) {
9284 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9285 pic16_popGet(AOP(result),0));
9287 if (((int) operandLitValue(right)))
9288 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9289 AOP(result)->aopu.aop_dir,
9290 AOP(result)->aopu.aop_dir);
9292 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9293 AOP(result)->aopu.aop_dir,
9294 AOP(result)->aopu.aop_dir);
9298 /* the right is also a bit variable */
9299 if (AOP_TYPE(right) == AOP_CRY) {
9300 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9301 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9302 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9304 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9305 AOP(result)->aopu.aop_dir,
9306 AOP(result)->aopu.aop_dir);
9307 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9308 AOP(right)->aopu.aop_dir,
9309 AOP(right)->aopu.aop_dir);
9310 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9311 AOP(result)->aopu.aop_dir,
9312 AOP(result)->aopu.aop_dir);
9317 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9318 pic16_toBoolean(right);
9320 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9321 //pic16_aopPut(AOP(result),"a",0);
9325 /* bit variables done */
9327 size = AOP_SIZE(result);
9329 if(AOP_TYPE(right) == AOP_LIT)
9330 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9332 /* VR - What is this?! */
9333 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9334 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9335 if(aopIdx(AOP(result),0) == 4) {
9336 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9337 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9338 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9341 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9346 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9347 if(AOP_TYPE(right) == AOP_LIT) {
9349 if(know_W != (lit&0xff))
9350 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9352 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9354 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9358 } else if (AOP_TYPE(right) == AOP_CRY) {
9359 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9361 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9362 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9365 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9368 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9369 normally should work, but mind that thw W register live range
9370 is not checked, so if the code generator assumes that the W
9371 is already loaded after such a pair, wrong code will be generated.
9373 Checking the live range is the next step.
9374 This is experimental code yet and has not been fully tested yet.
9375 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9376 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9379 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9381 /* This is the old code, which is assumed(?!) that works fine(!?) */
9383 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9384 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9393 pic16_freeAsmop (right,NULL,ic,FALSE);
9394 pic16_freeAsmop (result,NULL,ic,TRUE);
9397 /*-----------------------------------------------------------------*/
9398 /* genJumpTab - generates code for jump table */
9399 /*-----------------------------------------------------------------*/
9400 static void genJumpTab (iCode *ic)
9405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9407 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9408 /* get the condition into accumulator */
9409 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9411 /* multiply by three */
9412 pic16_emitcode("add","a,acc");
9413 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9415 jtab = newiTempLabel(NULL);
9416 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9417 pic16_emitcode("jmp","@a+dptr");
9418 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9420 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9421 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9423 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9424 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9425 pic16_emitpLabel(jtab->key);
9427 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9429 /* now generate the jump labels */
9430 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9431 jtab = setNextItem(IC_JTLABELS(ic))) {
9432 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9433 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9439 /*-----------------------------------------------------------------*/
9440 /* genMixedOperation - gen code for operators between mixed types */
9441 /*-----------------------------------------------------------------*/
9443 TSD - Written for the PIC port - but this unfortunately is buggy.
9444 This routine is good in that it is able to efficiently promote
9445 types to different (larger) sizes. Unfortunately, the temporary
9446 variables that are optimized out by this routine are sometimes
9447 used in other places. So until I know how to really parse the
9448 iCode tree, I'm going to not be using this routine :(.
9450 static int genMixedOperation (iCode *ic)
9453 operand *result = IC_RESULT(ic);
9454 sym_link *ctype = operandType(IC_LEFT(ic));
9455 operand *right = IC_RIGHT(ic);
9461 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9463 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9469 nextright = IC_RIGHT(nextic);
9470 nextleft = IC_LEFT(nextic);
9471 nextresult = IC_RESULT(nextic);
9473 pic16_aopOp(right,ic,FALSE);
9474 pic16_aopOp(result,ic,FALSE);
9475 pic16_aopOp(nextright, nextic, FALSE);
9476 pic16_aopOp(nextleft, nextic, FALSE);
9477 pic16_aopOp(nextresult, nextic, FALSE);
9479 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9485 pic16_emitcode(";remove right +","");
9487 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9493 pic16_emitcode(";remove left +","");
9497 big = AOP_SIZE(nextleft);
9498 small = AOP_SIZE(nextright);
9500 switch(nextic->op) {
9503 pic16_emitcode(";optimize a +","");
9504 /* if unsigned or not an integral type */
9505 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9506 pic16_emitcode(";add a bit to something","");
9509 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9511 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9512 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9513 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9515 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9523 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9524 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9525 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9528 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9530 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9531 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9532 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9533 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9534 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9537 pic16_emitcode("rlf","known_zero,w");
9544 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9545 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9546 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9548 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9558 pic16_freeAsmop(right,NULL,ic,TRUE);
9559 pic16_freeAsmop(result,NULL,ic,TRUE);
9560 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9561 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9563 nextic->generated = 1;
9570 /*-----------------------------------------------------------------*/
9571 /* genCast - gen code for casting */
9572 /*-----------------------------------------------------------------*/
9573 static void genCast (iCode *ic)
9575 operand *result = IC_RESULT(ic);
9576 sym_link *ctype = operandType(IC_LEFT(ic));
9577 sym_link *rtype = operandType(IC_RIGHT(ic));
9578 operand *right = IC_RIGHT(ic);
9581 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9582 /* if they are equivalent then do nothing */
9583 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9586 pic16_aopOp(right,ic,FALSE) ;
9587 pic16_aopOp(result,ic,FALSE);
9589 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9591 /* if the result is a bit */
9592 if (AOP_TYPE(result) == AOP_CRY) {
9593 /* if the right size is a literal then
9594 we know what the value is */
9595 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9596 if (AOP_TYPE(right) == AOP_LIT) {
9598 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9599 pic16_popGet(AOP(result),0));
9601 if (((int) operandLitValue(right)))
9602 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9603 AOP(result)->aopu.aop_dir,
9604 AOP(result)->aopu.aop_dir);
9606 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9607 AOP(result)->aopu.aop_dir,
9608 AOP(result)->aopu.aop_dir);
9613 /* the right is also a bit variable */
9614 if (AOP_TYPE(right) == AOP_CRY) {
9617 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9619 pic16_emitcode("clrc","");
9620 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9621 AOP(right)->aopu.aop_dir,
9622 AOP(right)->aopu.aop_dir);
9623 pic16_aopPut(AOP(result),"c",0);
9628 if (AOP_TYPE(right) == AOP_REG) {
9629 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9630 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9631 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9633 pic16_toBoolean(right);
9634 pic16_aopPut(AOP(result),"a",0);
9638 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9640 size = AOP_SIZE(result);
9642 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9644 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9645 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9646 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9649 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9654 /* if they are the same size : or less */
9655 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9657 /* if they are in the same place */
9658 if (pic16_sameRegs(AOP(right),AOP(result)))
9661 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9663 if (IS_PTR_CONST(rtype))
9665 if (IS_CODEPTR(rtype))
9667 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9669 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9671 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
9673 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9675 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9676 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9677 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9678 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9679 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9680 if(AOP_SIZE(result) <2)
9681 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9685 /* if they in different places then copy */
9686 size = AOP_SIZE(result);
9689 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9690 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9692 //pic16_aopPut(AOP(result),
9693 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9703 /* if the result is of type pointer */
9704 if (IS_PTR(ctype)) {
9707 sym_link *type = operandType(right);
9708 sym_link *etype = getSpec(type);
9709 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9711 /* pointer to generic pointer */
9712 if (IS_GENPTR(ctype)) {
9716 p_type = DCL_TYPE(type);
9718 /* we have to go by the storage class */
9719 p_type = PTR_TYPE(SPEC_OCLS(etype));
9721 /* if (SPEC_OCLS(etype)->codesp ) */
9722 /* p_type = CPOINTER ; */
9724 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9725 /* p_type = FPOINTER ; */
9727 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9728 /* p_type = PPOINTER; */
9730 /* if (SPEC_OCLS(etype) == idata ) */
9731 /* p_type = IPOINTER ; */
9733 /* p_type = POINTER ; */
9736 /* the first two bytes are known */
9737 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9738 size = GPTRSIZE - 1;
9741 if(offset < AOP_SIZE(right)) {
9742 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9743 if ((AOP_TYPE(right) == AOP_PCODE) &&
9744 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9745 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9746 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9748 pic16_aopPut(AOP(result),
9749 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9753 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9756 /* the last byte depending on type */
9760 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9763 pic16_emitcode(";BUG!? ","%d",__LINE__);
9767 pic16_emitcode(";BUG!? ","%d",__LINE__);
9771 pic16_emitcode(";BUG!? ","%d",__LINE__);
9776 /* this should never happen */
9777 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9778 "got unknown pointer type");
9781 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9785 /* just copy the pointers */
9786 size = AOP_SIZE(result);
9789 pic16_aopPut(AOP(result),
9790 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9799 /* so we now know that the size of destination is greater
9800 than the size of the source.
9801 Now, if the next iCode is an operator then we might be
9802 able to optimize the operation without performing a cast.
9804 if(genMixedOperation(ic))
9807 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9809 /* we move to result for the size of source */
9810 size = AOP_SIZE(right);
9813 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9814 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9818 /* now depending on the sign of the destination */
9819 size = AOP_SIZE(result) - AOP_SIZE(right);
9820 /* if unsigned or not an integral type */
9821 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9823 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9825 /* we need to extend the sign :{ */
9828 /* Save one instruction of casting char to int */
9829 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9830 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9831 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
9833 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9836 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9838 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9840 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9843 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
9848 pic16_freeAsmop(right,NULL,ic,TRUE);
9849 pic16_freeAsmop(result,NULL,ic,TRUE);
9853 /*-----------------------------------------------------------------*/
9854 /* genDjnz - generate decrement & jump if not zero instrucion */
9855 /*-----------------------------------------------------------------*/
9856 static int genDjnz (iCode *ic, iCode *ifx)
9859 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9864 /* if the if condition has a false label
9865 then we cannot save */
9869 /* if the minus is not of the form
9871 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9872 !IS_OP_LITERAL(IC_RIGHT(ic)))
9875 if (operandLitValue(IC_RIGHT(ic)) != 1)
9878 /* if the size of this greater than one then no
9880 if (getSize(operandType(IC_RESULT(ic))) > 1)
9883 /* otherwise we can save BIG */
9884 lbl = newiTempLabel(NULL);
9885 lbl1= newiTempLabel(NULL);
9887 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9889 if (IS_AOP_PREG(IC_RESULT(ic))) {
9890 pic16_emitcode("dec","%s",
9891 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9892 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9893 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9897 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9898 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9900 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9901 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9904 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9905 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9906 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9907 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9910 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9915 /*-----------------------------------------------------------------*/
9916 /* genReceive - generate code for a receive iCode */
9917 /*-----------------------------------------------------------------*/
9918 static void genReceive (iCode *ic)
9920 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9922 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9923 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9924 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9926 int size = getSize(operandType(IC_RESULT(ic)));
9927 int offset = pic16_fReturnSizePic - size;
9929 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9930 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9933 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9934 size = AOP_SIZE(IC_RESULT(ic));
9937 pic16_emitcode ("pop","acc");
9938 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9943 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9945 assignResultValue(IC_RESULT(ic));
9948 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9951 /*-----------------------------------------------------------------*/
9952 /* genDummyRead - generate code for dummy read of volatiles */
9953 /*-----------------------------------------------------------------*/
9955 genDummyRead (iCode * ic)
9957 pic16_emitcode ("; genDummyRead","");
9958 pic16_emitcode ("; not implemented","");
9963 /*-----------------------------------------------------------------*/
9964 /* genpic16Code - generate code for pic16 based controllers */
9965 /*-----------------------------------------------------------------*/
9967 * At this point, ralloc.c has gone through the iCode and attempted
9968 * to optimize in a way suitable for a PIC. Now we've got to generate
9969 * PIC instructions that correspond to the iCode.
9971 * Once the instructions are generated, we'll pass through both the
9972 * peep hole optimizer and the pCode optimizer.
9973 *-----------------------------------------------------------------*/
9975 void genpic16Code (iCode *lic)
9980 lineHead = lineCurr = NULL;
9982 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9983 pic16_addpBlock(pb);
9986 /* if debug information required */
9987 if (options.debug && currFunc) {
9989 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9991 if (IS_STATIC(currFunc->etype)) {
9992 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9993 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9995 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9996 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10005 for (ic = lic ; ic ; ic = ic->next ) {
10007 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10008 // DEBUGpic16_emitcode("; VR", "");
10009 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10010 if ( cln != ic->lineno ) {
10011 if ( options.debug ) {
10013 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10014 FileBaseName(ic->filename),ic->lineno,
10015 ic->level,ic->block);
10019 pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
10020 pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
10021 printCLine(ic->filename, ic->lineno));
10023 pic16_addpCode2pBlock(pb,
10024 pic16_newpCodeCSource(ic->lineno,
10026 printCLine(ic->filename, ic->lineno)));
10030 /* if the result is marked as
10031 spilt and rematerializable or code for
10032 this has already been generated then
10034 if (resultRemat(ic) || ic->generated )
10037 /* depending on the operation */
10056 /* IPOP happens only when trying to restore a
10057 spilt live range, if there is an ifx statement
10058 following this pop then the if statement might
10059 be using some of the registers being popped which
10060 would destroy the contents of the register so
10061 we need to check for this condition and handle it */
10063 ic->next->op == IFX &&
10064 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10065 genIfx (ic->next,ic);
10083 genEndFunction (ic);
10099 pic16_genPlus (ic) ;
10103 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10104 pic16_genMinus (ic);
10120 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10124 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10131 /* note these two are xlated by algebraic equivalence
10132 during parsing SDCC.y */
10133 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10134 "got '>=' or '<=' shouldn't have come here");
10138 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10150 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10154 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10158 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10182 genRightShift (ic);
10185 case GET_VALUE_AT_ADDRESS:
10190 if (POINTER_SET(ic))
10217 addSet(&_G.sendSet,ic);
10220 case DUMMY_READ_VOLATILE:
10230 /* now we are ready to call the
10231 peep hole optimizer */
10232 if (!options.nopeep) {
10233 peepHole (&lineHead);
10235 /* now do the actual printing */
10236 printLine (lineHead,codeOutFile);
10239 DFPRINTF((stderr,"printing pBlock\n\n"));
10240 pic16_printpBlock(stdout,pb);