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"
48 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
49 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
50 void pic16_genMult8X8_8 (operand *, operand *,operand *);
51 pCode *pic16_AssembleLine(char *line);
52 extern void pic16_printpBlock(FILE *of, pBlock *pb);
53 static asmop *newAsmop (short type);
54 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
55 static void mov2w (asmop *aop, int offset);
56 static int aopIdx (asmop *aop, int offset);
58 static int labelOffset=0;
59 extern int pic16_debug_verbose;
60 static int optimized_for_speed = 0;
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__);
767 /* if this a literal */
768 if (IS_OP_LITERAL(op)) {
769 op->aop = aop = newAsmop(AOP_LIT);
770 aop->aopu.aop_lit = op->operand.valOperand;
771 aop->size = getSize(operandType(op));
776 sym_link *type = operandType(op);
778 if(IS_PTR_CONST(type))
782 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
785 /* if already has a asmop then continue */
789 /* if the underlying symbol has a aop */
790 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
791 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
792 op->aop = OP_SYMBOL(op)->aop;
796 /* if this is a true symbol */
797 if (IS_TRUE_SYMOP(op)) {
798 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
799 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
803 /* this is a temporary : this has
809 e) can be a return use only */
813 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
814 /* if the type is a conditional */
815 if (sym->regType == REG_CND) {
816 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
821 /* if it is spilt then two situations
823 b) has a spill location */
824 if (sym->isspilt || sym->nRegs == 0) {
826 DEBUGpic16_emitcode(";","%d",__LINE__);
827 /* rematerialize it NOW */
830 sym->aop = op->aop = aop =
832 aop->size = getSize(sym->type);
833 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
839 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
840 aop->size = getSize(sym->type);
841 for ( i = 0 ; i < 2 ; i++ )
842 aop->aopu.aop_str[i] = accUse[i];
843 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
849 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
850 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
851 //pic16_allocDirReg (IC_LEFT(ic));
852 aop->size = getSize(sym->type);
857 aop = op->aop = sym->aop = newAsmop(AOP_STR);
858 aop->size = getSize(sym->type);
859 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
860 aop->aopu.aop_str[i] = fReturn[i];
862 DEBUGpic16_emitcode(";","%d",__LINE__);
866 /* else spill location */
867 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
868 /* force a new aop if sizes differ */
869 sym->usl.spillLoc->aop = NULL;
871 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
872 __FUNCTION__,__LINE__,
873 sym->usl.spillLoc->rname,
874 sym->rname, sym->usl.spillLoc->offset);
876 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
877 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
878 aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname,
880 sym->usl.spillLoc->offset);
881 aop->size = getSize(sym->type);
887 sym_link *type = operandType(op);
889 if(IS_PTR_CONST(type))
893 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
896 /* must be in a register */
897 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
898 sym->aop = op->aop = aop = newAsmop(AOP_REG);
899 aop->size = sym->nRegs;
900 for ( i = 0 ; i < sym->nRegs ;i++)
901 aop->aopu.aop_reg[i] = sym->regs[i];
904 /*-----------------------------------------------------------------*/
905 /* pic16_freeAsmop - free up the asmop given to an operand */
906 /*----------------------------------------------------------------*/
907 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
924 /* depending on the asmop type only three cases need work AOP_RO
925 , AOP_R1 && AOP_STK */
931 pic16_emitcode ("pop","ar0");
935 bitVectUnSetBit(ic->rUsed,R0_IDX);
941 pic16_emitcode ("pop","ar1");
945 bitVectUnSetBit(ic->rUsed,R1_IDX);
951 int stk = aop->aopu.aop_stk + aop->size;
952 bitVectUnSetBit(ic->rUsed,R0_IDX);
953 bitVectUnSetBit(ic->rUsed,R1_IDX);
955 getFreePtr(ic,&aop,FALSE);
957 if (options.stack10bit)
959 /* I'm not sure what to do here yet... */
962 "*** Warning: probably generating bad code for "
963 "10 bit stack mode.\n");
967 pic16_emitcode ("mov","a,_bp");
968 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
969 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
971 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
975 pic16_emitcode("pop","acc");
976 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
978 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
981 pic16_freeAsmop(op,NULL,ic,TRUE);
983 pic16_emitcode("pop","ar0");
988 pic16_emitcode("pop","ar1");
996 /* all other cases just dealloc */
1000 OP_SYMBOL(op)->aop = NULL;
1001 /* if the symbol has a spill */
1003 SPIL_LOC(op)->aop = NULL;
1008 /*-----------------------------------------------------------------*/
1009 /* pic16_aopGet - for fetching value of the aop */
1010 /*-----------------------------------------------------------------*/
1011 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1016 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1017 /* offset is greater than
1019 if (offset > (aop->size - 1) &&
1020 aop->type != AOP_LIT)
1023 /* depending on type */
1024 switch (aop->type) {
1028 DEBUGpic16_emitcode(";","%d",__LINE__);
1029 /* if we need to increment it */
1030 while (offset > aop->coff) {
1031 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1035 while (offset < aop->coff) {
1036 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1040 aop->coff = offset ;
1042 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1043 return (dname ? "acc" : "a");
1045 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1046 rs = Safe_calloc(1,strlen(s)+1);
1052 DEBUGpic16_emitcode(";","%d",__LINE__);
1053 if (aop->type == AOP_DPTR2)
1058 while (offset > aop->coff) {
1059 pic16_emitcode ("inc","dptr");
1063 while (offset < aop->coff) {
1064 pic16_emitcode("lcall","__decdptr");
1070 pic16_emitcode("clr","a");
1071 pic16_emitcode("movc","a,@a+dptr");
1074 pic16_emitcode("movx","a,@dptr");
1077 if (aop->type == AOP_DPTR2)
1082 return (dname ? "acc" : "a");
1087 sprintf (s,"%s",aop->aopu.aop_immd);
1090 sprintf(s,"(%s >> %d)",
1095 aop->aopu.aop_immd);
1096 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1097 rs = Safe_calloc(1,strlen(s)+1);
1103 sprintf(s,"(%s + %d)",
1106 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1108 sprintf(s,"%s",aop->aopu.aop_dir);
1109 rs = Safe_calloc(1,strlen(s)+1);
1115 // return aop->aopu.aop_reg[offset]->dname;
1117 return aop->aopu.aop_reg[offset]->name;
1120 //pic16_emitcode(";","%d",__LINE__);
1121 return aop->aopu.aop_dir;
1124 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1125 return "AOP_accumulator_bug";
1128 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1129 rs = Safe_calloc(1,strlen(s)+1);
1134 aop->coff = offset ;
1135 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1138 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1140 return aop->aopu.aop_str[offset];
1144 pCodeOp *pcop = aop->aopu.pcop;
1145 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1147 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1148 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1149 sprintf(s,"%s", pcop->name);
1151 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1154 rs = Safe_calloc(1,strlen(s)+1);
1160 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1161 "aopget got unsupported aop->type");
1166 /*-----------------------------------------------------------------*/
1167 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1168 /*-----------------------------------------------------------------*/
1169 pCodeOp *pic16_popGetTempReg(void)
1174 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1175 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1176 PCOR(pcop)->r->wasUsed=1;
1177 PCOR(pcop)->r->isFree=0;
1183 /*-----------------------------------------------------------------*/
1184 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1185 /*-----------------------------------------------------------------*/
1186 void pic16_popReleaseTempReg(pCodeOp *pcop)
1189 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1190 PCOR(pcop)->r->isFree = 1;
1193 /*-----------------------------------------------------------------*/
1194 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1195 /*-----------------------------------------------------------------*/
1196 pCodeOp *pic16_popGetLabel(unsigned int key)
1199 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1204 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1207 /*-----------------------------------------------------------------*/
1208 /* pic16_popCopyReg - copy a pcode operator */
1209 /*-----------------------------------------------------------------*/
1210 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1214 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1215 pcor->pcop.type = pc->pcop.type;
1217 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1218 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1220 pcor->pcop.name = NULL;
1223 pcor->rIdx = pc->rIdx;
1226 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1231 /*-----------------------------------------------------------------*/
1232 /* pic16_popGetLit - asm operator to pcode operator conversion */
1233 /*-----------------------------------------------------------------*/
1234 pCodeOp *pic16_popGetLit(unsigned int lit)
1236 return pic16_newpCodeOpLit(lit);
1239 /*-----------------------------------------------------------------*/
1240 /* pic16_popGetLit2 - asm operator to pcode operator conversion */
1241 /*-----------------------------------------------------------------*/
1242 pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2)
1244 return pic16_newpCodeOpLit2(lit, lit2);
1248 /*-----------------------------------------------------------------*/
1249 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1250 /*-----------------------------------------------------------------*/
1251 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1254 return pic16_newpCodeOpImmd(name, offset,index, 0);
1258 /*-----------------------------------------------------------------*/
1259 /* pic16_popGet - asm operator to pcode operator conversion */
1260 /*-----------------------------------------------------------------*/
1261 pCodeOp *pic16_popGetWithString(char *str)
1267 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1271 pcop = pic16_newpCodeOp(str,PO_STR);
1276 /*-----------------------------------------------------------------*/
1277 /* pic16_popRegFromString - */
1278 /*-----------------------------------------------------------------*/
1279 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
1282 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1283 pcop->type = PO_DIR;
1285 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1286 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1291 pcop->name = Safe_calloc(1,strlen(str)+1);
1292 strcpy(pcop->name,str);
1294 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1296 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1297 if(PCOR(pcop)->r == NULL) {
1298 // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n",
1299 // __FUNCTION__, __LINE__, str, size, offset);
1300 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1302 //fprintf(stderr, "allocating new register -> %s\n", str);
1304 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1306 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1308 PCOR(pcop)->instance = offset;
1313 static pCodeOp *popRegFromIdx(int rIdx)
1317 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1318 __FUNCTION__,__LINE__,rIdx);
1320 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1322 PCOR(pcop)->rIdx = rIdx;
1323 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1324 PCOR(pcop)->r->isFree = 0;
1325 PCOR(pcop)->r->wasUsed = 1;
1327 pcop->type = PCOR(pcop)->r->pc_type;
1333 /*---------------------------------------------------------------------------------*/
1334 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1336 /*---------------------------------------------------------------------------------*/
1337 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1342 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1343 temp = pic16_popGet(aop_dst, offset);
1344 pcop2->pcop2 = temp;
1349 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst)
1353 pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
1354 pcop2->pcop2 = pic16_popCopyReg(dst);
1359 /*-----------------------------------------------------------------*/
1360 /* pic16_popGet - asm operator to pcode operator conversion */
1361 /*-----------------------------------------------------------------*/
1362 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1364 //char *s = buffer ;
1369 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1370 /* offset is greater than
1373 if (offset > (aop->size - 1) &&
1374 aop->type != AOP_LIT)
1375 return NULL; //zero;
1377 /* depending on type */
1378 switch (aop->type) {
1385 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1389 DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__);
1390 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1393 DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__);
1394 return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1398 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1400 DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__);
1401 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1402 PCOR(pcop)->rIdx = rIdx;
1403 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1404 PCOR(pcop)->r->wasUsed=1;
1405 PCOR(pcop)->r->isFree=0;
1407 PCOR(pcop)->instance = offset;
1408 pcop->type = PCOR(pcop)->r->pc_type;
1409 //rs = aop->aopu.aop_reg[offset]->name;
1410 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1415 DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__);
1417 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1418 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1419 //if(PCOR(pcop)->r == NULL)
1420 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1424 DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__);
1425 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1428 DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]);
1429 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1432 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1433 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1434 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1435 pcop->type = PCOR(pcop)->r->pc_type;
1436 pcop->name = PCOR(pcop)->r->name;
1442 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1444 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1445 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1446 PCOI(pcop)->offset = offset;
1450 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1451 "pic16_popGet got unsupported aop->type");
1454 /*-----------------------------------------------------------------*/
1455 /* pic16_aopPut - puts a string for a aop */
1456 /*-----------------------------------------------------------------*/
1457 void pic16_aopPut (asmop *aop, char *s, int offset)
1462 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1464 if (aop->size && offset > ( aop->size - 1)) {
1465 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1466 "pic16_aopPut got offset > aop->size");
1470 /* will assign value to value */
1471 /* depending on where it is ofcourse */
1472 switch (aop->type) {
1475 sprintf(d,"(%s + %d)",
1476 aop->aopu.aop_dir,offset);
1477 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1480 sprintf(d,"%s",aop->aopu.aop_dir);
1483 DEBUGpic16_emitcode(";","%d",__LINE__);
1485 pic16_emitcode("movf","%s,w",s);
1486 pic16_emitcode("movwf","%s",d);
1489 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1490 if(offset >= aop->size) {
1491 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1494 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1497 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1504 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1505 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1508 strcmp(s,"r0") == 0 ||
1509 strcmp(s,"r1") == 0 ||
1510 strcmp(s,"r2") == 0 ||
1511 strcmp(s,"r3") == 0 ||
1512 strcmp(s,"r4") == 0 ||
1513 strcmp(s,"r5") == 0 ||
1514 strcmp(s,"r6") == 0 ||
1515 strcmp(s,"r7") == 0 )
1516 pic16_emitcode("mov","%s,%s ; %d",
1517 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1521 if(strcmp(s,"W")==0 )
1522 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1524 pic16_emitcode("movwf","%s",
1525 aop->aopu.aop_reg[offset]->name);
1527 if(strcmp(s,zero)==0) {
1528 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1530 } else if(strcmp(s,"W")==0) {
1531 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1532 pcop->type = PO_GPR_REGISTER;
1534 PCOR(pcop)->rIdx = -1;
1535 PCOR(pcop)->r = NULL;
1537 DEBUGpic16_emitcode(";","%d",__LINE__);
1538 pcop->name = Safe_strdup(s);
1539 pic16_emitpcode(POC_MOVFW,pcop);
1540 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1541 } else if(strcmp(s,one)==0) {
1542 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1543 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1545 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1553 if (aop->type == AOP_DPTR2)
1559 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1560 "pic16_aopPut writting to code space");
1564 while (offset > aop->coff) {
1566 pic16_emitcode ("inc","dptr");
1569 while (offset < aop->coff) {
1571 pic16_emitcode("lcall","__decdptr");
1576 /* if not in accumulater */
1579 pic16_emitcode ("movx","@dptr,a");
1581 if (aop->type == AOP_DPTR2)
1589 while (offset > aop->coff) {
1591 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1593 while (offset < aop->coff) {
1595 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1601 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1606 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1608 if (strcmp(s,"r0") == 0 ||
1609 strcmp(s,"r1") == 0 ||
1610 strcmp(s,"r2") == 0 ||
1611 strcmp(s,"r3") == 0 ||
1612 strcmp(s,"r4") == 0 ||
1613 strcmp(s,"r5") == 0 ||
1614 strcmp(s,"r6") == 0 ||
1615 strcmp(s,"r7") == 0 ) {
1617 sprintf(buffer,"a%s",s);
1618 pic16_emitcode("mov","@%s,%s",
1619 aop->aopu.aop_ptr->name,buffer);
1621 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1626 if (strcmp(s,"a") == 0)
1627 pic16_emitcode("push","acc");
1629 pic16_emitcode("push","%s",s);
1634 /* if bit variable */
1635 if (!aop->aopu.aop_dir) {
1636 pic16_emitcode("clr","a");
1637 pic16_emitcode("rlc","a");
1640 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1643 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1646 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1648 lbl = newiTempLabel(NULL);
1650 if (strcmp(s,"a")) {
1653 pic16_emitcode("clr","c");
1654 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1655 pic16_emitcode("cpl","c");
1656 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1657 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1664 if (strcmp(aop->aopu.aop_str[offset],s))
1665 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1670 if (!offset && (strcmp(s,"acc") == 0))
1673 if (strcmp(aop->aopu.aop_str[offset],s))
1674 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1678 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1679 "pic16_aopPut got unsupported aop->type");
1685 /*-----------------------------------------------------------------*/
1686 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1687 /*-----------------------------------------------------------------*/
1688 static void mov2w (asmop *aop, int offset)
1694 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1696 if ( aop->type == AOP_PCODE ||
1697 aop->type == AOP_LIT )
1698 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1700 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1705 /*-----------------------------------------------------------------*/
1706 /* pushw - pushes wreg to stack */
1707 /*-----------------------------------------------------------------*/
1710 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1711 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1));
1715 /*-----------------------------------------------------------------*/
1716 /* pushaop - pushes aop to stack */
1717 /*-----------------------------------------------------------------*/
1718 void pushaop(asmop *aop, int offset)
1720 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1721 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1));
1725 /*-----------------------------------------------------------------*/
1726 /* popaop - pops aop from stack */
1727 /*-----------------------------------------------------------------*/
1728 void popaop(asmop *aop, int offset)
1734 void popaopidx(asmop *aop, int offset, int index)
1738 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1740 if(STACK_MODEL_LARGE)ofs++;
1742 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
1743 pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset))));
1746 /*-----------------------------------------------------------------*/
1747 /* reAdjustPreg - points a register back to where it should */
1748 /*-----------------------------------------------------------------*/
1749 static void reAdjustPreg (asmop *aop)
1753 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1755 if ((size = aop->size) <= 1)
1758 switch (aop->type) {
1762 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1766 if (aop->type == AOP_DPTR2)
1772 pic16_emitcode("lcall","__decdptr");
1775 if (aop->type == AOP_DPTR2)
1787 /*-----------------------------------------------------------------*/
1788 /* opIsGptr: returns non-zero if the passed operand is */
1789 /* a generic pointer type. */
1790 /*-----------------------------------------------------------------*/
1791 static int opIsGptr(operand *op)
1793 sym_link *type = operandType(op);
1795 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1796 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1804 /*-----------------------------------------------------------------*/
1805 /* pic16_getDataSize - get the operand data size */
1806 /*-----------------------------------------------------------------*/
1807 int pic16_getDataSize(operand *op)
1809 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1812 return AOP_SIZE(op);
1814 // tsd- in the pic port, the genptr size is 1, so this code here
1815 // fails. ( in the 8051 port, the size was 4).
1818 size = AOP_SIZE(op);
1819 if (size == GPTRSIZE)
1821 sym_link *type = operandType(op);
1822 if (IS_GENPTR(type))
1824 /* generic pointer; arithmetic operations
1825 * should ignore the high byte (pointer type).
1828 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1835 /*-----------------------------------------------------------------*/
1836 /* pic16_outAcc - output Acc */
1837 /*-----------------------------------------------------------------*/
1838 void pic16_outAcc(operand *result)
1841 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1842 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1845 size = pic16_getDataSize(result);
1847 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1850 /* unsigned or positive */
1852 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1857 /*-----------------------------------------------------------------*/
1858 /* pic16_outBitC - output a bit C */
1859 /*-----------------------------------------------------------------*/
1860 void pic16_outBitC(operand *result)
1863 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1864 /* if the result is bit */
1865 if (AOP_TYPE(result) == AOP_CRY)
1866 pic16_aopPut(AOP(result),"c",0);
1868 pic16_emitcode("clr","a ; %d", __LINE__);
1869 pic16_emitcode("rlc","a");
1870 pic16_outAcc(result);
1874 /*-----------------------------------------------------------------*/
1875 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1876 /*-----------------------------------------------------------------*/
1877 void pic16_toBoolean(operand *oper)
1879 int size = AOP_SIZE(oper) - 1;
1882 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1884 if ( AOP_TYPE(oper) != AOP_ACC) {
1885 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1888 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1893 #if !defined(GEN_Not)
1894 /*-----------------------------------------------------------------*/
1895 /* genNot - generate code for ! operation */
1896 /*-----------------------------------------------------------------*/
1897 static void pic16_genNot (iCode *ic)
1902 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1903 /* assign asmOps to operand & result */
1904 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1905 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1907 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1908 /* if in bit space then a special case */
1909 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1910 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1911 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1912 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1914 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1915 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1916 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1921 size = AOP_SIZE(IC_LEFT(ic));
1923 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1924 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1925 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1928 pic16_toBoolean(IC_LEFT(ic));
1930 tlbl = newiTempLabel(NULL);
1931 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1932 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1933 pic16_outBitC(IC_RESULT(ic));
1936 /* release the aops */
1937 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1938 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1943 #if !defined(GEN_Cpl)
1944 /*-----------------------------------------------------------------*/
1945 /* genCpl - generate code for complement */
1946 /*-----------------------------------------------------------------*/
1947 static void pic16_genCpl (iCode *ic)
1953 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1954 /* assign asmOps to operand & result */
1955 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1956 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1958 /* if both are in bit space then
1960 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1961 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1963 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1964 pic16_emitcode("cpl","c");
1965 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1969 size = AOP_SIZE(IC_RESULT(ic));
1972 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1974 pic16_emitcode("cpl","a");
1975 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1977 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1978 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
1980 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1981 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1989 /* release the aops */
1990 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1991 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1995 /*-----------------------------------------------------------------*/
1996 /* genUminusFloat - unary minus for floating points */
1997 /*-----------------------------------------------------------------*/
1998 static void genUminusFloat(operand *op,operand *result)
2000 int size ,offset =0 ;
2003 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2004 /* for this we just need to flip the
2005 first it then copy the rest in place */
2006 size = AOP_SIZE(op) - 1;
2007 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
2011 pic16_emitcode("cpl","acc.7");
2012 pic16_aopPut(AOP(result),"a",3);
2015 pic16_aopPut(AOP(result),
2016 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2022 /*-----------------------------------------------------------------*/
2023 /* genUminus - unary minus code generation */
2024 /*-----------------------------------------------------------------*/
2025 static void genUminus (iCode *ic)
2028 sym_link *optype, *rtype;
2031 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2033 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2034 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2036 /* if both in bit space then special
2038 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2039 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2041 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2042 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2043 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2048 optype = operandType(IC_LEFT(ic));
2049 rtype = operandType(IC_RESULT(ic));
2051 /* if float then do float stuff */
2052 if (IS_FLOAT(optype)) {
2053 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2057 /* otherwise subtract from zero by taking the 2's complement */
2058 size = AOP_SIZE(IC_LEFT(ic));
2060 for(i=0; i<size; i++) {
2061 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2062 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2064 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2065 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2069 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2070 for(i=1; i<size; i++) {
2072 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2076 /* release the aops */
2077 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2078 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2081 /*-----------------------------------------------------------------*/
2082 /* saveRegisters - will look for a call and save the registers */
2083 /*-----------------------------------------------------------------*/
2084 static void saveRegisters(iCode *lic)
2091 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2093 for (ic = lic ; ic ; ic = ic->next)
2094 if (ic->op == CALL || ic->op == PCALL)
2098 fprintf(stderr,"found parameter push with no function call\n");
2102 /* if the registers have been saved already then
2104 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2107 /* find the registers in use at this time
2108 and push them away to safety */
2109 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2113 if (options.useXstack) {
2114 if (bitVectBitValue(rsave,R0_IDX))
2115 pic16_emitcode("mov","b,r0");
2116 pic16_emitcode("mov","r0,%s",spname);
2117 for (i = 0 ; i < pic16_nRegs ; i++) {
2118 if (bitVectBitValue(rsave,i)) {
2120 pic16_emitcode("mov","a,b");
2122 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2123 pic16_emitcode("movx","@r0,a");
2124 pic16_emitcode("inc","r0");
2127 pic16_emitcode("mov","%s,r0",spname);
2128 if (bitVectBitValue(rsave,R0_IDX))
2129 pic16_emitcode("mov","r0,b");
2131 //for (i = 0 ; i < pic16_nRegs ; i++) {
2132 // if (bitVectBitValue(rsave,i))
2133 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2136 dtype = operandType(IC_LEFT(ic));
2137 if (currFunc && dtype &&
2138 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2139 IFFUNC_ISISR(currFunc->type) &&
2142 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2145 /*-----------------------------------------------------------------*/
2146 /* unsaveRegisters - pop the pushed registers */
2147 /*-----------------------------------------------------------------*/
2148 static void unsaveRegisters (iCode *ic)
2153 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2154 /* find the registers in use at this time
2155 and push them away to safety */
2156 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2159 if (options.useXstack) {
2160 pic16_emitcode("mov","r0,%s",spname);
2161 for (i = pic16_nRegs ; i >= 0 ; i--) {
2162 if (bitVectBitValue(rsave,i)) {
2163 pic16_emitcode("dec","r0");
2164 pic16_emitcode("movx","a,@r0");
2166 pic16_emitcode("mov","b,a");
2168 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2172 pic16_emitcode("mov","%s,r0",spname);
2173 if (bitVectBitValue(rsave,R0_IDX))
2174 pic16_emitcode("mov","r0,b");
2176 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2177 // if (bitVectBitValue(rsave,i))
2178 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2184 /*-----------------------------------------------------------------*/
2186 /*-----------------------------------------------------------------*/
2187 static void pushSide(operand * oper, int size)
2191 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2193 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2194 if (AOP_TYPE(oper) != AOP_REG &&
2195 AOP_TYPE(oper) != AOP_DIR &&
2197 pic16_emitcode("mov","a,%s",l);
2198 pic16_emitcode("push","acc");
2200 pic16_emitcode("push","%s",l);
2205 /*-----------------------------------------------------------------*/
2206 /* assignResultValue - */
2207 /*-----------------------------------------------------------------*/
2208 static void assignResultValue(operand * oper)
2210 int size = AOP_SIZE(oper);
2212 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2213 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2215 if(!GpsuedoStkPtr) {
2216 // DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
2217 /* The last byte in the assignment is in W */
2219 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2224 // DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
2225 // DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
2229 popaopidx(AOP(oper), size, GpsuedoStkPtr);
2231 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2234 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2235 #endif /* STACK_SUPPORT */
2240 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2242 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2250 /*-----------------------------------------------------------------*/
2251 /* genIpush - genrate code for pushing this gets a little complex */
2252 /*-----------------------------------------------------------------*/
2253 static void genIpush (iCode *ic)
2256 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2258 int size, offset = 0 ;
2262 /* if this is not a parm push : ie. it is spill push
2263 and spill push is always done on the local stack */
2264 if (!ic->parmPush) {
2266 /* and the item is spilt then do nothing */
2267 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2270 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2271 size = AOP_SIZE(IC_LEFT(ic));
2272 /* push it on the stack */
2274 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2279 pic16_emitcode("push","%s",l);
2284 /* this is a paramter push: in this case we call
2285 the routine to find the call and save those
2286 registers that need to be saved */
2289 /* then do the push */
2290 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2293 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2294 size = AOP_SIZE(IC_LEFT(ic));
2297 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2298 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2299 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2301 pic16_emitcode("mov","a,%s",l);
2302 pic16_emitcode("push","acc");
2304 pic16_emitcode("push","%s",l);
2307 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2311 /*-----------------------------------------------------------------*/
2312 /* genIpop - recover the registers: can happen only for spilling */
2313 /*-----------------------------------------------------------------*/
2314 static void genIpop (iCode *ic)
2316 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2321 /* if the temp was not pushed then */
2322 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2325 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2326 size = AOP_SIZE(IC_LEFT(ic));
2329 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2332 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2336 /*-----------------------------------------------------------------*/
2337 /* unsaverbank - restores the resgister bank from stack */
2338 /*-----------------------------------------------------------------*/
2339 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2341 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2347 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2349 if (options.useXstack) {
2351 r = getFreePtr(ic,&aop,FALSE);
2354 pic16_emitcode("mov","%s,_spx",r->name);
2355 pic16_emitcode("movx","a,@%s",r->name);
2356 pic16_emitcode("mov","psw,a");
2357 pic16_emitcode("dec","%s",r->name);
2360 pic16_emitcode ("pop","psw");
2363 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2364 if (options.useXstack) {
2365 pic16_emitcode("movx","a,@%s",r->name);
2366 //pic16_emitcode("mov","(%s+%d),a",
2367 // regspic16[i].base,8*bank+regspic16[i].offset);
2368 pic16_emitcode("dec","%s",r->name);
2371 pic16_emitcode("pop",""); //"(%s+%d)",
2372 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2375 if (options.useXstack) {
2377 pic16_emitcode("mov","_spx,%s",r->name);
2378 pic16_freeAsmop(NULL,aop,ic,TRUE);
2384 /*-----------------------------------------------------------------*/
2385 /* saverbank - saves an entire register bank on the stack */
2386 /*-----------------------------------------------------------------*/
2387 static void saverbank (int bank, iCode *ic, bool pushPsw)
2389 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2396 if (options.useXstack) {
2399 r = getFreePtr(ic,&aop,FALSE);
2400 pic16_emitcode("mov","%s,_spx",r->name);
2404 for (i = 0 ; i < pic16_nRegs ;i++) {
2405 if (options.useXstack) {
2406 pic16_emitcode("inc","%s",r->name);
2407 //pic16_emitcode("mov","a,(%s+%d)",
2408 // regspic16[i].base,8*bank+regspic16[i].offset);
2409 pic16_emitcode("movx","@%s,a",r->name);
2411 pic16_emitcode("push","");// "(%s+%d)",
2412 //regspic16[i].base,8*bank+regspic16[i].offset);
2416 if (options.useXstack) {
2417 pic16_emitcode("mov","a,psw");
2418 pic16_emitcode("movx","@%s,a",r->name);
2419 pic16_emitcode("inc","%s",r->name);
2420 pic16_emitcode("mov","_spx,%s",r->name);
2421 pic16_freeAsmop (NULL,aop,ic,TRUE);
2424 pic16_emitcode("push","psw");
2426 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2434 /*-----------------------------------------------------------------*/
2435 /* genCall - generates a call statement */
2436 /*-----------------------------------------------------------------*/
2437 static void genCall (iCode *ic)
2442 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2444 /* if caller saves & we have not saved then */
2448 /* if we are calling a function that is not using
2449 * the same register bank then we need to save the
2450 * destination registers on the stack */
2451 dtype = operandType(IC_LEFT(ic));
2452 if (currFunc && dtype &&
2453 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2454 IFFUNC_ISISR(currFunc->type) &&
2457 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2459 /* if send set is not empty the assign */
2463 /* For the Pic port, there is no data stack.
2464 * So parameters passed to functions are stored
2465 * in registers. (The pCode optimizer will get
2466 * rid of most of these :). */
2468 int psuedoStkPtr=-1;
2469 int firstTimeThruLoop = 1;
2471 _G.sendSet = reverseSet(_G.sendSet);
2473 /* First figure how many parameters are getting passed */
2474 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2475 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2476 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2477 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2480 stackParms = psuedoStkPtr;
2482 for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) {
2483 int size, offset = 0;
2485 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2486 size = AOP_SIZE(IC_LEFT(sic));
2489 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2490 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2491 DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1);
2493 if(!firstTimeThruLoop) {
2494 /* If this is not the first time we've been through the loop
2495 * then we need to save the parameter in a temporary
2496 * register. The last byte of the last parameter is
2502 --psuedoStkPtr; // sanity check
2504 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2507 pic16_emitpcode(POC_MOVWF, popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2508 #endif /* STACK_SUPPORT */
2511 firstTimeThruLoop=0;
2513 mov2w (AOP(IC_LEFT(sic)), offset);
2516 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2522 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2523 OP_SYMBOL(IC_LEFT(ic))->rname :
2524 OP_SYMBOL(IC_LEFT(ic))->name));
2527 /* if we need assign a result value */
2528 if ((IS_ITEMP(IC_RESULT(ic)) &&
2529 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2530 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2531 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2534 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2537 assignResultValue(IC_RESULT(ic));
2539 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2540 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2542 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2547 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
2548 pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
2549 if(STACK_MODEL_LARGE) {
2551 pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
2556 /* adjust the stack for parameters if required */
2557 fprintf(stderr, "%s:%d: ic->parmBytes= %d\n", __FILE__, __LINE__, ic->parmBytes);
2559 if (ic->parmBytes) {
2562 if (ic->parmBytes > 3) {
2563 pic16_emitcode("mov","a,%s",spname);
2564 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2565 pic16_emitcode("mov","%s,a",spname);
2567 for ( i = 0 ; i < ic->parmBytes ;i++)
2568 pic16_emitcode("dec","%s",spname);
2571 /* if register bank was saved then pop them */
2573 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2575 /* if we hade saved some registers then unsave them */
2576 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2577 unsaveRegisters (ic);
2580 /*-----------------------------------------------------------------*/
2581 /* genPcall - generates a call by pointer statement */
2582 /*-----------------------------------------------------------------*/
2583 static void genPcall (iCode *ic)
2586 symbol *rlbl = newiTempLabel(NULL);
2589 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2590 /* if caller saves & we have not saved then */
2594 /* if we are calling a function that is not using
2595 the same register bank then we need to save the
2596 destination registers on the stack */
2597 dtype = operandType(IC_LEFT(ic));
2598 if (currFunc && dtype &&
2599 IFFUNC_ISISR(currFunc->type) &&
2600 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2601 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2604 /* push the return address on to the stack */
2605 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2606 pic16_emitcode("push","acc");
2607 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2608 pic16_emitcode("push","acc");
2610 if (options.model == MODEL_FLAT24)
2612 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2613 pic16_emitcode("push","acc");
2616 /* now push the calling address */
2617 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2619 pushSide(IC_LEFT(ic), FPTRSIZE);
2621 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2623 /* if send set is not empty the assign */
2627 for (sic = setFirstItem(_G.sendSet) ; sic ;
2628 sic = setNextItem(_G.sendSet)) {
2629 int size, offset = 0;
2630 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2631 size = AOP_SIZE(IC_LEFT(sic));
2633 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2635 if (strcmp(l,fReturn[offset]))
2636 pic16_emitcode("mov","%s,%s",
2641 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2646 pic16_emitcode("ret","");
2647 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2650 /* if we need assign a result value */
2651 if ((IS_ITEMP(IC_RESULT(ic)) &&
2652 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2653 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2654 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2657 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2660 assignResultValue(IC_RESULT(ic));
2662 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2665 /* adjust the stack for parameters if
2667 if (ic->parmBytes) {
2669 if (ic->parmBytes > 3) {
2670 pic16_emitcode("mov","a,%s",spname);
2671 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2672 pic16_emitcode("mov","%s,a",spname);
2674 for ( i = 0 ; i < ic->parmBytes ;i++)
2675 pic16_emitcode("dec","%s",spname);
2679 /* if register bank was saved then unsave them */
2680 if (currFunc && dtype &&
2681 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2682 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2684 /* if we hade saved some registers then
2687 unsaveRegisters (ic);
2691 /*-----------------------------------------------------------------*/
2692 /* resultRemat - result is rematerializable */
2693 /*-----------------------------------------------------------------*/
2694 static int resultRemat (iCode *ic)
2696 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2697 if (SKIP_IC(ic) || ic->op == IFX)
2700 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2701 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2702 if (sym->remat && !POINTER_SET(ic))
2709 #if defined(__BORLANDC__) || defined(_MSC_VER)
2710 #define STRCASECMP stricmp
2712 #define STRCASECMP strcasecmp
2716 /*-----------------------------------------------------------------*/
2717 /* inExcludeList - return 1 if the string is in exclude Reg list */
2718 /*-----------------------------------------------------------------*/
2719 static bool inExcludeList(char *s)
2721 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2724 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2725 if (options.excludeRegs[i] &&
2726 STRCASECMP(options.excludeRegs[i],"none") == 0)
2729 for ( i = 0 ; options.excludeRegs[i]; i++) {
2730 if (options.excludeRegs[i] &&
2731 STRCASECMP(s,options.excludeRegs[i]) == 0)
2738 /*-----------------------------------------------------------------*/
2739 /* genFunction - generated code for function entry */
2740 /*-----------------------------------------------------------------*/
2741 static void genFunction (iCode *ic)
2746 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2748 labelOffset += (max_key+4);
2752 /* create the function header */
2753 pic16_emitcode(";","-----------------------------------------");
2754 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2755 pic16_emitcode(";","-----------------------------------------");
2757 pic16_emitcode("","%s:",sym->rname);
2758 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2760 ftype = operandType(IC_LEFT(ic));
2762 /* if critical function then turn interrupts off */
2763 if (IFFUNC_ISCRITICAL(ftype))
2764 pic16_emitcode("clr","ea");
2766 /* here we need to generate the equates for the
2767 register bank if required */
2769 if (FUNC_REGBANK(ftype) != rbank) {
2772 rbank = FUNC_REGBANK(ftype);
2773 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2774 if (strcmp(regspic16[i].base,"0") == 0)
2775 pic16_emitcode("","%s = 0x%02x",
2777 8*rbank+regspic16[i].offset);
2779 pic16_emitcode ("","%s = %s + 0x%02x",
2782 8*rbank+regspic16[i].offset);
2787 /* if this is an interrupt service routine then
2788 save acc, b, dpl, dph */
2789 if (IFFUNC_ISISR(sym->type)) {
2792 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2794 /* what is the reason of having these 3 NOPS? VR - 030701 */
2795 pic16_emitpcodeNULLop(POC_NOP);
2796 pic16_emitpcodeNULLop(POC_NOP);
2797 pic16_emitpcodeNULLop(POC_NOP);
2800 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2801 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2802 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2803 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2805 pic16_pBlockConvert2ISR(pb);
2807 if (!inExcludeList("acc"))
2808 pic16_emitcode ("push","acc");
2809 if (!inExcludeList("b"))
2810 pic16_emitcode ("push","b");
2811 if (!inExcludeList("dpl"))
2812 pic16_emitcode ("push","dpl");
2813 if (!inExcludeList("dph"))
2814 pic16_emitcode ("push","dph");
2815 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2817 pic16_emitcode ("push", "dpx");
2818 /* Make sure we're using standard DPTR */
2819 pic16_emitcode ("push", "dps");
2820 pic16_emitcode ("mov", "dps, #0x00");
2821 if (options.stack10bit)
2823 /* This ISR could conceivably use DPTR2. Better save it. */
2824 pic16_emitcode ("push", "dpl1");
2825 pic16_emitcode ("push", "dph1");
2826 pic16_emitcode ("push", "dpx1");
2829 /* if this isr has no bank i.e. is going to
2830 run with bank 0 , then we need to save more
2832 if (!FUNC_REGBANK(sym->type)) {
2834 /* if this function does not call any other
2835 function then we can be economical and
2836 save only those registers that are used */
2837 if (! IFFUNC_HASFCALL(sym->type)) {
2840 /* if any registers used */
2841 if (sym->regsUsed) {
2842 /* save the registers used */
2843 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2844 if (bitVectBitValue(sym->regsUsed,i) ||
2845 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2846 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2851 /* this function has a function call cannot
2852 determines register usage so we will have the
2854 saverbank(0,ic,FALSE);
2859 /* if callee-save to be used for this function
2860 then save the registers being used in this function */
2861 if (IFFUNC_CALLEESAVES(sym->type)) {
2864 /* if any registers used */
2865 if (sym->regsUsed) {
2866 /* save the registers used */
2867 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2868 if (bitVectBitValue(sym->regsUsed,i) ||
2869 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2870 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2878 /* emit code to setup stack frame if user enabled,
2879 * and function is not main() */
2881 fprintf(stderr, "function name: %s\n", sym->name);
2882 if(USE_STACK && strcmp(sym->name, "main")) {
2883 /* setup the stack frame */
2884 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1));
2885 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l));
2886 if(STACK_MODEL_LARGE)
2887 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h));
2893 /* set the register bank to the desired value */
2894 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2895 pic16_emitcode("push","psw");
2896 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2899 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2901 if (options.useXstack) {
2902 pic16_emitcode("mov","r0,%s",spname);
2903 pic16_emitcode("mov","a,_bp");
2904 pic16_emitcode("movx","@r0,a");
2905 pic16_emitcode("inc","%s",spname);
2909 /* set up the stack */
2910 pic16_emitcode ("push","_bp"); /* save the callers stack */
2912 pic16_emitcode ("mov","_bp,%s",spname);
2915 DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
2917 /* adjust the stack for the function */
2922 werror(W_STACK_OVERFLOW,sym->name);
2924 if (i > 3 && sym->recvSize < 4) {
2925 pic16_emitcode ("mov","a,sp");
2926 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2927 pic16_emitcode ("mov","sp,a");
2932 pic16_emitcode("inc","sp");
2936 DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
2937 pic16_emitcode ("mov","a,_spx");
2938 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2939 pic16_emitcode ("mov","_spx,a");
2944 /*-----------------------------------------------------------------*/
2945 /* genEndFunction - generates epilogue for functions */
2946 /*-----------------------------------------------------------------*/
2947 static void genEndFunction (iCode *ic)
2949 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2951 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2953 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2955 pic16_emitcode ("mov","%s,_bp",spname);
2958 /* if use external stack but some variables were
2959 added to the local stack then decrement the
2961 if (options.useXstack && sym->stack) {
2962 pic16_emitcode("mov","a,sp");
2963 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2964 pic16_emitcode("mov","sp,a");
2968 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2969 if (options.useXstack) {
2970 pic16_emitcode("mov","r0,%s",spname);
2971 pic16_emitcode("movx","a,@r0");
2972 pic16_emitcode("mov","_bp,a");
2973 pic16_emitcode("dec","%s",spname);
2977 pic16_emitcode ("pop","_bp");
2981 /* restore the register bank */
2982 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2983 pic16_emitcode ("pop","psw");
2985 if (IFFUNC_ISISR(sym->type)) {
2987 /* now we need to restore the registers */
2988 /* if this isr has no bank i.e. is going to
2989 run with bank 0 , then we need to save more
2991 if (!FUNC_REGBANK(sym->type)) {
2993 /* if this function does not call any other
2994 function then we can be economical and
2995 save only those registers that are used */
2996 if (! IFFUNC_HASFCALL(sym->type)) {
2999 /* if any registers used */
3000 if (sym->regsUsed) {
3001 /* save the registers used */
3002 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3003 if (bitVectBitValue(sym->regsUsed,i) ||
3004 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3005 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
3010 /* this function has a function call cannot
3011 determines register usage so we will have the
3013 unsaverbank(0,ic,FALSE);
3017 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
3019 if (options.stack10bit)
3021 pic16_emitcode ("pop", "dpx1");
3022 pic16_emitcode ("pop", "dph1");
3023 pic16_emitcode ("pop", "dpl1");
3025 pic16_emitcode ("pop", "dps");
3026 pic16_emitcode ("pop", "dpx");
3028 if (!inExcludeList("dph"))
3029 pic16_emitcode ("pop","dph");
3030 if (!inExcludeList("dpl"))
3031 pic16_emitcode ("pop","dpl");
3032 if (!inExcludeList("b"))
3033 pic16_emitcode ("pop","b");
3034 if (!inExcludeList("acc"))
3035 pic16_emitcode ("pop","acc");
3037 if (IFFUNC_ISCRITICAL(sym->type))
3038 pic16_emitcode("setb","ea");
3041 /* if debug then send end of function */
3042 /* if (options.debug && currFunc) { */
3045 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3046 FileBaseName(ic->filename),currFunc->lastLine,
3047 ic->level,ic->block);
3048 if (IS_STATIC(currFunc->etype))
3049 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3051 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3055 // pic16_emitcode ("reti","");
3057 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
3058 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
3059 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
3060 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
3061 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
3064 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
3067 pic16_emitpcodeNULLop(POC_RETFIE);
3071 if (IFFUNC_ISCRITICAL(sym->type))
3072 pic16_emitcode("setb","ea");
3074 if (IFFUNC_CALLEESAVES(sym->type)) {
3077 /* if any registers used */
3078 if (sym->regsUsed) {
3079 /* save the registers used */
3080 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3081 if (bitVectBitValue(sym->regsUsed,i) ||
3082 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3083 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
3089 /* if debug then send end of function */
3092 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3093 FileBaseName(ic->filename),currFunc->lastLine,
3094 ic->level,ic->block);
3095 if (IS_STATIC(currFunc->etype))
3096 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3098 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3103 /* insert code to restore stack frame, if user enabled it
3104 * and function is not main() */
3106 if(USE_STACK && strcmp(sym->name, "main")) {
3107 /* restore stack frame */
3108 if(STACK_MODEL_LARGE)
3109 pic16_emitpcode(POC_MOVFF,
3110 pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h ));
3111 pic16_emitpcode(POC_MOVFF,
3112 pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l ));
3115 * I added this because of a mistake in the stack pointers design
3116 * They should be removed though
3118 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2h));
3119 pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2l));
3124 pic16_emitcode ("return","");
3125 pic16_emitpcodeNULLop(POC_RETURN);
3127 /* Mark the end of a function */
3128 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3133 /*-----------------------------------------------------------------*/
3134 /* genRet - generate code for return statement */
3135 /*-----------------------------------------------------------------*/
3136 static void genRet (iCode *ic)
3138 int size,offset = 0 , pushed = 0;
3140 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3141 /* if we have no return value then
3142 just generate the "ret" */
3146 /* we have something to return then
3147 move the return value into place */
3148 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3149 size = AOP_SIZE(IC_LEFT(ic));
3153 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3155 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3157 pic16_emitcode("push","%s",l);
3160 DEBUGpic16_emitcode(";", "%d", __LINE__);
3161 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3163 DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l);
3164 if (strcmp(fReturn[offset],l)) {
3165 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3166 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3167 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3169 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3172 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3182 if (strcmp(fReturn[pushed],"a"))
3183 pic16_emitcode("pop",fReturn[pushed]);
3185 pic16_emitcode("pop","acc");
3188 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3191 /* generate a jump to the return label
3192 if the next is not the return statement */
3193 if (!(ic->next && ic->next->op == LABEL &&
3194 IC_LABEL(ic->next) == returnLabel)) {
3196 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3197 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3202 /*-----------------------------------------------------------------*/
3203 /* genLabel - generates a label */
3204 /*-----------------------------------------------------------------*/
3205 static void genLabel (iCode *ic)
3207 /* special case never generate */
3208 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3209 if (IC_LABEL(ic) == entryLabel)
3212 pic16_emitpLabel(IC_LABEL(ic)->key);
3213 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3216 /*-----------------------------------------------------------------*/
3217 /* genGoto - generates a goto */
3218 /*-----------------------------------------------------------------*/
3220 static void genGoto (iCode *ic)
3222 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3223 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3227 /*-----------------------------------------------------------------*/
3228 /* genMultbits :- multiplication of bits */
3229 /*-----------------------------------------------------------------*/
3230 static void genMultbits (operand *left,
3234 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3236 if(!pic16_sameRegs(AOP(result),AOP(right)))
3237 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3239 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3240 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3241 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3246 /*-----------------------------------------------------------------*/
3247 /* genMultOneByte : 8 bit multiplication & division */
3248 /*-----------------------------------------------------------------*/
3249 static void genMultOneByte (operand *left,
3253 sym_link *opetype = operandType(result);
3258 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3259 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3260 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3262 /* (if two literals, the value is computed before) */
3263 /* if one literal, literal on the right */
3264 if (AOP_TYPE(left) == AOP_LIT){
3270 size = AOP_SIZE(result);
3273 if (AOP_TYPE(right) == AOP_LIT){
3274 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3275 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3276 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3277 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3278 pic16_emitcode("call","genMultLit");
3280 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3281 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3282 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3283 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3284 pic16_emitcode("call","pic16_genMult8X8_8");
3287 pic16_genMult8X8_8 (left, right,result);
3290 /* signed or unsigned */
3291 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3292 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3294 //pic16_emitcode("mul","ab");
3295 /* if result size = 1, mul signed = mul unsigned */
3296 //pic16_aopPut(AOP(result),"a",0);
3298 } else { // (size > 1)
3300 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3301 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3302 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3303 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3305 if (SPEC_USIGN(opetype)){
3306 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3307 pic16_genUMult8X8_16 (left, right, result, NULL);
3310 /* for filling the MSBs */
3311 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3312 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3316 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3318 pic16_emitcode("mov","a,b");
3320 /* adjust the MSB if left or right neg */
3322 /* if one literal */
3323 if (AOP_TYPE(right) == AOP_LIT){
3324 pic16_emitcode("multiply ","right is a lit");
3325 /* AND literal negative */
3326 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3327 /* adjust MSB (c==0 after mul) */
3328 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3332 pic16_genSMult8X8_16 (left, right, result, NULL);
3336 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3338 pic16_emitcode("rlc","a");
3339 pic16_emitcode("subb","a,acc");
3347 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3348 //pic16_aopPut(AOP(result),"a",offset++);
3352 /*-----------------------------------------------------------------*/
3353 /* genMult - generates code for multiplication */
3354 /*-----------------------------------------------------------------*/
3355 static void genMult (iCode *ic)
3357 operand *left = IC_LEFT(ic);
3358 operand *right = IC_RIGHT(ic);
3359 operand *result= IC_RESULT(ic);
3361 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3362 /* assign the amsops */
3363 pic16_aopOp (left,ic,FALSE);
3364 pic16_aopOp (right,ic,FALSE);
3365 pic16_aopOp (result,ic,TRUE);
3367 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3369 /* special cases first */
3371 if (AOP_TYPE(left) == AOP_CRY &&
3372 AOP_TYPE(right)== AOP_CRY) {
3373 genMultbits(left,right,result);
3377 /* if both are of size == 1 */
3378 if (AOP_SIZE(left) == 1 &&
3379 AOP_SIZE(right) == 1 ) {
3380 genMultOneByte(left,right,result);
3384 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3386 /* should have been converted to function call */
3390 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3391 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3392 pic16_freeAsmop(result,NULL,ic,TRUE);
3395 /*-----------------------------------------------------------------*/
3396 /* genDivbits :- division of bits */
3397 /*-----------------------------------------------------------------*/
3398 static void genDivbits (operand *left,
3405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3406 /* the result must be bit */
3407 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3408 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3412 pic16_emitcode("div","ab");
3413 pic16_emitcode("rrc","a");
3414 pic16_aopPut(AOP(result),"c",0);
3417 /*-----------------------------------------------------------------*/
3418 /* genDivOneByte : 8 bit division */
3419 /*-----------------------------------------------------------------*/
3420 static void genDivOneByte (operand *left,
3424 sym_link *opetype = operandType(result);
3429 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3430 size = AOP_SIZE(result) - 1;
3432 /* signed or unsigned */
3433 if (SPEC_USIGN(opetype)) {
3434 /* unsigned is easy */
3435 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3436 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3438 pic16_emitcode("div","ab");
3439 pic16_aopPut(AOP(result),"a",0);
3441 pic16_aopPut(AOP(result),zero,offset++);
3445 /* signed is a little bit more difficult */
3447 /* save the signs of the operands */
3448 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3450 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3451 pic16_emitcode("push","acc"); /* save it on the stack */
3453 /* now sign adjust for both left & right */
3454 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3456 lbl = newiTempLabel(NULL);
3457 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3458 pic16_emitcode("cpl","a");
3459 pic16_emitcode("inc","a");
3460 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3461 pic16_emitcode("mov","b,a");
3463 /* sign adjust left side */
3464 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3467 lbl = newiTempLabel(NULL);
3468 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3469 pic16_emitcode("cpl","a");
3470 pic16_emitcode("inc","a");
3471 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3473 /* now the division */
3474 pic16_emitcode("div","ab");
3475 /* we are interested in the lower order
3477 pic16_emitcode("mov","b,a");
3478 lbl = newiTempLabel(NULL);
3479 pic16_emitcode("pop","acc");
3480 /* if there was an over flow we don't
3481 adjust the sign of the result */
3482 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3483 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3485 pic16_emitcode("clr","a");
3486 pic16_emitcode("subb","a,b");
3487 pic16_emitcode("mov","b,a");
3488 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3490 /* now we are done */
3491 pic16_aopPut(AOP(result),"b",0);
3493 pic16_emitcode("mov","c,b.7");
3494 pic16_emitcode("subb","a,acc");
3497 pic16_aopPut(AOP(result),"a",offset++);
3501 /*-----------------------------------------------------------------*/
3502 /* genDiv - generates code for division */
3503 /*-----------------------------------------------------------------*/
3504 static void genDiv (iCode *ic)
3506 operand *left = IC_LEFT(ic);
3507 operand *right = IC_RIGHT(ic);
3508 operand *result= IC_RESULT(ic);
3510 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3511 /* assign the amsops */
3512 pic16_aopOp (left,ic,FALSE);
3513 pic16_aopOp (right,ic,FALSE);
3514 pic16_aopOp (result,ic,TRUE);
3516 /* special cases first */
3518 if (AOP_TYPE(left) == AOP_CRY &&
3519 AOP_TYPE(right)== AOP_CRY) {
3520 genDivbits(left,right,result);
3524 /* if both are of size == 1 */
3525 if (AOP_SIZE(left) == 1 &&
3526 AOP_SIZE(right) == 1 ) {
3527 genDivOneByte(left,right,result);
3531 /* should have been converted to function call */
3534 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3535 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3536 pic16_freeAsmop(result,NULL,ic,TRUE);
3539 /*-----------------------------------------------------------------*/
3540 /* genModbits :- modulus of bits */
3541 /*-----------------------------------------------------------------*/
3542 static void genModbits (operand *left,
3549 /* the result must be bit */
3550 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3551 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3555 pic16_emitcode("div","ab");
3556 pic16_emitcode("mov","a,b");
3557 pic16_emitcode("rrc","a");
3558 pic16_aopPut(AOP(result),"c",0);
3561 /*-----------------------------------------------------------------*/
3562 /* genModOneByte : 8 bit modulus */
3563 /*-----------------------------------------------------------------*/
3564 static void genModOneByte (operand *left,
3568 sym_link *opetype = operandType(result);
3572 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3573 /* signed or unsigned */
3574 if (SPEC_USIGN(opetype)) {
3575 /* unsigned is easy */
3576 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3577 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3579 pic16_emitcode("div","ab");
3580 pic16_aopPut(AOP(result),"b",0);
3584 /* signed is a little bit more difficult */
3586 /* save the signs of the operands */
3587 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3590 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3591 pic16_emitcode("push","acc"); /* save it on the stack */
3593 /* now sign adjust for both left & right */
3594 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3597 lbl = newiTempLabel(NULL);
3598 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3599 pic16_emitcode("cpl","a");
3600 pic16_emitcode("inc","a");
3601 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3602 pic16_emitcode("mov","b,a");
3604 /* sign adjust left side */
3605 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3608 lbl = newiTempLabel(NULL);
3609 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3610 pic16_emitcode("cpl","a");
3611 pic16_emitcode("inc","a");
3612 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3614 /* now the multiplication */
3615 pic16_emitcode("div","ab");
3616 /* we are interested in the lower order
3618 lbl = newiTempLabel(NULL);
3619 pic16_emitcode("pop","acc");
3620 /* if there was an over flow we don't
3621 adjust the sign of the result */
3622 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3623 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3625 pic16_emitcode("clr","a");
3626 pic16_emitcode("subb","a,b");
3627 pic16_emitcode("mov","b,a");
3628 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3630 /* now we are done */
3631 pic16_aopPut(AOP(result),"b",0);
3635 /*-----------------------------------------------------------------*/
3636 /* genMod - generates code for division */
3637 /*-----------------------------------------------------------------*/
3638 static void genMod (iCode *ic)
3640 operand *left = IC_LEFT(ic);
3641 operand *right = IC_RIGHT(ic);
3642 operand *result= IC_RESULT(ic);
3644 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3645 /* assign the amsops */
3646 pic16_aopOp (left,ic,FALSE);
3647 pic16_aopOp (right,ic,FALSE);
3648 pic16_aopOp (result,ic,TRUE);
3650 /* special cases first */
3652 if (AOP_TYPE(left) == AOP_CRY &&
3653 AOP_TYPE(right)== AOP_CRY) {
3654 genModbits(left,right,result);
3658 /* if both are of size == 1 */
3659 if (AOP_SIZE(left) == 1 &&
3660 AOP_SIZE(right) == 1 ) {
3661 genModOneByte(left,right,result);
3665 /* should have been converted to function call */
3669 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3670 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3671 pic16_freeAsmop(result,NULL,ic,TRUE);
3674 /*-----------------------------------------------------------------*/
3675 /* genIfxJump :- will create a jump depending on the ifx */
3676 /*-----------------------------------------------------------------*/
3678 note: May need to add parameter to indicate when a variable is in bit space.
3680 static void genIfxJump (iCode *ic, char *jval)
3683 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3684 /* if true label then we jump if condition
3686 if ( IC_TRUE(ic) ) {
3688 if(strcmp(jval,"a") == 0)
3690 else if (strcmp(jval,"c") == 0)
3693 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3694 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3697 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3698 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3702 /* false label is present */
3703 if(strcmp(jval,"a") == 0)
3705 else if (strcmp(jval,"c") == 0)
3708 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3709 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3712 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3713 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3718 /* mark the icode as generated */
3722 /*-----------------------------------------------------------------*/
3724 /*-----------------------------------------------------------------*/
3725 static void genSkip(iCode *ifx,int status_bit)
3730 if ( IC_TRUE(ifx) ) {
3731 switch(status_bit) {
3746 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3747 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3751 switch(status_bit) {
3765 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3766 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3772 /*-----------------------------------------------------------------*/
3774 /*-----------------------------------------------------------------*/
3775 static void genSkipc(resolvedIfx *rifx)
3785 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3786 rifx->generated = 1;
3789 /*-----------------------------------------------------------------*/
3791 /*-----------------------------------------------------------------*/
3792 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3797 if( (rifx->condition ^ invert_condition) & 1)
3802 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3803 rifx->generated = 1;
3806 /*-----------------------------------------------------------------*/
3808 /*-----------------------------------------------------------------*/
3809 static void genSkipz(iCode *ifx, int condition)
3820 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3822 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3825 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3827 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3830 /*-----------------------------------------------------------------*/
3832 /*-----------------------------------------------------------------*/
3833 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3839 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3841 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3844 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3845 rifx->generated = 1;
3849 /*-----------------------------------------------------------------*/
3850 /* genChkZeroes :- greater or less than comparison */
3851 /* For each byte in a literal that is zero, inclusive or the */
3852 /* the corresponding byte in the operand with W */
3853 /* returns true if any of the bytes are zero */
3854 /*-----------------------------------------------------------------*/
3855 static int genChkZeroes(operand *op, int lit, int size)
3862 i = (lit >> (size*8)) & 0xff;
3866 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3868 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3877 /*-----------------------------------------------------------------*/
3878 /* genCmp :- greater or less than comparison */
3879 /*-----------------------------------------------------------------*/
3880 static void genCmp (operand *left,operand *right,
3881 operand *result, iCode *ifx, int sign)
3883 int size; //, offset = 0 ;
3884 unsigned long lit = 0L,i = 0;
3885 resolvedIfx rFalseIfx;
3886 // resolvedIfx rTrueIfx;
3888 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3891 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3892 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3896 resolveIfx(&rFalseIfx,ifx);
3897 truelbl = newiTempLabel(NULL);
3898 size = max(AOP_SIZE(left),AOP_SIZE(right));
3900 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3904 /* if literal is on the right then swap with left */
3905 if ((AOP_TYPE(right) == AOP_LIT)) {
3906 operand *tmp = right ;
3907 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3908 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3911 lit = (lit - 1) & mask;
3914 rFalseIfx.condition ^= 1;
3917 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3918 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3922 //if(IC_TRUE(ifx) == NULL)
3923 /* if left & right are bit variables */
3924 if (AOP_TYPE(left) == AOP_CRY &&
3925 AOP_TYPE(right) == AOP_CRY ) {
3926 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3927 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3929 /* subtract right from left if at the
3930 end the carry flag is set then we know that
3931 left is greater than right */
3935 symbol *lbl = newiTempLabel(NULL);
3938 if(AOP_TYPE(right) == AOP_LIT) {
3940 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3942 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3949 genSkipCond(&rFalseIfx,left,size-1,7);
3951 /* no need to compare to 0...*/
3952 /* NOTE: this is a de-generate compare that most certainly
3953 * creates some dead code. */
3954 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3956 if(ifx) ifx->generated = 1;
3963 //i = (lit >> (size*8)) & 0xff;
3964 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3966 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3968 i = ((0-lit) & 0xff);
3971 /* lit is 0x7f, all signed chars are less than
3972 * this except for 0x7f itself */
3973 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3974 genSkipz2(&rFalseIfx,0);
3976 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3977 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3978 genSkipc(&rFalseIfx);
3983 genSkipz2(&rFalseIfx,1);
3985 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3986 genSkipc(&rFalseIfx);
3990 if(ifx) ifx->generated = 1;
3994 /* chars are out of the way. now do ints and longs */
3997 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
4004 genSkipCond(&rFalseIfx,left,size,7);
4005 if(ifx) ifx->generated = 1;
4010 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4012 //rFalseIfx.condition ^= 1;
4013 //genSkipCond(&rFalseIfx,left,size,7);
4014 //rFalseIfx.condition ^= 1;
4016 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4017 if(rFalseIfx.condition)
4018 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4020 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4022 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
4023 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4024 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
4027 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
4029 if(rFalseIfx.condition) {
4031 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4037 genSkipc(&rFalseIfx);
4038 pic16_emitpLabel(truelbl->key);
4039 if(ifx) ifx->generated = 1;
4046 if( (lit & 0xff) == 0) {
4047 /* lower byte is zero */
4048 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4049 i = ((lit >> 8) & 0xff) ^0x80;
4050 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4051 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4052 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4053 genSkipc(&rFalseIfx);
4056 if(ifx) ifx->generated = 1;
4061 /* Special cases for signed longs */
4062 if( (lit & 0xffffff) == 0) {
4063 /* lower byte is zero */
4064 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4065 i = ((lit >> 8*3) & 0xff) ^0x80;
4066 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4067 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4068 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4069 genSkipc(&rFalseIfx);
4072 if(ifx) ifx->generated = 1;
4080 if(lit & (0x80 << (size*8))) {
4081 /* lit is negative */
4082 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4084 //genSkipCond(&rFalseIfx,left,size,7);
4086 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4088 if(rFalseIfx.condition)
4089 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4091 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4095 /* lit is positive */
4096 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4097 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4098 if(rFalseIfx.condition)
4099 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4101 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4106 This works, but is only good for ints.
4107 It also requires a "known zero" register.
4108 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4109 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4110 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4111 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4112 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4113 genSkipc(&rFalseIfx);
4115 pic16_emitpLabel(truelbl->key);
4116 if(ifx) ifx->generated = 1;
4120 /* There are no more special cases, so perform a general compare */
4122 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4123 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4127 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4129 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4131 //rFalseIfx.condition ^= 1;
4132 genSkipc(&rFalseIfx);
4134 pic16_emitpLabel(truelbl->key);
4136 if(ifx) ifx->generated = 1;
4143 /* sign is out of the way. So now do an unsigned compare */
4144 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4147 /* General case - compare to an unsigned literal on the right.*/
4149 i = (lit >> (size*8)) & 0xff;
4150 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4151 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4153 i = (lit >> (size*8)) & 0xff;
4156 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4158 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4160 /* this byte of the lit is zero,
4161 *if it's not the last then OR in the variable */
4163 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4168 pic16_emitpLabel(lbl->key);
4169 //if(emitFinalCheck)
4170 genSkipc(&rFalseIfx);
4172 pic16_emitpLabel(truelbl->key);
4174 if(ifx) ifx->generated = 1;
4181 if(AOP_TYPE(left) == AOP_LIT) {
4182 //symbol *lbl = newiTempLabel(NULL);
4184 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4187 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4190 if((lit == 0) && (sign == 0)){
4193 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4195 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4197 genSkipz2(&rFalseIfx,0);
4198 if(ifx) ifx->generated = 1;
4205 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4206 /* degenerate compare can never be true */
4207 if(rFalseIfx.condition == 0)
4208 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4210 if(ifx) ifx->generated = 1;
4215 /* signed comparisons to a literal byte */
4217 int lp1 = (lit+1) & 0xff;
4219 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4222 rFalseIfx.condition ^= 1;
4223 genSkipCond(&rFalseIfx,right,0,7);
4226 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4227 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4228 genSkipz2(&rFalseIfx,1);
4231 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4232 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4233 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4234 rFalseIfx.condition ^= 1;
4235 genSkipc(&rFalseIfx);
4239 /* unsigned comparisons to a literal byte */
4241 switch(lit & 0xff ) {
4243 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4244 genSkipz2(&rFalseIfx,0);
4247 rFalseIfx.condition ^= 1;
4248 genSkipCond(&rFalseIfx,right,0,7);
4252 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4253 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4254 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4255 rFalseIfx.condition ^= 1;
4256 if (AOP_TYPE(result) == AOP_CRY)
4257 genSkipc(&rFalseIfx);
4259 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4260 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4266 if(ifx) ifx->generated = 1;
4272 /* Size is greater than 1 */
4280 /* this means lit = 0xffffffff, or -1 */
4283 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4284 rFalseIfx.condition ^= 1;
4285 genSkipCond(&rFalseIfx,right,size,7);
4286 if(ifx) ifx->generated = 1;
4293 if(rFalseIfx.condition) {
4294 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4295 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4298 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4300 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4304 if(rFalseIfx.condition) {
4305 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4306 pic16_emitpLabel(truelbl->key);
4308 rFalseIfx.condition ^= 1;
4309 genSkipCond(&rFalseIfx,right,s,7);
4312 if(ifx) ifx->generated = 1;
4316 if((size == 1) && (0 == (lp1&0xff))) {
4317 /* lower byte of signed word is zero */
4318 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4319 i = ((lp1 >> 8) & 0xff) ^0x80;
4320 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4321 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4322 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4323 rFalseIfx.condition ^= 1;
4324 genSkipc(&rFalseIfx);
4327 if(ifx) ifx->generated = 1;
4331 if(lit & (0x80 << (size*8))) {
4332 /* Lit is less than zero */
4333 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4334 //rFalseIfx.condition ^= 1;
4335 //genSkipCond(&rFalseIfx,left,size,7);
4336 //rFalseIfx.condition ^= 1;
4337 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4338 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4340 if(rFalseIfx.condition)
4341 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4343 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4347 /* Lit is greater than or equal to zero */
4348 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4349 //rFalseIfx.condition ^= 1;
4350 //genSkipCond(&rFalseIfx,right,size,7);
4351 //rFalseIfx.condition ^= 1;
4353 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4354 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4356 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4357 if(rFalseIfx.condition)
4358 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4360 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4365 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4366 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4370 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4372 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4374 rFalseIfx.condition ^= 1;
4375 //rFalseIfx.condition = 1;
4376 genSkipc(&rFalseIfx);
4378 pic16_emitpLabel(truelbl->key);
4380 if(ifx) ifx->generated = 1;
4385 /* compare word or long to an unsigned literal on the right.*/
4390 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4393 break; /* handled above */
4396 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4398 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4399 genSkipz2(&rFalseIfx,0);
4403 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4405 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4408 if(rFalseIfx.condition)
4409 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4411 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4414 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4415 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4417 rFalseIfx.condition ^= 1;
4418 genSkipc(&rFalseIfx);
4421 pic16_emitpLabel(truelbl->key);
4423 if(ifx) ifx->generated = 1;
4429 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4430 i = (lit >> (size*8)) & 0xff;
4432 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4433 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4436 i = (lit >> (size*8)) & 0xff;
4439 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4441 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4443 /* this byte of the lit is zero,
4444 *if it's not the last then OR in the variable */
4446 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4451 pic16_emitpLabel(lbl->key);
4453 rFalseIfx.condition ^= 1;
4454 genSkipc(&rFalseIfx);
4458 pic16_emitpLabel(truelbl->key);
4459 if(ifx) ifx->generated = 1;
4463 /* Compare two variables */
4465 DEBUGpic16_emitcode(";sign","%d",sign);
4469 /* Sigh. thus sucks... */
4471 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4472 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4473 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4474 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4475 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4476 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4478 /* Signed char comparison */
4479 /* Special thanks to Nikolai Golovchenko for this snippet */
4480 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4481 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4482 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4483 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4484 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4485 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4487 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4488 genSkipc(&rFalseIfx);
4490 if(ifx) ifx->generated = 1;
4496 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4497 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4501 /* The rest of the bytes of a multi-byte compare */
4505 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4508 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4509 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4514 pic16_emitpLabel(lbl->key);
4516 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4517 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4518 (AOP_TYPE(result) == AOP_REG)) {
4519 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4520 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4522 genSkipc(&rFalseIfx);
4524 //genSkipc(&rFalseIfx);
4525 if(ifx) ifx->generated = 1;
4532 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4533 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4534 pic16_outBitC(result);
4536 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4537 /* if the result is used in the next
4538 ifx conditional branch then generate
4539 code a little differently */
4541 genIfxJump (ifx,"c");
4543 pic16_outBitC(result);
4544 /* leave the result in acc */
4549 /*-----------------------------------------------------------------*/
4550 /* genCmpGt :- greater than comparison */
4551 /*-----------------------------------------------------------------*/
4552 static void genCmpGt (iCode *ic, iCode *ifx)
4554 operand *left, *right, *result;
4555 sym_link *letype , *retype;
4558 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4560 right= IC_RIGHT(ic);
4561 result = IC_RESULT(ic);
4563 letype = getSpec(operandType(left));
4564 retype =getSpec(operandType(right));
4565 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4566 /* assign the amsops */
4567 pic16_aopOp (left,ic,FALSE);
4568 pic16_aopOp (right,ic,FALSE);
4569 pic16_aopOp (result,ic,TRUE);
4571 genCmp(right, left, result, ifx, sign);
4573 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4574 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4575 pic16_freeAsmop(result,NULL,ic,TRUE);
4578 /*-----------------------------------------------------------------*/
4579 /* genCmpLt - less than comparisons */
4580 /*-----------------------------------------------------------------*/
4581 static void genCmpLt (iCode *ic, iCode *ifx)
4583 operand *left, *right, *result;
4584 sym_link *letype , *retype;
4587 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4589 right= IC_RIGHT(ic);
4590 result = IC_RESULT(ic);
4592 letype = getSpec(operandType(left));
4593 retype =getSpec(operandType(right));
4594 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4596 /* assign the amsops */
4597 pic16_aopOp (left,ic,FALSE);
4598 pic16_aopOp (right,ic,FALSE);
4599 pic16_aopOp (result,ic,TRUE);
4601 genCmp(left, right, result, ifx, sign);
4603 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4604 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4605 pic16_freeAsmop(result,NULL,ic,TRUE);
4608 /*-----------------------------------------------------------------*/
4609 /* genc16bit2lit - compare a 16 bit value to a literal */
4610 /*-----------------------------------------------------------------*/
4611 static void genc16bit2lit(operand *op, int lit, int offset)
4615 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4616 if( (lit&0xff) == 0)
4621 switch( BYTEofLONG(lit,i)) {
4623 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4626 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4629 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4632 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4633 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4638 switch( BYTEofLONG(lit,i)) {
4640 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4644 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4648 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4651 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4653 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4659 /*-----------------------------------------------------------------*/
4660 /* gencjneshort - compare and jump if not equal */
4661 /*-----------------------------------------------------------------*/
4662 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4664 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4666 int res_offset = 0; /* the result may be a different size then left or right */
4667 int res_size = AOP_SIZE(result);
4671 unsigned long lit = 0L;
4672 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4673 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4675 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4676 resolveIfx(&rIfx,ifx);
4677 lbl = newiTempLabel(NULL);
4680 /* if the left side is a literal or
4681 if the right is in a pointer register and left
4683 if ((AOP_TYPE(left) == AOP_LIT) ||
4684 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4689 if(AOP_TYPE(right) == AOP_LIT)
4690 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4692 /* if the right side is a literal then anything goes */
4693 if (AOP_TYPE(right) == AOP_LIT &&
4694 AOP_TYPE(left) != AOP_DIR ) {
4697 genc16bit2lit(left, lit, 0);
4699 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4704 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4705 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4707 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4711 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4713 if(res_offset < res_size-1)
4721 /* if the right side is in a register or in direct space or
4722 if the left is a pointer register & right is not */
4723 else if (AOP_TYPE(right) == AOP_REG ||
4724 AOP_TYPE(right) == AOP_DIR ||
4725 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4726 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4727 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4728 int lbl_key = lbl->key;
4731 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4732 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4734 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4735 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4736 __FUNCTION__,__LINE__);
4740 /* switch(size) { */
4742 /* genc16bit2lit(left, lit, 0); */
4744 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4749 if((AOP_TYPE(left) == AOP_DIR) &&
4750 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4752 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4753 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4755 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4757 switch (lit & 0xff) {
4759 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4762 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4763 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4764 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4768 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4769 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4770 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4771 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4775 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4776 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4781 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4784 if(AOP_TYPE(result) == AOP_CRY) {
4785 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4790 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4792 /* fix me. probably need to check result size too */
4793 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4798 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4799 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4806 if(res_offset < res_size-1)
4811 } else if(AOP_TYPE(right) == AOP_REG &&
4812 AOP_TYPE(left) != AOP_DIR){
4815 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4816 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4817 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4822 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4824 if(res_offset < res_size-1)
4829 /* right is a pointer reg need both a & b */
4831 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4833 pic16_emitcode("mov","b,%s",l);
4834 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4835 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4840 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4842 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4844 pic16_emitpLabel(lbl->key);
4846 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4853 /*-----------------------------------------------------------------*/
4854 /* gencjne - compare and jump if not equal */
4855 /*-----------------------------------------------------------------*/
4856 static void gencjne(operand *left, operand *right, iCode *ifx)
4858 symbol *tlbl = newiTempLabel(NULL);
4860 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4861 gencjneshort(left, right, lbl);
4863 pic16_emitcode("mov","a,%s",one);
4864 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4865 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4866 pic16_emitcode("clr","a");
4867 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4869 pic16_emitpLabel(lbl->key);
4870 pic16_emitpLabel(tlbl->key);
4875 /*-----------------------------------------------------------------*/
4876 /* genCmpEq - generates code for equal to */
4877 /*-----------------------------------------------------------------*/
4878 static void genCmpEq (iCode *ic, iCode *ifx)
4880 operand *left, *right, *result;
4881 unsigned long lit = 0L;
4884 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4887 DEBUGpic16_emitcode ("; ifx is non-null","");
4889 DEBUGpic16_emitcode ("; ifx is null","");
4891 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4892 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4893 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4895 size = max(AOP_SIZE(left),AOP_SIZE(right));
4897 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4899 /* if literal, literal on the right or
4900 if the right is in a pointer register and left
4902 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4903 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4904 operand *tmp = right ;
4910 if(ifx && !AOP_SIZE(result)){
4912 /* if they are both bit variables */
4913 if (AOP_TYPE(left) == AOP_CRY &&
4914 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4915 if(AOP_TYPE(right) == AOP_LIT){
4916 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4918 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4919 pic16_emitcode("cpl","c");
4920 } else if(lit == 1L) {
4921 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4923 pic16_emitcode("clr","c");
4925 /* AOP_TYPE(right) == AOP_CRY */
4927 symbol *lbl = newiTempLabel(NULL);
4928 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4929 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4930 pic16_emitcode("cpl","c");
4931 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4933 /* if true label then we jump if condition
4935 tlbl = newiTempLabel(NULL);
4936 if ( IC_TRUE(ifx) ) {
4937 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4938 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4940 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4941 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4943 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4946 /* left and right are both bit variables, result is carry */
4949 resolveIfx(&rIfx,ifx);
4951 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4952 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4953 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4954 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4959 /* They're not both bit variables. Is the right a literal? */
4960 if(AOP_TYPE(right) == AOP_LIT) {
4961 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4966 switch(lit & 0xff) {
4968 if ( IC_TRUE(ifx) ) {
4969 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4971 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4973 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4974 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4978 if ( IC_TRUE(ifx) ) {
4979 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4981 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4983 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4984 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4988 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4990 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4995 /* end of size == 1 */
4999 genc16bit2lit(left,lit,offset);
5002 /* end of size == 2 */
5007 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5008 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
5009 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5010 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5014 /* search for patterns that can be optimized */
5016 genc16bit2lit(left,lit,0);
5019 genSkipz(ifx,IC_TRUE(ifx) == NULL);
5021 genc16bit2lit(left,lit,2);
5023 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
5024 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
5037 } else if(AOP_TYPE(right) == AOP_CRY ) {
5038 /* we know the left is not a bit, but that the right is */
5039 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5040 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
5041 pic16_popGet(AOP(right),offset));
5042 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
5044 /* if the two are equal, then W will be 0 and the Z bit is set
5045 * we could test Z now, or go ahead and check the high order bytes if
5046 * the variable we're comparing is larger than a byte. */
5049 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
5051 if ( IC_TRUE(ifx) ) {
5053 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5054 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5057 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5058 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5062 /* They're both variables that are larger than bits */
5065 tlbl = newiTempLabel(NULL);
5068 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5069 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
5071 if ( IC_TRUE(ifx) ) {
5075 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ");
5077 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
5078 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
5082 DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPNZ");
5085 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
5086 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
5091 DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ");
5093 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
5094 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5098 if(s>1 && IC_TRUE(ifx)) {
5099 pic16_emitpLabel(tlbl->key);
5100 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5104 /* mark the icode as generated */
5109 /* if they are both bit variables */
5110 if (AOP_TYPE(left) == AOP_CRY &&
5111 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5112 if(AOP_TYPE(right) == AOP_LIT){
5113 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5115 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5116 pic16_emitcode("cpl","c");
5117 } else if(lit == 1L) {
5118 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5120 pic16_emitcode("clr","c");
5122 /* AOP_TYPE(right) == AOP_CRY */
5124 symbol *lbl = newiTempLabel(NULL);
5125 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5126 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5127 pic16_emitcode("cpl","c");
5128 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5131 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5132 pic16_outBitC(result);
5136 genIfxJump (ifx,"c");
5139 /* if the result is used in an arithmetic operation
5140 then put the result in place */
5141 pic16_outBitC(result);
5144 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5145 gencjne(left,right,result,ifx);
5148 gencjne(left,right,newiTempLabel(NULL));
5150 if(IC_TRUE(ifx)->key)
5151 gencjne(left,right,IC_TRUE(ifx)->key);
5153 gencjne(left,right,IC_FALSE(ifx)->key);
5157 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5158 pic16_aopPut(AOP(result),"a",0);
5163 genIfxJump (ifx,"a");
5167 /* if the result is used in an arithmetic operation
5168 then put the result in place */
5170 if (AOP_TYPE(result) != AOP_CRY)
5171 pic16_outAcc(result);
5173 /* leave the result in acc */
5177 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5178 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5179 pic16_freeAsmop(result,NULL,ic,TRUE);
5182 /*-----------------------------------------------------------------*/
5183 /* ifxForOp - returns the icode containing the ifx for operand */
5184 /*-----------------------------------------------------------------*/
5185 static iCode *ifxForOp ( operand *op, iCode *ic )
5187 /* if true symbol then needs to be assigned */
5188 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5189 if (IS_TRUE_SYMOP(op))
5192 /* if this has register type condition and
5193 the next instruction is ifx with the same operand
5194 and live to of the operand is upto the ifx only then */
5196 ic->next->op == IFX &&
5197 IC_COND(ic->next)->key == op->key &&
5198 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5202 ic->next->op == IFX &&
5203 IC_COND(ic->next)->key == op->key) {
5204 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5208 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5210 ic->next->op == IFX)
5211 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5214 ic->next->op == IFX &&
5215 IC_COND(ic->next)->key == op->key) {
5216 DEBUGpic16_emitcode ("; "," key is okay");
5217 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5218 OP_SYMBOL(op)->liveTo,
5225 /*-----------------------------------------------------------------*/
5226 /* genAndOp - for && operation */
5227 /*-----------------------------------------------------------------*/
5228 static void genAndOp (iCode *ic)
5230 operand *left,*right, *result;
5233 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5234 /* note here that && operations that are in an
5235 if statement are taken away by backPatchLabels
5236 only those used in arthmetic operations remain */
5237 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5238 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5239 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5241 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5243 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5244 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5245 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5247 /* if both are bit variables */
5248 /* if (AOP_TYPE(left) == AOP_CRY && */
5249 /* AOP_TYPE(right) == AOP_CRY ) { */
5250 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5251 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5252 /* pic16_outBitC(result); */
5254 /* tlbl = newiTempLabel(NULL); */
5255 /* pic16_toBoolean(left); */
5256 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5257 /* pic16_toBoolean(right); */
5258 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5259 /* pic16_outBitAcc(result); */
5262 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5263 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5264 pic16_freeAsmop(result,NULL,ic,TRUE);
5268 /*-----------------------------------------------------------------*/
5269 /* genOrOp - for || operation */
5270 /*-----------------------------------------------------------------*/
5273 modified this code, but it doesn't appear to ever get called
5276 static void genOrOp (iCode *ic)
5278 operand *left,*right, *result;
5281 /* note here that || operations that are in an
5282 if statement are taken away by backPatchLabels
5283 only those used in arthmetic operations remain */
5284 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5285 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5286 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5287 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5289 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5291 /* if both are bit variables */
5292 if (AOP_TYPE(left) == AOP_CRY &&
5293 AOP_TYPE(right) == AOP_CRY ) {
5294 pic16_emitcode("clrc","");
5295 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5296 AOP(left)->aopu.aop_dir,
5297 AOP(left)->aopu.aop_dir);
5298 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5299 AOP(right)->aopu.aop_dir,
5300 AOP(right)->aopu.aop_dir);
5301 pic16_emitcode("setc","");
5304 tlbl = newiTempLabel(NULL);
5305 pic16_toBoolean(left);
5307 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5308 pic16_toBoolean(right);
5309 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5311 pic16_outBitAcc(result);
5314 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5315 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5316 pic16_freeAsmop(result,NULL,ic,TRUE);
5319 /*-----------------------------------------------------------------*/
5320 /* isLiteralBit - test if lit == 2^n */
5321 /*-----------------------------------------------------------------*/
5322 static int isLiteralBit(unsigned long lit)
5324 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5325 0x100L,0x200L,0x400L,0x800L,
5326 0x1000L,0x2000L,0x4000L,0x8000L,
5327 0x10000L,0x20000L,0x40000L,0x80000L,
5328 0x100000L,0x200000L,0x400000L,0x800000L,
5329 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5330 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5333 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5334 for(idx = 0; idx < 32; idx++)
5340 /*-----------------------------------------------------------------*/
5341 /* continueIfTrue - */
5342 /*-----------------------------------------------------------------*/
5343 static void continueIfTrue (iCode *ic)
5345 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5347 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5351 /*-----------------------------------------------------------------*/
5353 /*-----------------------------------------------------------------*/
5354 static void jumpIfTrue (iCode *ic)
5356 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5358 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5362 /*-----------------------------------------------------------------*/
5363 /* jmpTrueOrFalse - */
5364 /*-----------------------------------------------------------------*/
5365 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5367 // ugly but optimized by peephole
5368 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5370 symbol *nlbl = newiTempLabel(NULL);
5371 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5372 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5373 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5374 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5377 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5378 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5383 /*-----------------------------------------------------------------*/
5384 /* genAnd - code for and */
5385 /*-----------------------------------------------------------------*/
5386 static void genAnd (iCode *ic, iCode *ifx)
5388 operand *left, *right, *result;
5390 unsigned long lit = 0L;
5395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5396 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5397 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5398 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5400 resolveIfx(&rIfx,ifx);
5402 /* if left is a literal & right is not then exchange them */
5403 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5404 AOP_NEEDSACC(left)) {
5405 operand *tmp = right ;
5410 /* if result = right then exchange them */
5411 if(pic16_sameRegs(AOP(result),AOP(right))){
5412 operand *tmp = right ;
5417 /* if right is bit then exchange them */
5418 if (AOP_TYPE(right) == AOP_CRY &&
5419 AOP_TYPE(left) != AOP_CRY){
5420 operand *tmp = right ;
5424 if(AOP_TYPE(right) == AOP_LIT)
5425 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5427 size = AOP_SIZE(result);
5429 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5432 // result = bit & yy;
5433 if (AOP_TYPE(left) == AOP_CRY){
5434 // c = bit & literal;
5435 if(AOP_TYPE(right) == AOP_LIT){
5437 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5440 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5443 if(size && (AOP_TYPE(result) == AOP_CRY)){
5444 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5447 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5451 pic16_emitcode("clr","c");
5454 if (AOP_TYPE(right) == AOP_CRY){
5456 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5457 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5460 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5462 pic16_emitcode("rrc","a");
5463 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5469 pic16_outBitC(result);
5471 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5472 genIfxJump(ifx, "c");
5476 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5477 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5478 if((AOP_TYPE(right) == AOP_LIT) &&
5479 (AOP_TYPE(result) == AOP_CRY) &&
5480 (AOP_TYPE(left) != AOP_CRY)){
5481 int posbit = isLiteralBit(lit);
5485 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5488 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5494 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5495 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5497 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5498 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5501 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5502 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5503 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5510 symbol *tlbl = newiTempLabel(NULL);
5511 int sizel = AOP_SIZE(left);
5513 pic16_emitcode("setb","c");
5515 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5516 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5518 if((posbit = isLiteralBit(bytelit)) != 0)
5519 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5521 if(bytelit != 0x0FFL)
5522 pic16_emitcode("anl","a,%s",
5523 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5524 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5529 // bit = left & literal
5531 pic16_emitcode("clr","c");
5532 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5534 // if(left & literal)
5537 jmpTrueOrFalse(ifx, tlbl);
5541 pic16_outBitC(result);
5545 /* if left is same as result */
5546 if(pic16_sameRegs(AOP(result),AOP(left))){
5548 for(;size--; offset++,lit>>=8) {
5549 if(AOP_TYPE(right) == AOP_LIT){
5550 switch(lit & 0xff) {
5552 /* and'ing with 0 has clears the result */
5553 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5554 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5557 /* and'ing with 0xff is a nop when the result and left are the same */
5562 int p = my_powof2( (~lit) & 0xff );
5564 /* only one bit is set in the literal, so use a bcf instruction */
5565 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5566 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5569 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5570 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5571 if(know_W != (lit&0xff))
5572 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5574 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5579 if (AOP_TYPE(left) == AOP_ACC) {
5580 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5582 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5583 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5590 // left & result in different registers
5591 if(AOP_TYPE(result) == AOP_CRY){
5593 // if(size), result in bit
5594 // if(!size && ifx), conditional oper: if(left & right)
5595 symbol *tlbl = newiTempLabel(NULL);
5596 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5598 pic16_emitcode("setb","c");
5600 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5601 pic16_emitcode("anl","a,%s",
5602 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5603 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5608 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5609 pic16_outBitC(result);
5611 jmpTrueOrFalse(ifx, tlbl);
5613 for(;(size--);offset++) {
5615 // result = left & right
5616 if(AOP_TYPE(right) == AOP_LIT){
5617 int t = (lit >> (offset*8)) & 0x0FFL;
5620 pic16_emitcode("clrf","%s",
5621 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5622 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5625 pic16_emitcode("movf","%s,w",
5626 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5627 pic16_emitcode("movwf","%s",
5628 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5629 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5630 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5633 pic16_emitcode("movlw","0x%x",t);
5634 pic16_emitcode("andwf","%s,w",
5635 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5636 pic16_emitcode("movwf","%s",
5637 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5639 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5640 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5641 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5646 if (AOP_TYPE(left) == AOP_ACC) {
5647 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5648 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5650 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5651 pic16_emitcode("andwf","%s,w",
5652 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5653 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5654 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5656 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5657 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5663 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5664 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5665 pic16_freeAsmop(result,NULL,ic,TRUE);
5668 /*-----------------------------------------------------------------*/
5669 /* genOr - code for or */
5670 /*-----------------------------------------------------------------*/
5671 static void genOr (iCode *ic, iCode *ifx)
5673 operand *left, *right, *result;
5675 unsigned long lit = 0L;
5677 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5679 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5680 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5681 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5683 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5685 /* if left is a literal & right is not then exchange them */
5686 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5687 AOP_NEEDSACC(left)) {
5688 operand *tmp = right ;
5693 /* if result = right then exchange them */
5694 if(pic16_sameRegs(AOP(result),AOP(right))){
5695 operand *tmp = right ;
5700 /* if right is bit then exchange them */
5701 if (AOP_TYPE(right) == AOP_CRY &&
5702 AOP_TYPE(left) != AOP_CRY){
5703 operand *tmp = right ;
5708 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5710 if(AOP_TYPE(right) == AOP_LIT)
5711 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5713 size = AOP_SIZE(result);
5717 if (AOP_TYPE(left) == AOP_CRY){
5718 if(AOP_TYPE(right) == AOP_LIT){
5719 // c = bit & literal;
5721 // lit != 0 => result = 1
5722 if(AOP_TYPE(result) == AOP_CRY){
5724 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5725 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5726 // AOP(result)->aopu.aop_dir,
5727 // AOP(result)->aopu.aop_dir);
5729 continueIfTrue(ifx);
5733 // lit == 0 => result = left
5734 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5736 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5739 if (AOP_TYPE(right) == AOP_CRY){
5740 if(pic16_sameRegs(AOP(result),AOP(left))){
5742 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5743 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5744 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5746 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5747 AOP(result)->aopu.aop_dir,
5748 AOP(result)->aopu.aop_dir);
5749 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5750 AOP(right)->aopu.aop_dir,
5751 AOP(right)->aopu.aop_dir);
5752 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5753 AOP(result)->aopu.aop_dir,
5754 AOP(result)->aopu.aop_dir);
5756 if( AOP_TYPE(result) == AOP_ACC) {
5757 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5758 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5759 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5760 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5764 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5765 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5766 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5767 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5769 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5770 AOP(result)->aopu.aop_dir,
5771 AOP(result)->aopu.aop_dir);
5772 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5773 AOP(right)->aopu.aop_dir,
5774 AOP(right)->aopu.aop_dir);
5775 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5776 AOP(left)->aopu.aop_dir,
5777 AOP(left)->aopu.aop_dir);
5778 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5779 AOP(result)->aopu.aop_dir,
5780 AOP(result)->aopu.aop_dir);
5785 symbol *tlbl = newiTempLabel(NULL);
5786 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5789 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5790 if( AOP_TYPE(right) == AOP_ACC) {
5791 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5793 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5794 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5799 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5800 pic16_emitcode(";XXX setb","c");
5801 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5802 AOP(left)->aopu.aop_dir,tlbl->key+100);
5803 pic16_toBoolean(right);
5804 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5805 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5806 jmpTrueOrFalse(ifx, tlbl);
5810 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5817 pic16_outBitC(result);
5819 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5820 genIfxJump(ifx, "c");
5824 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5825 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5826 if((AOP_TYPE(right) == AOP_LIT) &&
5827 (AOP_TYPE(result) == AOP_CRY) &&
5828 (AOP_TYPE(left) != AOP_CRY)){
5830 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5833 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5835 continueIfTrue(ifx);
5838 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5839 // lit = 0, result = boolean(left)
5841 pic16_emitcode(";XXX setb","c");
5842 pic16_toBoolean(right);
5844 symbol *tlbl = newiTempLabel(NULL);
5845 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5847 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5849 genIfxJump (ifx,"a");
5853 pic16_outBitC(result);
5857 /* if left is same as result */
5858 if(pic16_sameRegs(AOP(result),AOP(left))){
5860 for(;size--; offset++,lit>>=8) {
5861 if(AOP_TYPE(right) == AOP_LIT){
5862 if((lit & 0xff) == 0)
5863 /* or'ing with 0 has no effect */
5866 int p = my_powof2(lit & 0xff);
5868 /* only one bit is set in the literal, so use a bsf instruction */
5869 pic16_emitpcode(POC_BSF,
5870 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5872 if(know_W != (lit & 0xff))
5873 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5874 know_W = lit & 0xff;
5875 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5880 if (AOP_TYPE(left) == AOP_ACC) {
5881 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5882 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5884 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5885 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5887 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5888 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5894 // left & result in different registers
5895 if(AOP_TYPE(result) == AOP_CRY){
5897 // if(size), result in bit
5898 // if(!size && ifx), conditional oper: if(left | right)
5899 symbol *tlbl = newiTempLabel(NULL);
5900 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5901 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5905 pic16_emitcode(";XXX setb","c");
5907 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5908 pic16_emitcode(";XXX orl","a,%s",
5909 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5910 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5915 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5916 pic16_outBitC(result);
5918 jmpTrueOrFalse(ifx, tlbl);
5919 } else for(;(size--);offset++){
5921 // result = left & right
5922 if(AOP_TYPE(right) == AOP_LIT){
5923 int t = (lit >> (offset*8)) & 0x0FFL;
5926 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5927 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5929 pic16_emitcode("movf","%s,w",
5930 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5931 pic16_emitcode("movwf","%s",
5932 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5935 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5936 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5937 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5939 pic16_emitcode("movlw","0x%x",t);
5940 pic16_emitcode("iorwf","%s,w",
5941 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5942 pic16_emitcode("movwf","%s",
5943 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5949 // faster than result <- left, anl result,right
5950 // and better if result is SFR
5951 if (AOP_TYPE(left) == AOP_ACC) {
5952 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5953 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5955 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5956 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5958 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5959 pic16_emitcode("iorwf","%s,w",
5960 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5962 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5963 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5968 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5969 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5970 pic16_freeAsmop(result,NULL,ic,TRUE);
5973 /*-----------------------------------------------------------------*/
5974 /* genXor - code for xclusive or */
5975 /*-----------------------------------------------------------------*/
5976 static void genXor (iCode *ic, iCode *ifx)
5978 operand *left, *right, *result;
5980 unsigned long lit = 0L;
5982 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5984 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5985 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5986 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5988 /* if left is a literal & right is not ||
5989 if left needs acc & right does not */
5990 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5991 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5992 operand *tmp = right ;
5997 /* if result = right then exchange them */
5998 if(pic16_sameRegs(AOP(result),AOP(right))){
5999 operand *tmp = right ;
6004 /* if right is bit then exchange them */
6005 if (AOP_TYPE(right) == AOP_CRY &&
6006 AOP_TYPE(left) != AOP_CRY){
6007 operand *tmp = right ;
6011 if(AOP_TYPE(right) == AOP_LIT)
6012 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
6014 size = AOP_SIZE(result);
6018 if (AOP_TYPE(left) == AOP_CRY){
6019 if(AOP_TYPE(right) == AOP_LIT){
6020 // c = bit & literal;
6022 // lit>>1 != 0 => result = 1
6023 if(AOP_TYPE(result) == AOP_CRY){
6025 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
6026 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
6028 continueIfTrue(ifx);
6031 pic16_emitcode("setb","c");
6035 // lit == 0, result = left
6036 if(size && pic16_sameRegs(AOP(result),AOP(left)))
6038 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6040 // lit == 1, result = not(left)
6041 if(size && pic16_sameRegs(AOP(result),AOP(left))){
6042 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
6043 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
6044 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
6047 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
6048 pic16_emitcode("cpl","c");
6055 symbol *tlbl = newiTempLabel(NULL);
6056 if (AOP_TYPE(right) == AOP_CRY){
6058 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
6061 int sizer = AOP_SIZE(right);
6063 // if val>>1 != 0, result = 1
6064 pic16_emitcode("setb","c");
6066 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
6068 // test the msb of the lsb
6069 pic16_emitcode("anl","a,#0xfe");
6070 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6074 pic16_emitcode("rrc","a");
6076 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
6077 pic16_emitcode("cpl","c");
6078 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
6083 pic16_outBitC(result);
6085 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
6086 genIfxJump(ifx, "c");
6090 if(pic16_sameRegs(AOP(result),AOP(left))){
6091 /* if left is same as result */
6092 for(;size--; offset++) {
6093 if(AOP_TYPE(right) == AOP_LIT){
6094 int t = (lit >> (offset*8)) & 0x0FFL;
6098 if (IS_AOP_PREG(left)) {
6099 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6100 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6101 pic16_aopPut(AOP(result),"a",offset);
6103 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6104 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6105 pic16_emitcode("xrl","%s,%s",
6106 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6107 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6110 if (AOP_TYPE(left) == AOP_ACC)
6111 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6113 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6114 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6116 if (IS_AOP_PREG(left)) {
6117 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6118 pic16_aopPut(AOP(result),"a",offset);
6120 pic16_emitcode("xrl","%s,a",
6121 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6127 // left & result in different registers
6128 if(AOP_TYPE(result) == AOP_CRY){
6130 // if(size), result in bit
6131 // if(!size && ifx), conditional oper: if(left ^ right)
6132 symbol *tlbl = newiTempLabel(NULL);
6133 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6135 pic16_emitcode("setb","c");
6137 if((AOP_TYPE(right) == AOP_LIT) &&
6138 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6139 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6141 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6142 pic16_emitcode("xrl","a,%s",
6143 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6145 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6150 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6151 pic16_outBitC(result);
6153 jmpTrueOrFalse(ifx, tlbl);
6154 } else for(;(size--);offset++){
6156 // result = left & right
6157 if(AOP_TYPE(right) == AOP_LIT){
6158 int t = (lit >> (offset*8)) & 0x0FFL;
6161 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6162 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6163 pic16_emitcode("movf","%s,w",
6164 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6165 pic16_emitcode("movwf","%s",
6166 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6169 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6170 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6171 pic16_emitcode("comf","%s,w",
6172 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6173 pic16_emitcode("movwf","%s",
6174 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6177 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6178 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6179 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6180 pic16_emitcode("movlw","0x%x",t);
6181 pic16_emitcode("xorwf","%s,w",
6182 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6183 pic16_emitcode("movwf","%s",
6184 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6190 // faster than result <- left, anl result,right
6191 // and better if result is SFR
6192 if (AOP_TYPE(left) == AOP_ACC) {
6193 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6194 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6196 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6197 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6198 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6199 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6201 if ( AOP_TYPE(result) != AOP_ACC){
6202 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6203 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6209 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6210 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6211 pic16_freeAsmop(result,NULL,ic,TRUE);
6214 /*-----------------------------------------------------------------*/
6215 /* genInline - write the inline code out */
6216 /*-----------------------------------------------------------------*/
6217 static void genInline (iCode *ic)
6219 char *buffer, *bp, *bp1;
6221 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6223 _G.inLine += (!options.asmpeep);
6225 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6226 strcpy(buffer,IC_INLINE(ic));
6228 /* emit each line as a code */
6234 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6241 pic16_emitcode(bp1,"");
6247 if ((bp1 != bp) && *bp1)
6248 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6252 _G.inLine -= (!options.asmpeep);
6255 /*-----------------------------------------------------------------*/
6256 /* genRRC - rotate right with carry */
6257 /*-----------------------------------------------------------------*/
6258 static void genRRC (iCode *ic)
6260 operand *left , *result ;
6261 int size, offset = 0, same;
6263 /* rotate right with carry */
6265 result=IC_RESULT(ic);
6266 pic16_aopOp (left,ic,FALSE);
6267 pic16_aopOp (result,ic,FALSE);
6269 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6271 same = pic16_sameRegs(AOP(result),AOP(left));
6273 size = AOP_SIZE(result);
6275 /* get the lsb and put it into the carry */
6276 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6283 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6285 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6286 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6292 pic16_freeAsmop(left,NULL,ic,TRUE);
6293 pic16_freeAsmop(result,NULL,ic,TRUE);
6296 /*-----------------------------------------------------------------*/
6297 /* genRLC - generate code for rotate left with carry */
6298 /*-----------------------------------------------------------------*/
6299 static void genRLC (iCode *ic)
6301 operand *left , *result ;
6302 int size, offset = 0;
6305 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6306 /* rotate right with carry */
6308 result=IC_RESULT(ic);
6309 pic16_aopOp (left,ic,FALSE);
6310 pic16_aopOp (result,ic,FALSE);
6312 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6314 same = pic16_sameRegs(AOP(result),AOP(left));
6316 /* move it to the result */
6317 size = AOP_SIZE(result);
6319 /* get the msb and put it into the carry */
6320 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6327 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6329 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6330 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6337 pic16_freeAsmop(left,NULL,ic,TRUE);
6338 pic16_freeAsmop(result,NULL,ic,TRUE);
6341 /*-----------------------------------------------------------------*/
6342 /* genGetHbit - generates code get highest order bit */
6343 /*-----------------------------------------------------------------*/
6344 static void genGetHbit (iCode *ic)
6346 operand *left, *result;
6348 result=IC_RESULT(ic);
6349 pic16_aopOp (left,ic,FALSE);
6350 pic16_aopOp (result,ic,FALSE);
6352 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6353 /* get the highest order byte into a */
6354 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6355 if(AOP_TYPE(result) == AOP_CRY){
6356 pic16_emitcode("rlc","a");
6357 pic16_outBitC(result);
6360 pic16_emitcode("rl","a");
6361 pic16_emitcode("anl","a,#0x01");
6362 pic16_outAcc(result);
6366 pic16_freeAsmop(left,NULL,ic,TRUE);
6367 pic16_freeAsmop(result,NULL,ic,TRUE);
6370 /*-----------------------------------------------------------------*/
6371 /* AccRol - rotate left accumulator by known count */
6372 /*-----------------------------------------------------------------*/
6373 static void AccRol (int shCount)
6375 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6376 shCount &= 0x0007; // shCount : 0..7
6381 pic16_emitcode("rl","a");
6384 pic16_emitcode("rl","a");
6385 pic16_emitcode("rl","a");
6388 pic16_emitcode("swap","a");
6389 pic16_emitcode("rr","a");
6392 pic16_emitcode("swap","a");
6395 pic16_emitcode("swap","a");
6396 pic16_emitcode("rl","a");
6399 pic16_emitcode("rr","a");
6400 pic16_emitcode("rr","a");
6403 pic16_emitcode("rr","a");
6408 /*-----------------------------------------------------------------*/
6409 /* AccLsh - left shift accumulator by known count */
6410 /*-----------------------------------------------------------------*/
6411 static void AccLsh (int shCount)
6413 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6416 pic16_emitcode("add","a,acc");
6419 pic16_emitcode("add","a,acc");
6420 pic16_emitcode("add","a,acc");
6422 /* rotate left accumulator */
6424 /* and kill the lower order bits */
6425 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6430 /*-----------------------------------------------------------------*/
6431 /* AccRsh - right shift accumulator by known count */
6432 /*-----------------------------------------------------------------*/
6433 static void AccRsh (int shCount)
6435 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6439 pic16_emitcode("rrc","a");
6441 /* rotate right accumulator */
6442 AccRol(8 - shCount);
6443 /* and kill the higher order bits */
6444 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6450 /*-----------------------------------------------------------------*/
6451 /* AccSRsh - signed right shift accumulator by known count */
6452 /*-----------------------------------------------------------------*/
6453 static void AccSRsh (int shCount)
6456 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6459 pic16_emitcode("mov","c,acc.7");
6460 pic16_emitcode("rrc","a");
6461 } else if(shCount == 2){
6462 pic16_emitcode("mov","c,acc.7");
6463 pic16_emitcode("rrc","a");
6464 pic16_emitcode("mov","c,acc.7");
6465 pic16_emitcode("rrc","a");
6467 tlbl = newiTempLabel(NULL);
6468 /* rotate right accumulator */
6469 AccRol(8 - shCount);
6470 /* and kill the higher order bits */
6471 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6472 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6473 pic16_emitcode("orl","a,#0x%02x",
6474 (unsigned char)~SRMask[shCount]);
6475 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6480 /*-----------------------------------------------------------------*/
6481 /* shiftR1Left2Result - shift right one byte from left to result */
6482 /*-----------------------------------------------------------------*/
6483 static void shiftR1Left2ResultSigned (operand *left, int offl,
6484 operand *result, int offr,
6489 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6491 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6495 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6497 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6499 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6500 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6506 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6508 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6510 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6511 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6513 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6514 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6520 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6522 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6523 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6526 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6527 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6528 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6530 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6531 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6533 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6537 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6538 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6539 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6540 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6541 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6545 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6547 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6548 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6550 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6551 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6552 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6553 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6554 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6559 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6560 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6561 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6562 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6563 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6564 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6566 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6567 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6568 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6569 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6570 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6576 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6577 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6578 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6579 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6581 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6582 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6583 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6591 /*-----------------------------------------------------------------*/
6592 /* shiftR1Left2Result - shift right one byte from left to result */
6593 /*-----------------------------------------------------------------*/
6594 static void shiftR1Left2Result (operand *left, int offl,
6595 operand *result, int offr,
6596 int shCount, int sign)
6600 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6602 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6604 /* Copy the msb into the carry if signed. */
6606 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6616 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6618 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6619 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6625 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6627 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6628 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6631 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6636 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6638 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6639 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6642 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6643 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6644 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6645 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6649 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6650 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6651 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6655 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6656 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6657 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6659 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6664 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6665 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6666 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6667 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6668 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6673 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6674 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6675 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6684 /*-----------------------------------------------------------------*/
6685 /* shiftL1Left2Result - shift left one byte from left to result */
6686 /*-----------------------------------------------------------------*/
6687 static void shiftL1Left2Result (operand *left, int offl,
6688 operand *result, int offr, int shCount)
6693 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6695 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6696 DEBUGpic16_emitcode ("; ***","same = %d",same);
6697 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6699 /* shift left accumulator */
6700 //AccLsh(shCount); // don't comment out just yet...
6701 // pic16_aopPut(AOP(result),"a",offr);
6705 /* Shift left 1 bit position */
6706 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6708 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6710 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6711 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6715 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6716 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6717 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6718 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6721 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6722 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6723 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6724 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6725 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6728 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6729 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6730 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6733 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6734 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6735 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6736 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6739 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6740 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6741 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6742 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6743 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6746 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6747 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6748 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6752 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6757 /*-----------------------------------------------------------------*/
6758 /* movLeft2Result - move byte from left to result */
6759 /*-----------------------------------------------------------------*/
6760 static void movLeft2Result (operand *left, int offl,
6761 operand *result, int offr)
6764 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6765 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6766 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6768 if (*l == '@' && (IS_AOP_PREG(result))) {
6769 pic16_emitcode("mov","a,%s",l);
6770 pic16_aopPut(AOP(result),"a",offr);
6772 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6773 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6778 /*-----------------------------------------------------------------*/
6779 /* shiftL2Left2Result - shift left two bytes from left to result */
6780 /*-----------------------------------------------------------------*/
6781 static void shiftL2Left2Result (operand *left, int offl,
6782 operand *result, int offr, int shCount)
6786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6788 if(pic16_sameRegs(AOP(result), AOP(left))) {
6796 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6797 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6798 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6802 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6803 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6809 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6810 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6811 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6812 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6813 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6814 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6815 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6817 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6818 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6822 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6823 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6824 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6825 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6826 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6827 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6828 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6829 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6830 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6831 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6834 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6835 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6836 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6837 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6838 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6848 /* note, use a mov/add for the shift since the mov has a
6849 chance of getting optimized out */
6850 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6851 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6852 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6853 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6854 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6858 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6859 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6865 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6866 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6867 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6868 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6869 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6870 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6871 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6872 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6876 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6877 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6881 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6882 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6883 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6884 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6886 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6887 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6888 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6889 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6890 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6891 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6892 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6893 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6896 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6897 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6898 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6899 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6900 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6905 /*-----------------------------------------------------------------*/
6906 /* shiftR2Left2Result - shift right two bytes from left to result */
6907 /*-----------------------------------------------------------------*/
6908 static void shiftR2Left2Result (operand *left, int offl,
6909 operand *result, int offr,
6910 int shCount, int sign)
6914 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6915 same = pic16_sameRegs(AOP(result), AOP(left));
6917 if(same && ((offl + MSB16) == offr)){
6919 /* don't crash result[offr] */
6920 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6921 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6924 movLeft2Result(left,offl, result, offr);
6925 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6928 /* a:x >> shCount (x = lsb(result))*/
6931 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6933 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6942 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6947 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6948 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6950 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6951 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6952 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6953 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6958 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6961 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6962 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6969 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6970 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6971 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6973 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6974 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6975 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6976 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6978 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6979 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6980 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6982 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6983 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6984 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6985 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6986 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6990 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6991 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6995 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6996 pic16_emitpcode(POC_BTFSC,
6997 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6998 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
7006 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7007 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7009 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7010 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7011 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
7012 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7014 pic16_emitpcode(POC_BTFSC,
7015 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
7016 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7018 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7019 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
7020 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
7021 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7023 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7024 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7025 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7026 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7027 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7028 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7029 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
7030 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
7032 pic16_emitpcode(POC_BTFSC,
7033 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
7034 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
7036 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
7037 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
7044 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
7045 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
7046 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
7047 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
7050 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
7052 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
7057 /*-----------------------------------------------------------------*/
7058 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
7059 /*-----------------------------------------------------------------*/
7060 static void shiftLLeftOrResult (operand *left, int offl,
7061 operand *result, int offr, int shCount)
7063 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7064 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
7065 /* shift left accumulator */
7067 /* or with result */
7068 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
7069 /* back to result */
7070 pic16_aopPut(AOP(result),"a",offr);
7073 /*-----------------------------------------------------------------*/
7074 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
7075 /*-----------------------------------------------------------------*/
7076 static void shiftRLeftOrResult (operand *left, int offl,
7077 operand *result, int offr, int shCount)
7079 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7080 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
7081 /* shift right accumulator */
7083 /* or with result */
7084 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
7085 /* back to result */
7086 pic16_aopPut(AOP(result),"a",offr);
7089 /*-----------------------------------------------------------------*/
7090 /* genlshOne - left shift a one byte quantity by known count */
7091 /*-----------------------------------------------------------------*/
7092 static void genlshOne (operand *result, operand *left, int shCount)
7094 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7095 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7098 /*-----------------------------------------------------------------*/
7099 /* genlshTwo - left shift two bytes by known amount != 0 */
7100 /*-----------------------------------------------------------------*/
7101 static void genlshTwo (operand *result,operand *left, int shCount)
7105 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7106 size = pic16_getDataSize(result);
7108 /* if shCount >= 8 */
7114 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7116 movLeft2Result(left, LSB, result, MSB16);
7118 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7121 /* 1 <= shCount <= 7 */
7124 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7126 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7130 /*-----------------------------------------------------------------*/
7131 /* shiftLLong - shift left one long from left to result */
7132 /* offl = LSB or MSB16 */
7133 /*-----------------------------------------------------------------*/
7134 static void shiftLLong (operand *left, operand *result, int offr )
7137 int size = AOP_SIZE(result);
7139 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7140 if(size >= LSB+offr){
7141 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7143 pic16_emitcode("add","a,acc");
7144 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7145 size >= MSB16+offr && offr != LSB )
7146 pic16_emitcode("xch","a,%s",
7147 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7149 pic16_aopPut(AOP(result),"a",LSB+offr);
7152 if(size >= MSB16+offr){
7153 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7154 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7157 pic16_emitcode("rlc","a");
7158 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7159 size >= MSB24+offr && offr != LSB)
7160 pic16_emitcode("xch","a,%s",
7161 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7163 pic16_aopPut(AOP(result),"a",MSB16+offr);
7166 if(size >= MSB24+offr){
7167 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7168 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7171 pic16_emitcode("rlc","a");
7172 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7173 size >= MSB32+offr && offr != LSB )
7174 pic16_emitcode("xch","a,%s",
7175 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7177 pic16_aopPut(AOP(result),"a",MSB24+offr);
7180 if(size > MSB32+offr){
7181 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7182 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7185 pic16_emitcode("rlc","a");
7186 pic16_aopPut(AOP(result),"a",MSB32+offr);
7189 pic16_aopPut(AOP(result),zero,LSB);
7192 /*-----------------------------------------------------------------*/
7193 /* genlshFour - shift four byte by a known amount != 0 */
7194 /*-----------------------------------------------------------------*/
7195 static void genlshFour (operand *result, operand *left, int shCount)
7199 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7200 size = AOP_SIZE(result);
7202 /* if shifting more that 3 bytes */
7203 if (shCount >= 24 ) {
7206 /* lowest order of left goes to the highest
7207 order of the destination */
7208 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7210 movLeft2Result(left, LSB, result, MSB32);
7211 pic16_aopPut(AOP(result),zero,LSB);
7212 pic16_aopPut(AOP(result),zero,MSB16);
7213 pic16_aopPut(AOP(result),zero,MSB32);
7217 /* more than two bytes */
7218 else if ( shCount >= 16 ) {
7219 /* lower order two bytes goes to higher order two bytes */
7221 /* if some more remaining */
7223 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7225 movLeft2Result(left, MSB16, result, MSB32);
7226 movLeft2Result(left, LSB, result, MSB24);
7228 pic16_aopPut(AOP(result),zero,MSB16);
7229 pic16_aopPut(AOP(result),zero,LSB);
7233 /* if more than 1 byte */
7234 else if ( shCount >= 8 ) {
7235 /* lower order three bytes goes to higher order three bytes */
7239 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7241 movLeft2Result(left, LSB, result, MSB16);
7243 else{ /* size = 4 */
7245 movLeft2Result(left, MSB24, result, MSB32);
7246 movLeft2Result(left, MSB16, result, MSB24);
7247 movLeft2Result(left, LSB, result, MSB16);
7248 pic16_aopPut(AOP(result),zero,LSB);
7250 else if(shCount == 1)
7251 shiftLLong(left, result, MSB16);
7253 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7254 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7255 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7256 pic16_aopPut(AOP(result),zero,LSB);
7261 /* 1 <= shCount <= 7 */
7262 else if(shCount <= 2){
7263 shiftLLong(left, result, LSB);
7265 shiftLLong(result, result, LSB);
7267 /* 3 <= shCount <= 7, optimize */
7269 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7270 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7271 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7275 /*-----------------------------------------------------------------*/
7276 /* genLeftShiftLiteral - left shifting by known count */
7277 /*-----------------------------------------------------------------*/
7278 static void genLeftShiftLiteral (operand *left,
7283 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7286 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7287 pic16_freeAsmop(right,NULL,ic,TRUE);
7289 pic16_aopOp(left,ic,FALSE);
7290 pic16_aopOp(result,ic,FALSE);
7292 size = getSize(operandType(result));
7295 pic16_emitcode("; shift left ","result %d, left %d",size,
7299 /* I suppose that the left size >= result size */
7302 movLeft2Result(left, size, result, size);
7306 else if(shCount >= (size * 8))
7308 pic16_aopPut(AOP(result),zero,size);
7312 genlshOne (result,left,shCount);
7317 genlshTwo (result,left,shCount);
7321 genlshFour (result,left,shCount);
7325 pic16_freeAsmop(left,NULL,ic,TRUE);
7326 pic16_freeAsmop(result,NULL,ic,TRUE);
7329 /*-----------------------------------------------------------------*
7330 * genMultiAsm - repeat assembly instruction for size of register.
7331 * if endian == 1, then the high byte (i.e base address + size of
7332 * register) is used first else the low byte is used first;
7333 *-----------------------------------------------------------------*/
7334 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7339 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7352 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7357 /*-----------------------------------------------------------------*/
7358 /* genLeftShift - generates code for left shifting */
7359 /*-----------------------------------------------------------------*/
7360 static void genLeftShift (iCode *ic)
7362 operand *left,*right, *result;
7365 symbol *tlbl , *tlbl1;
7368 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7370 right = IC_RIGHT(ic);
7372 result = IC_RESULT(ic);
7374 pic16_aopOp(right,ic,FALSE);
7376 /* if the shift count is known then do it
7377 as efficiently as possible */
7378 if (AOP_TYPE(right) == AOP_LIT) {
7379 genLeftShiftLiteral (left,right,result,ic);
7383 /* shift count is unknown then we have to form
7384 a loop get the loop count in B : Note: we take
7385 only the lower order byte since shifting
7386 more that 32 bits make no sense anyway, ( the
7387 largest size of an object can be only 32 bits ) */
7390 pic16_aopOp(left,ic,FALSE);
7391 pic16_aopOp(result,ic,FALSE);
7393 /* now move the left to the result if they are not the
7395 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7396 AOP_SIZE(result) > 1) {
7398 size = AOP_SIZE(result);
7401 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7402 if (*l == '@' && (IS_AOP_PREG(result))) {
7404 pic16_emitcode("mov","a,%s",l);
7405 pic16_aopPut(AOP(result),"a",offset);
7407 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7408 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7409 //pic16_aopPut(AOP(result),l,offset);
7415 size = AOP_SIZE(result);
7417 /* if it is only one byte then */
7419 if(optimized_for_speed) {
7420 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7421 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7422 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7423 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7424 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7425 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7426 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7427 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7428 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7429 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7430 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7431 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7434 tlbl = newiTempLabel(NULL);
7435 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7436 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7437 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7440 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7441 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7442 pic16_emitpLabel(tlbl->key);
7443 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7444 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7446 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7451 if (pic16_sameRegs(AOP(left),AOP(result))) {
7453 tlbl = newiTempLabel(NULL);
7454 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7455 genMultiAsm(POC_RRCF, result, size,1);
7456 pic16_emitpLabel(tlbl->key);
7457 genMultiAsm(POC_RLCF, result, size,0);
7458 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7460 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7464 //tlbl = newiTempLabel(NULL);
7466 //tlbl1 = newiTempLabel(NULL);
7468 //reAdjustPreg(AOP(result));
7470 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7471 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7472 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7474 //pic16_emitcode("add","a,acc");
7475 //pic16_aopPut(AOP(result),"a",offset++);
7477 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7479 // pic16_emitcode("rlc","a");
7480 // pic16_aopPut(AOP(result),"a",offset++);
7482 //reAdjustPreg(AOP(result));
7484 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7485 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7488 tlbl = newiTempLabel(NULL);
7489 tlbl1= newiTempLabel(NULL);
7491 size = AOP_SIZE(result);
7494 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7496 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7498 /* offset should be 0, 1 or 3 */
7499 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7501 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7503 pic16_emitpcode(POC_MOVWF, pctemp);
7506 pic16_emitpLabel(tlbl->key);
7509 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7511 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7513 pic16_emitpcode(POC_DECFSZ, pctemp);
7514 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7515 pic16_emitpLabel(tlbl1->key);
7517 pic16_popReleaseTempReg(pctemp);
7521 pic16_freeAsmop (right,NULL,ic,TRUE);
7522 pic16_freeAsmop(left,NULL,ic,TRUE);
7523 pic16_freeAsmop(result,NULL,ic,TRUE);
7526 /*-----------------------------------------------------------------*/
7527 /* genrshOne - right shift a one byte quantity by known count */
7528 /*-----------------------------------------------------------------*/
7529 static void genrshOne (operand *result, operand *left,
7530 int shCount, int sign)
7532 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7533 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7536 /*-----------------------------------------------------------------*/
7537 /* genrshTwo - right shift two bytes by known amount != 0 */
7538 /*-----------------------------------------------------------------*/
7539 static void genrshTwo (operand *result,operand *left,
7540 int shCount, int sign)
7542 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7543 /* if shCount >= 8 */
7547 shiftR1Left2Result(left, MSB16, result, LSB,
7550 movLeft2Result(left, MSB16, result, LSB);
7552 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7555 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7556 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7560 /* 1 <= shCount <= 7 */
7562 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7565 /*-----------------------------------------------------------------*/
7566 /* shiftRLong - shift right one long from left to result */
7567 /* offl = LSB or MSB16 */
7568 /*-----------------------------------------------------------------*/
7569 static void shiftRLong (operand *left, int offl,
7570 operand *result, int sign)
7572 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7574 pic16_emitcode("clr","c");
7575 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7577 pic16_emitcode("mov","c,acc.7");
7578 pic16_emitcode("rrc","a");
7579 pic16_aopPut(AOP(result),"a",MSB32-offl);
7581 /* add sign of "a" */
7582 pic16_addSign(result, MSB32, sign);
7584 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7585 pic16_emitcode("rrc","a");
7586 pic16_aopPut(AOP(result),"a",MSB24-offl);
7588 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7589 pic16_emitcode("rrc","a");
7590 pic16_aopPut(AOP(result),"a",MSB16-offl);
7593 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7594 pic16_emitcode("rrc","a");
7595 pic16_aopPut(AOP(result),"a",LSB);
7599 /*-----------------------------------------------------------------*/
7600 /* genrshFour - shift four byte by a known amount != 0 */
7601 /*-----------------------------------------------------------------*/
7602 static void genrshFour (operand *result, operand *left,
7603 int shCount, int sign)
7605 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7606 /* if shifting more that 3 bytes */
7607 if(shCount >= 24 ) {
7610 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7612 movLeft2Result(left, MSB32, result, LSB);
7614 pic16_addSign(result, MSB16, sign);
7616 else if(shCount >= 16){
7619 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7621 movLeft2Result(left, MSB24, result, LSB);
7622 movLeft2Result(left, MSB32, result, MSB16);
7624 pic16_addSign(result, MSB24, sign);
7626 else if(shCount >= 8){
7629 shiftRLong(left, MSB16, result, sign);
7630 else if(shCount == 0){
7631 movLeft2Result(left, MSB16, result, LSB);
7632 movLeft2Result(left, MSB24, result, MSB16);
7633 movLeft2Result(left, MSB32, result, MSB24);
7634 pic16_addSign(result, MSB32, sign);
7637 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7638 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7639 /* the last shift is signed */
7640 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7641 pic16_addSign(result, MSB32, sign);
7644 else{ /* 1 <= shCount <= 7 */
7646 shiftRLong(left, LSB, result, sign);
7648 shiftRLong(result, LSB, result, sign);
7651 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7652 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7653 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7658 /*-----------------------------------------------------------------*/
7659 /* genRightShiftLiteral - right shifting by known count */
7660 /*-----------------------------------------------------------------*/
7661 static void genRightShiftLiteral (operand *left,
7667 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7670 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7671 pic16_freeAsmop(right,NULL,ic,TRUE);
7673 pic16_aopOp(left,ic,FALSE);
7674 pic16_aopOp(result,ic,FALSE);
7677 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7681 lsize = pic16_getDataSize(left);
7682 res_size = pic16_getDataSize(result);
7683 /* test the LEFT size !!! */
7685 /* I suppose that the left size >= result size */
7688 movLeft2Result(left, lsize, result, res_size);
7691 else if(shCount >= (lsize * 8)){
7694 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7696 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7697 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7702 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7703 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7704 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7706 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7711 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7718 genrshOne (result,left,shCount,sign);
7722 genrshTwo (result,left,shCount,sign);
7726 genrshFour (result,left,shCount,sign);
7734 pic16_freeAsmop(left,NULL,ic,TRUE);
7735 pic16_freeAsmop(result,NULL,ic,TRUE);
7738 /*-----------------------------------------------------------------*/
7739 /* genSignedRightShift - right shift of signed number */
7740 /*-----------------------------------------------------------------*/
7741 static void genSignedRightShift (iCode *ic)
7743 operand *right, *left, *result;
7746 symbol *tlbl, *tlbl1 ;
7749 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7751 /* we do it the hard way put the shift count in b
7752 and loop thru preserving the sign */
7753 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7755 right = IC_RIGHT(ic);
7757 result = IC_RESULT(ic);
7759 pic16_aopOp(right,ic,FALSE);
7760 pic16_aopOp(left,ic,FALSE);
7761 pic16_aopOp(result,ic,FALSE);
7764 if ( AOP_TYPE(right) == AOP_LIT) {
7765 genRightShiftLiteral (left,right,result,ic,1);
7768 /* shift count is unknown then we have to form
7769 a loop get the loop count in B : Note: we take
7770 only the lower order byte since shifting
7771 more that 32 bits make no sense anyway, ( the
7772 largest size of an object can be only 32 bits ) */
7774 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7775 //pic16_emitcode("inc","b");
7776 //pic16_freeAsmop (right,NULL,ic,TRUE);
7777 //pic16_aopOp(left,ic,FALSE);
7778 //pic16_aopOp(result,ic,FALSE);
7780 /* now move the left to the result if they are not the
7782 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7783 AOP_SIZE(result) > 1) {
7785 size = AOP_SIZE(result);
7789 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7790 if (*l == '@' && IS_AOP_PREG(result)) {
7792 pic16_emitcode("mov","a,%s",l);
7793 pic16_aopPut(AOP(result),"a",offset);
7795 pic16_aopPut(AOP(result),l,offset);
7797 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7798 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7804 /* mov the highest order bit to OVR */
7805 tlbl = newiTempLabel(NULL);
7806 tlbl1= newiTempLabel(NULL);
7808 size = AOP_SIZE(result);
7811 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7813 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7815 /* offset should be 0, 1 or 3 */
7816 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7818 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7820 pic16_emitpcode(POC_MOVWF, pctemp);
7823 pic16_emitpLabel(tlbl->key);
7825 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7826 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7829 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7832 pic16_emitpcode(POC_DECFSZ, pctemp);
7833 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7834 pic16_emitpLabel(tlbl1->key);
7836 pic16_popReleaseTempReg(pctemp);
7838 size = AOP_SIZE(result);
7840 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7841 pic16_emitcode("rlc","a");
7842 pic16_emitcode("mov","ov,c");
7843 /* if it is only one byte then */
7845 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7847 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7848 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7849 pic16_emitcode("mov","c,ov");
7850 pic16_emitcode("rrc","a");
7851 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7852 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7853 pic16_aopPut(AOP(result),"a",0);
7857 reAdjustPreg(AOP(result));
7858 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7859 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7860 pic16_emitcode("mov","c,ov");
7862 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7864 pic16_emitcode("rrc","a");
7865 pic16_aopPut(AOP(result),"a",offset--);
7867 reAdjustPreg(AOP(result));
7868 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7869 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7874 pic16_freeAsmop(left,NULL,ic,TRUE);
7875 pic16_freeAsmop(result,NULL,ic,TRUE);
7876 pic16_freeAsmop(right,NULL,ic,TRUE);
7879 /*-----------------------------------------------------------------*/
7880 /* genRightShift - generate code for right shifting */
7881 /*-----------------------------------------------------------------*/
7882 static void genRightShift (iCode *ic)
7884 operand *right, *left, *result;
7888 symbol *tlbl, *tlbl1 ;
7890 /* if signed then we do it the hard way preserve the
7891 sign bit moving it inwards */
7892 retype = getSpec(operandType(IC_RESULT(ic)));
7893 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7895 if (!SPEC_USIGN(retype)) {
7896 genSignedRightShift (ic);
7900 /* signed & unsigned types are treated the same : i.e. the
7901 signed is NOT propagated inwards : quoting from the
7902 ANSI - standard : "for E1 >> E2, is equivalent to division
7903 by 2**E2 if unsigned or if it has a non-negative value,
7904 otherwise the result is implementation defined ", MY definition
7905 is that the sign does not get propagated */
7907 right = IC_RIGHT(ic);
7909 result = IC_RESULT(ic);
7911 pic16_aopOp(right,ic,FALSE);
7913 /* if the shift count is known then do it
7914 as efficiently as possible */
7915 if (AOP_TYPE(right) == AOP_LIT) {
7916 genRightShiftLiteral (left,right,result,ic, 0);
7920 /* shift count is unknown then we have to form
7921 a loop get the loop count in B : Note: we take
7922 only the lower order byte since shifting
7923 more that 32 bits make no sense anyway, ( the
7924 largest size of an object can be only 32 bits ) */
7926 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7927 pic16_emitcode("inc","b");
7928 pic16_aopOp(left,ic,FALSE);
7929 pic16_aopOp(result,ic,FALSE);
7931 /* now move the left to the result if they are not the
7933 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7934 AOP_SIZE(result) > 1) {
7936 size = AOP_SIZE(result);
7939 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7940 if (*l == '@' && IS_AOP_PREG(result)) {
7942 pic16_emitcode("mov","a,%s",l);
7943 pic16_aopPut(AOP(result),"a",offset);
7945 pic16_aopPut(AOP(result),l,offset);
7950 tlbl = newiTempLabel(NULL);
7951 tlbl1= newiTempLabel(NULL);
7952 size = AOP_SIZE(result);
7955 /* if it is only one byte then */
7958 tlbl = newiTempLabel(NULL);
7959 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7960 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7961 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7964 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7965 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7966 pic16_emitpLabel(tlbl->key);
7967 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7968 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7970 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7975 reAdjustPreg(AOP(result));
7976 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7977 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7980 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7982 pic16_emitcode("rrc","a");
7983 pic16_aopPut(AOP(result),"a",offset--);
7985 reAdjustPreg(AOP(result));
7987 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7988 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7991 pic16_freeAsmop(left,NULL,ic,TRUE);
7992 pic16_freeAsmop (right,NULL,ic,TRUE);
7993 pic16_freeAsmop(result,NULL,ic,TRUE);
7996 /*-----------------------------------------------------------------*/
7997 /* genUnpackBits - generates code for unpacking bits */
7998 /*-----------------------------------------------------------------*/
7999 static void genUnpackBits (operand *result, char *rname, int ptype)
8006 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8007 etype = getSpec(operandType(result));
8009 /* read the first byte */
8014 pic16_emitcode("mov","a,@%s",rname);
8018 pic16_emitcode("movx","a,@%s",rname);
8022 pic16_emitcode("movx","a,@dptr");
8026 pic16_emitcode("clr","a");
8027 pic16_emitcode("movc","a","@a+dptr");
8031 pic16_emitcode("lcall","__gptrget");
8035 /* if we have bitdisplacement then it fits */
8036 /* into this byte completely or if length is */
8037 /* less than a byte */
8038 if ((shCnt = SPEC_BSTR(etype)) ||
8039 (SPEC_BLEN(etype) <= 8)) {
8041 /* shift right acc */
8044 pic16_emitcode("anl","a,#0x%02x",
8045 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
8046 pic16_aopPut(AOP(result),"a",offset);
8050 /* bit field did not fit in a byte */
8051 rlen = SPEC_BLEN(etype) - 8;
8052 pic16_aopPut(AOP(result),"a",offset++);
8059 pic16_emitcode("inc","%s",rname);
8060 pic16_emitcode("mov","a,@%s",rname);
8064 pic16_emitcode("inc","%s",rname);
8065 pic16_emitcode("movx","a,@%s",rname);
8069 pic16_emitcode("inc","dptr");
8070 pic16_emitcode("movx","a,@dptr");
8074 pic16_emitcode("clr","a");
8075 pic16_emitcode("inc","dptr");
8076 pic16_emitcode("movc","a","@a+dptr");
8080 pic16_emitcode("inc","dptr");
8081 pic16_emitcode("lcall","__gptrget");
8086 /* if we are done */
8090 pic16_aopPut(AOP(result),"a",offset++);
8095 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
8096 pic16_aopPut(AOP(result),"a",offset);
8103 /*-----------------------------------------------------------------*/
8104 /* genDataPointerGet - generates code when ptr offset is known */
8105 /*-----------------------------------------------------------------*/
8106 static void genDataPointerGet (operand *left,
8110 int size , offset = 0;
8113 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8116 /* optimization - most of the time, left and result are the same
8117 * address, but different types. for the pic code, we could omit
8121 pic16_aopOp(result,ic,TRUE);
8123 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8125 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8127 size = AOP_SIZE(result);
8130 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8134 pic16_freeAsmop(left,NULL,ic,TRUE);
8135 pic16_freeAsmop(result,NULL,ic,TRUE);
8138 /*-----------------------------------------------------------------*/
8139 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8140 /*-----------------------------------------------------------------*/
8141 static void genNearPointerGet (operand *left,
8146 //regs *preg = NULL ;
8148 sym_link *rtype, *retype;
8149 sym_link *ltype = operandType(left);
8152 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8154 rtype = operandType(result);
8155 retype= getSpec(rtype);
8157 pic16_aopOp(left,ic,FALSE);
8159 /* if left is rematerialisable and
8160 result is not bit variable type and
8161 the left is pointer to data space i.e
8162 lower 128 bytes of space */
8163 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8164 !IS_BITVAR(retype) &&
8165 DCL_TYPE(ltype) == POINTER) {
8166 //genDataPointerGet (left,result,ic);
8170 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8172 /* if the value is already in a pointer register
8173 then don't need anything more */
8174 if (!AOP_INPREG(AOP(left))) {
8175 /* otherwise get a free pointer register */
8176 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8179 preg = getFreePtr(ic,&aop,FALSE);
8180 pic16_emitcode("mov","%s,%s",
8182 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8183 rname = preg->name ;
8187 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8189 pic16_aopOp (result,ic,FALSE);
8191 /* if bitfield then unpack the bits */
8192 if (IS_BITVAR(retype))
8193 genUnpackBits (result,rname,POINTER);
8195 /* we have can just get the values */
8196 int size = AOP_SIZE(result);
8199 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8201 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8202 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8204 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8205 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8207 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8211 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8213 pic16_emitcode("mov","a,@%s",rname);
8214 pic16_aopPut(AOP(result),"a",offset);
8216 sprintf(buffer,"@%s",rname);
8217 pic16_aopPut(AOP(result),buffer,offset);
8221 pic16_emitcode("inc","%s",rname);
8226 /* now some housekeeping stuff */
8228 /* we had to allocate for this iCode */
8229 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8230 pic16_freeAsmop(NULL,aop,ic,TRUE);
8232 /* we did not allocate which means left
8233 already in a pointer register, then
8234 if size > 0 && this could be used again
8235 we have to point it back to where it
8237 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8238 if (AOP_SIZE(result) > 1 &&
8239 !OP_SYMBOL(left)->remat &&
8240 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8242 int size = AOP_SIZE(result) - 1;
8244 pic16_emitcode("dec","%s",rname);
8249 pic16_freeAsmop(left,NULL,ic,TRUE);
8250 pic16_freeAsmop(result,NULL,ic,TRUE);
8254 /*-----------------------------------------------------------------*/
8255 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8256 /*-----------------------------------------------------------------*/
8257 static void genPagedPointerGet (operand *left,
8264 sym_link *rtype, *retype;
8266 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8268 rtype = operandType(result);
8269 retype= getSpec(rtype);
8271 pic16_aopOp(left,ic,FALSE);
8273 /* if the value is already in a pointer register
8274 then don't need anything more */
8275 if (!AOP_INPREG(AOP(left))) {
8276 /* otherwise get a free pointer register */
8278 preg = getFreePtr(ic,&aop,FALSE);
8279 pic16_emitcode("mov","%s,%s",
8281 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8282 rname = preg->name ;
8284 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8286 pic16_freeAsmop(left,NULL,ic,TRUE);
8287 pic16_aopOp (result,ic,FALSE);
8289 /* if bitfield then unpack the bits */
8290 if (IS_BITVAR(retype))
8291 genUnpackBits (result,rname,PPOINTER);
8293 /* we have can just get the values */
8294 int size = AOP_SIZE(result);
8299 pic16_emitcode("movx","a,@%s",rname);
8300 pic16_aopPut(AOP(result),"a",offset);
8305 pic16_emitcode("inc","%s",rname);
8309 /* now some housekeeping stuff */
8311 /* we had to allocate for this iCode */
8312 pic16_freeAsmop(NULL,aop,ic,TRUE);
8314 /* we did not allocate which means left
8315 already in a pointer register, then
8316 if size > 0 && this could be used again
8317 we have to point it back to where it
8319 if (AOP_SIZE(result) > 1 &&
8320 !OP_SYMBOL(left)->remat &&
8321 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8323 int size = AOP_SIZE(result) - 1;
8325 pic16_emitcode("dec","%s",rname);
8330 pic16_freeAsmop(result,NULL,ic,TRUE);
8335 /*-----------------------------------------------------------------*/
8336 /* genFarPointerGet - gget value from far space */
8337 /*-----------------------------------------------------------------*/
8338 static void genFarPointerGet (operand *left,
8339 operand *result, iCode *ic)
8342 sym_link *retype = getSpec(operandType(result));
8344 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8346 pic16_aopOp(left,ic,FALSE);
8348 /* if the operand is already in dptr
8349 then we do nothing else we move the value to dptr */
8350 if (AOP_TYPE(left) != AOP_STR) {
8351 /* if this is remateriazable */
8352 if (AOP_TYPE(left) == AOP_IMMD)
8353 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8354 else { /* we need to get it byte by byte */
8355 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8356 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8357 if (options.model == MODEL_FLAT24)
8359 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8363 /* so dptr know contains the address */
8364 pic16_freeAsmop(left,NULL,ic,TRUE);
8365 pic16_aopOp(result,ic,FALSE);
8367 /* if bit then unpack */
8368 if (IS_BITVAR(retype))
8369 genUnpackBits(result,"dptr",FPOINTER);
8371 size = AOP_SIZE(result);
8375 pic16_emitcode("movx","a,@dptr");
8376 pic16_aopPut(AOP(result),"a",offset++);
8378 pic16_emitcode("inc","dptr");
8382 pic16_freeAsmop(result,NULL,ic,TRUE);
8385 /*-----------------------------------------------------------------*/
8386 /* genCodePointerGet - get value from code space */
8387 /*-----------------------------------------------------------------*/
8388 static void genCodePointerGet (operand *left,
8389 operand *result, iCode *ic)
8392 sym_link *retype = getSpec(operandType(result));
8394 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8396 pic16_aopOp(left,ic,FALSE);
8398 /* if the operand is already in dptr
8399 then we do nothing else we move the value to dptr */
8400 if (AOP_TYPE(left) != AOP_STR) {
8401 /* if this is remateriazable */
8402 if (AOP_TYPE(left) == AOP_IMMD)
8403 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8404 else { /* we need to get it byte by byte */
8405 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8406 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8407 if (options.model == MODEL_FLAT24)
8409 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8413 /* so dptr know contains the address */
8414 pic16_freeAsmop(left,NULL,ic,TRUE);
8415 pic16_aopOp(result,ic,FALSE);
8417 /* if bit then unpack */
8418 if (IS_BITVAR(retype))
8419 genUnpackBits(result,"dptr",CPOINTER);
8421 size = AOP_SIZE(result);
8425 pic16_emitcode("clr","a");
8426 pic16_emitcode("movc","a,@a+dptr");
8427 pic16_aopPut(AOP(result),"a",offset++);
8429 pic16_emitcode("inc","dptr");
8433 pic16_freeAsmop(result,NULL,ic,TRUE);
8436 /*-----------------------------------------------------------------*/
8437 /* genGenPointerGet - gget value from generic pointer space */
8438 /*-----------------------------------------------------------------*/
8439 static void genGenPointerGet (operand *left,
8440 operand *result, iCode *ic)
8443 sym_link *retype = getSpec(operandType(result));
8445 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8446 pic16_aopOp(left,ic,FALSE);
8447 pic16_aopOp(result,ic,FALSE);
8450 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8452 /* if the operand is already in dptr
8453 then we do nothing else we move the value to dptr */
8454 // if (AOP_TYPE(left) != AOP_STR) {
8455 /* if this is remateriazable */
8456 if (AOP_TYPE(left) == AOP_IMMD) {
8457 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8458 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8460 else { /* we need to get it byte by byte */
8462 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8463 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8465 size = AOP_SIZE(result);
8469 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8470 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8472 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8477 /* so dptr know contains the address */
8479 /* if bit then unpack */
8480 //if (IS_BITVAR(retype))
8481 // genUnpackBits(result,"dptr",GPOINTER);
8484 pic16_freeAsmop(left,NULL,ic,TRUE);
8485 pic16_freeAsmop(result,NULL,ic,TRUE);
8489 /*-----------------------------------------------------------------*/
8490 /* genConstPointerGet - get value from const generic pointer space */
8491 /*-----------------------------------------------------------------*/
8492 static void genConstPointerGet (operand *left,
8493 operand *result, iCode *ic)
8495 //sym_link *retype = getSpec(operandType(result));
8496 symbol *albl = newiTempLabel(NULL);
8497 symbol *blbl = newiTempLabel(NULL);
8500 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8501 pic16_aopOp(left,ic,FALSE);
8502 pic16_aopOp(result,ic,FALSE);
8505 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8507 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8509 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8510 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8511 pic16_emitpLabel(albl->key);
8513 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8515 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8516 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8517 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8518 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8520 pic16_emitpLabel(blbl->key);
8522 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8525 pic16_freeAsmop(left,NULL,ic,TRUE);
8526 pic16_freeAsmop(result,NULL,ic,TRUE);
8529 /*-----------------------------------------------------------------*/
8530 /* genPointerGet - generate code for pointer get */
8531 /*-----------------------------------------------------------------*/
8532 static void genPointerGet (iCode *ic)
8534 operand *left, *result ;
8535 sym_link *type, *etype;
8538 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8541 result = IC_RESULT(ic) ;
8543 /* depending on the type of pointer we need to
8544 move it to the correct pointer register */
8545 type = operandType(left);
8546 etype = getSpec(type);
8549 if (IS_PTR_CONST(type))
8551 if (IS_CODEPTR(type))
8553 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8555 /* if left is of type of pointer then it is simple */
8556 if (IS_PTR(type) && !IS_FUNC(type->next))
8557 p_type = DCL_TYPE(type);
8559 /* we have to go by the storage class */
8560 p_type = PTR_TYPE(SPEC_OCLS(etype));
8562 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8564 if (SPEC_OCLS(etype)->codesp ) {
8565 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8566 //p_type = CPOINTER ;
8569 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8570 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8571 /*p_type = FPOINTER ;*/
8573 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8574 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8575 /* p_type = PPOINTER; */
8577 if (SPEC_OCLS(etype) == idata )
8578 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8579 /* p_type = IPOINTER; */
8581 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8582 /* p_type = POINTER ; */
8585 /* now that we have the pointer type we assign
8586 the pointer values */
8591 genNearPointerGet (left,result,ic);
8595 genPagedPointerGet(left,result,ic);
8599 genFarPointerGet (left,result,ic);
8603 genConstPointerGet (left,result,ic);
8604 //pic16_emitcodePointerGet (left,result,ic);
8609 if (IS_PTR_CONST(type))
8610 genConstPointerGet (left,result,ic);
8613 genGenPointerGet (left,result,ic);
8619 /*-----------------------------------------------------------------*/
8620 /* genPackBits - generates code for packed bit storage */
8621 /*-----------------------------------------------------------------*/
8622 static void genPackBits (sym_link *etype ,
8624 char *rname, int p_type)
8632 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8633 blen = SPEC_BLEN(etype);
8634 bstr = SPEC_BSTR(etype);
8636 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8639 /* if the bit lenth is less than or */
8640 /* it exactly fits a byte then */
8641 if (SPEC_BLEN(etype) <= 8 ) {
8642 shCount = SPEC_BSTR(etype) ;
8644 /* shift left acc */
8647 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8652 pic16_emitcode ("mov","b,a");
8653 pic16_emitcode("mov","a,@%s",rname);
8657 pic16_emitcode ("mov","b,a");
8658 pic16_emitcode("movx","a,@dptr");
8662 pic16_emitcode ("push","b");
8663 pic16_emitcode ("push","acc");
8664 pic16_emitcode ("lcall","__gptrget");
8665 pic16_emitcode ("pop","b");
8669 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8670 ((unsigned char)(0xFF << (blen+bstr)) |
8671 (unsigned char)(0xFF >> (8-bstr)) ) );
8672 pic16_emitcode ("orl","a,b");
8673 if (p_type == GPOINTER)
8674 pic16_emitcode("pop","b");
8680 pic16_emitcode("mov","@%s,a",rname);
8684 pic16_emitcode("movx","@dptr,a");
8688 DEBUGpic16_emitcode(";lcall","__gptrput");
8693 if ( SPEC_BLEN(etype) <= 8 )
8696 pic16_emitcode("inc","%s",rname);
8697 rLen = SPEC_BLEN(etype) ;
8699 /* now generate for lengths greater than one byte */
8702 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8712 pic16_emitcode("mov","@%s,a",rname);
8714 pic16_emitcode("mov","@%s,%s",rname,l);
8719 pic16_emitcode("movx","@dptr,a");
8724 DEBUGpic16_emitcode(";lcall","__gptrput");
8727 pic16_emitcode ("inc","%s",rname);
8732 /* last last was not complete */
8734 /* save the byte & read byte */
8737 pic16_emitcode ("mov","b,a");
8738 pic16_emitcode("mov","a,@%s",rname);
8742 pic16_emitcode ("mov","b,a");
8743 pic16_emitcode("movx","a,@dptr");
8747 pic16_emitcode ("push","b");
8748 pic16_emitcode ("push","acc");
8749 pic16_emitcode ("lcall","__gptrget");
8750 pic16_emitcode ("pop","b");
8754 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8755 pic16_emitcode ("orl","a,b");
8758 if (p_type == GPOINTER)
8759 pic16_emitcode("pop","b");
8764 pic16_emitcode("mov","@%s,a",rname);
8768 pic16_emitcode("movx","@dptr,a");
8772 DEBUGpic16_emitcode(";lcall","__gptrput");
8776 /*-----------------------------------------------------------------*/
8777 /* genDataPointerSet - remat pointer to data space */
8778 /*-----------------------------------------------------------------*/
8779 static void genDataPointerSet(operand *right,
8783 int size, offset = 0 ;
8784 char *l, buffer[256];
8786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8787 pic16_aopOp(right,ic,FALSE);
8789 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8790 size = AOP_SIZE(right);
8792 if ( AOP_TYPE(result) == AOP_PCODE) {
8793 fprintf(stderr,"genDataPointerSet %s, %d\n",
8794 AOP(result)->aopu.pcop->name,
8795 PCOI(AOP(result)->aopu.pcop)->offset);
8799 // tsd, was l+1 - the underline `_' prefix was being stripped
8802 sprintf(buffer,"(%s + %d)",l,offset);
8803 fprintf(stderr,"oops %s\n",buffer);
8805 sprintf(buffer,"%s",l);
8807 if (AOP_TYPE(right) == AOP_LIT) {
8808 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8809 lit = lit >> (8*offset);
8811 pic16_emitcode("movlw","%d",lit);
8812 pic16_emitcode("movwf","%s",buffer);
8814 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8815 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
8816 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8819 pic16_emitcode("clrf","%s",buffer);
8820 //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer));
8821 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8824 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8825 pic16_emitcode("movwf","%s",buffer);
8827 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8828 //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer));
8829 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8836 pic16_freeAsmop(right,NULL,ic,TRUE);
8837 pic16_freeAsmop(result,NULL,ic,TRUE);
8840 /*-----------------------------------------------------------------*/
8841 /* genNearPointerSet - pic16_emitcode for near pointer put */
8842 /*-----------------------------------------------------------------*/
8843 static void genNearPointerSet (operand *right,
8850 sym_link *ptype = operandType(result);
8853 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8854 retype= getSpec(operandType(right));
8856 pic16_aopOp(result,ic,FALSE);
8859 /* if the result is rematerializable &
8860 in data space & not a bit variable */
8861 //if (AOP_TYPE(result) == AOP_IMMD &&
8862 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8863 DCL_TYPE(ptype) == POINTER &&
8864 !IS_BITVAR(retype)) {
8865 genDataPointerSet (right,result,ic);
8866 pic16_freeAsmop(result,NULL,ic,TRUE);
8870 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8871 pic16_aopOp(right,ic,FALSE);
8872 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8874 /* if the value is already in a pointer register
8875 then don't need anything more */
8876 if (!AOP_INPREG(AOP(result))) {
8877 /* otherwise get a free pointer register */
8878 //aop = newAsmop(0);
8879 //preg = getFreePtr(ic,&aop,FALSE);
8880 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8881 //pic16_emitcode("mov","%s,%s",
8883 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8884 //rname = preg->name ;
8885 //pic16_emitcode("movwf","fsr0");
8886 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8887 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8888 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8889 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8893 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8896 /* if bitfield then unpack the bits */
8897 if (IS_BITVAR(retype)) {
8898 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8899 "The programmer is obviously confused");
8900 //genPackBits (retype,right,rname,POINTER);
8904 /* we have can just get the values */
8905 int size = AOP_SIZE(right);
8908 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8910 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8913 //pic16_emitcode("mov","@%s,a",rname);
8914 pic16_emitcode("movf","indf0,w ;1");
8917 if (AOP_TYPE(right) == AOP_LIT) {
8918 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8920 pic16_emitcode("movlw","%s",l);
8921 pic16_emitcode("movwf","indf0 ;2");
8923 pic16_emitcode("clrf","indf0");
8925 pic16_emitcode("movf","%s,w",l);
8926 pic16_emitcode("movwf","indf0 ;2");
8928 //pic16_emitcode("mov","@%s,%s",rname,l);
8931 pic16_emitcode("incf","fsr0,f ;3");
8932 //pic16_emitcode("inc","%s",rname);
8937 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8938 /* now some housekeeping stuff */
8940 /* we had to allocate for this iCode */
8941 pic16_freeAsmop(NULL,aop,ic,TRUE);
8943 /* we did not allocate which means left
8944 already in a pointer register, then
8945 if size > 0 && this could be used again
8946 we have to point it back to where it
8948 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8949 if (AOP_SIZE(right) > 1 &&
8950 !OP_SYMBOL(result)->remat &&
8951 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8953 int size = AOP_SIZE(right) - 1;
8955 pic16_emitcode("decf","fsr0,f");
8956 //pic16_emitcode("dec","%s",rname);
8960 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8963 pic16_freeAsmop(right,NULL,ic,TRUE);
8964 pic16_freeAsmop(result,NULL,ic,TRUE);
8967 /*-----------------------------------------------------------------*/
8968 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8969 /*-----------------------------------------------------------------*/
8970 static void genPagedPointerSet (operand *right,
8979 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8981 retype= getSpec(operandType(right));
8983 pic16_aopOp(result,ic,FALSE);
8985 /* if the value is already in a pointer register
8986 then don't need anything more */
8987 if (!AOP_INPREG(AOP(result))) {
8988 /* otherwise get a free pointer register */
8990 preg = getFreePtr(ic,&aop,FALSE);
8991 pic16_emitcode("mov","%s,%s",
8993 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8994 rname = preg->name ;
8996 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8998 pic16_freeAsmop(result,NULL,ic,TRUE);
8999 pic16_aopOp (right,ic,FALSE);
9001 /* if bitfield then unpack the bits */
9002 if (IS_BITVAR(retype))
9003 genPackBits (retype,right,rname,PPOINTER);
9005 /* we have can just get the values */
9006 int size = AOP_SIZE(right);
9010 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
9013 pic16_emitcode("movx","@%s,a",rname);
9016 pic16_emitcode("inc","%s",rname);
9022 /* now some housekeeping stuff */
9024 /* we had to allocate for this iCode */
9025 pic16_freeAsmop(NULL,aop,ic,TRUE);
9027 /* we did not allocate which means left
9028 already in a pointer register, then
9029 if size > 0 && this could be used again
9030 we have to point it back to where it
9032 if (AOP_SIZE(right) > 1 &&
9033 !OP_SYMBOL(result)->remat &&
9034 ( OP_SYMBOL(result)->liveTo > ic->seq ||
9036 int size = AOP_SIZE(right) - 1;
9038 pic16_emitcode("dec","%s",rname);
9043 pic16_freeAsmop(right,NULL,ic,TRUE);
9048 /*-----------------------------------------------------------------*/
9049 /* genFarPointerSet - set value from far space */
9050 /*-----------------------------------------------------------------*/
9051 static void genFarPointerSet (operand *right,
9052 operand *result, iCode *ic)
9055 sym_link *retype = getSpec(operandType(right));
9057 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9058 pic16_aopOp(result,ic,FALSE);
9060 /* if the operand is already in dptr
9061 then we do nothing else we move the value to dptr */
9062 if (AOP_TYPE(result) != AOP_STR) {
9063 /* if this is remateriazable */
9064 if (AOP_TYPE(result) == AOP_IMMD)
9065 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9066 else { /* we need to get it byte by byte */
9067 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
9068 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
9069 if (options.model == MODEL_FLAT24)
9071 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
9075 /* so dptr know contains the address */
9076 pic16_freeAsmop(result,NULL,ic,TRUE);
9077 pic16_aopOp(right,ic,FALSE);
9079 /* if bit then unpack */
9080 if (IS_BITVAR(retype))
9081 genPackBits(retype,right,"dptr",FPOINTER);
9083 size = AOP_SIZE(right);
9087 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9089 pic16_emitcode("movx","@dptr,a");
9091 pic16_emitcode("inc","dptr");
9095 pic16_freeAsmop(right,NULL,ic,TRUE);
9098 /*-----------------------------------------------------------------*/
9099 /* genGenPointerSet - set value from generic pointer space */
9100 /*-----------------------------------------------------------------*/
9101 static void genGenPointerSet (operand *right,
9102 operand *result, iCode *ic)
9105 sym_link *retype = getSpec(operandType(right));
9107 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9109 pic16_aopOp(result,ic,FALSE);
9110 pic16_aopOp(right,ic,FALSE);
9111 size = AOP_SIZE(right);
9113 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9115 /* if the operand is already in dptr
9116 then we do nothing else we move the value to dptr */
9117 if (AOP_TYPE(result) != AOP_STR) {
9118 /* if this is remateriazable */
9119 if (AOP_TYPE(result) == AOP_IMMD) {
9120 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9121 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9123 else { /* we need to get it byte by byte */
9124 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9125 size = AOP_SIZE(right);
9128 /* hack hack! see if this the FSR. If so don't load W */
9129 if(AOP_TYPE(right) != AOP_ACC) {
9131 // pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(result), pic16_popCopyReg(&pic16_pc_fsr0), 0));
9133 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9134 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9136 if(AOP_SIZE(result) > 1) {
9137 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9138 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9139 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9144 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9146 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9147 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9151 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9152 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9155 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9162 if(aopIdx(AOP(result),0) != 4) {
9164 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9168 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9173 /* so dptr know contains the address */
9176 /* if bit then unpack */
9177 if (IS_BITVAR(retype))
9178 genPackBits(retype,right,"dptr",GPOINTER);
9180 size = AOP_SIZE(right);
9183 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9187 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9188 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9190 if (AOP_TYPE(right) == AOP_LIT)
9191 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9193 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9195 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9202 pic16_freeAsmop(right,NULL,ic,TRUE);
9203 pic16_freeAsmop(result,NULL,ic,TRUE);
9206 /*-----------------------------------------------------------------*/
9207 /* genPointerSet - stores the value into a pointer location */
9208 /*-----------------------------------------------------------------*/
9209 static void genPointerSet (iCode *ic)
9211 operand *right, *result ;
9212 sym_link *type, *etype;
9215 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9217 right = IC_RIGHT(ic);
9218 result = IC_RESULT(ic) ;
9220 /* depending on the type of pointer we need to
9221 move it to the correct pointer register */
9222 type = operandType(result);
9223 etype = getSpec(type);
9224 /* if left is of type of pointer then it is simple */
9225 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9226 p_type = DCL_TYPE(type);
9229 /* we have to go by the storage class */
9230 p_type = PTR_TYPE(SPEC_OCLS(etype));
9232 /* if (SPEC_OCLS(etype)->codesp ) { */
9233 /* p_type = CPOINTER ; */
9236 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9237 /* p_type = FPOINTER ; */
9239 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9240 /* p_type = PPOINTER ; */
9242 /* if (SPEC_OCLS(etype) == idata ) */
9243 /* p_type = IPOINTER ; */
9245 /* p_type = POINTER ; */
9248 /* now that we have the pointer type we assign
9249 the pointer values */
9254 genNearPointerSet (right,result,ic);
9258 genPagedPointerSet (right,result,ic);
9262 genFarPointerSet (right,result,ic);
9266 genGenPointerSet (right,result,ic);
9270 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9271 "genPointerSet: illegal pointer type");
9275 /*-----------------------------------------------------------------*/
9276 /* genIfx - generate code for Ifx statement */
9277 /*-----------------------------------------------------------------*/
9278 static void genIfx (iCode *ic, iCode *popIc)
9280 operand *cond = IC_COND(ic);
9283 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9285 pic16_aopOp(cond,ic,FALSE);
9287 /* get the value into acc */
9288 if (AOP_TYPE(cond) != AOP_CRY)
9289 pic16_toBoolean(cond);
9292 /* the result is now in the accumulator */
9293 pic16_freeAsmop(cond,NULL,ic,TRUE);
9295 /* if there was something to be popped then do it */
9299 /* if the condition is a bit variable */
9300 if (isbit && IS_ITEMP(cond) &&
9302 genIfxJump(ic,SPIL_LOC(cond)->rname);
9303 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9306 if (isbit && !IS_ITEMP(cond))
9307 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9315 /*-----------------------------------------------------------------*/
9316 /* genAddrOf - generates code for address of */
9317 /*-----------------------------------------------------------------*/
9319 static void genAddrOf (iCode *ic)
9321 operand *right, *result, *left;
9324 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9327 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9329 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9330 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9331 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9333 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9335 size = AOP_SIZE(IC_RESULT(ic));
9340 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9341 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9346 pic16_freeAsmop(left,NULL,ic,FALSE);
9347 pic16_freeAsmop(result,NULL,ic,TRUE);
9351 #else /* new genAddrOf */
9353 static void genAddrOf (iCode *ic)
9355 operand *result, *left;
9357 symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
9358 pCodeOp *pcop0, *pcop1;
9360 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9362 pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE);
9363 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9365 sym = OP_SYMBOL( left );
9367 size = AOP_SIZE(IC_RESULT(ic));
9369 /* Assume that what we want the address of is in direct addressing space
9370 * since there is no stack on the PIC, yet! -- VR */
9372 pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, 0));
9373 pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, 0));
9375 pcop0 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
9376 PCOI(pcop0)->offset = 0;
9377 PCOI(pcop0)->index = 0;
9378 pcop1 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
9379 PCOI(pcop1)->offset = 1;
9380 PCOI(pcop1)->index = 0;
9384 pic16_emitpcode(POC_MOVLW, pcop0);
9385 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9386 pic16_emitpcode(POC_MOVLW, pcop1);
9387 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9389 pic16_emitpcode(POC_MOVLW, pcop0);
9390 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9393 pic16_freeAsmop(result,NULL,ic,TRUE);
9394 pic16_freeAsmop(left, NULL, ic, FALSE);
9397 #endif /* new genAddrOf */
9400 /*-----------------------------------------------------------------*/
9401 /* genFarFarAssign - assignment when both are in far space */
9402 /*-----------------------------------------------------------------*/
9403 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9405 int size = AOP_SIZE(right);
9408 /* first push the right side on to the stack */
9410 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9412 pic16_emitcode ("push","acc");
9415 pic16_freeAsmop(right,NULL,ic,FALSE);
9416 /* now assign DPTR to result */
9417 pic16_aopOp(result,ic,FALSE);
9418 size = AOP_SIZE(result);
9420 pic16_emitcode ("pop","acc");
9421 pic16_aopPut(AOP(result),"a",--offset);
9423 pic16_freeAsmop(result,NULL,ic,FALSE);
9428 /*-----------------------------------------------------------------*/
9429 /* genAssign - generate code for assignment */
9430 /*-----------------------------------------------------------------*/
9431 static void genAssign (iCode *ic)
9433 operand *result, *right;
9434 int size, offset,know_W;
9435 unsigned long lit = 0L;
9437 result = IC_RESULT(ic);
9438 right = IC_RIGHT(ic) ;
9440 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9442 /* if they are the same */
9443 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9446 pic16_aopOp(right,ic,FALSE);
9447 pic16_aopOp(result,ic,TRUE);
9449 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9451 /* if they are the same registers */
9452 if (pic16_sameRegs(AOP(right),AOP(result)))
9455 /* if the result is a bit */
9456 if (AOP_TYPE(result) == AOP_CRY) {
9457 /* if the right size is a literal then
9458 we know what the value is */
9459 if (AOP_TYPE(right) == AOP_LIT) {
9461 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9462 pic16_popGet(AOP(result),0));
9464 if (((int) operandLitValue(right)))
9465 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9466 AOP(result)->aopu.aop_dir,
9467 AOP(result)->aopu.aop_dir);
9469 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9470 AOP(result)->aopu.aop_dir,
9471 AOP(result)->aopu.aop_dir);
9475 /* the right is also a bit variable */
9476 if (AOP_TYPE(right) == AOP_CRY) {
9477 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9478 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9479 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9481 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9482 AOP(result)->aopu.aop_dir,
9483 AOP(result)->aopu.aop_dir);
9484 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9485 AOP(right)->aopu.aop_dir,
9486 AOP(right)->aopu.aop_dir);
9487 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9488 AOP(result)->aopu.aop_dir,
9489 AOP(result)->aopu.aop_dir);
9494 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9495 pic16_toBoolean(right);
9497 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9498 //pic16_aopPut(AOP(result),"a",0);
9502 /* bit variables done */
9504 size = AOP_SIZE(result);
9506 if(AOP_TYPE(right) == AOP_LIT)
9507 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9509 /* VR - What is this?! */
9510 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9511 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9512 if(aopIdx(AOP(result),0) == 4) {
9513 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9514 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9515 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9518 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9523 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9524 if(AOP_TYPE(right) == AOP_LIT) {
9526 if(know_W != (lit&0xff))
9527 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9529 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9531 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9535 } else if (AOP_TYPE(right) == AOP_CRY) {
9536 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9538 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9539 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9542 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9545 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9546 normally should work, but mind that the W register live range
9547 is not checked, so if the code generator assumes that the W
9548 is already loaded after such a pair, wrong code will be generated.
9550 Checking the live range is the next step.
9551 This is experimental code yet and has not been fully tested yet.
9552 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9553 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9555 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9557 /* This is the old code, which is assumed(?!) that works fine(!?) */
9559 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9560 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9569 pic16_freeAsmop (right,NULL,ic,FALSE);
9570 pic16_freeAsmop (result,NULL,ic,TRUE);
9573 /*-----------------------------------------------------------------*/
9574 /* genJumpTab - generates code for jump table */
9575 /*-----------------------------------------------------------------*/
9576 static void genJumpTab (iCode *ic)
9581 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9583 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9584 /* get the condition into accumulator */
9585 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9587 /* multiply by three */
9588 pic16_emitcode("add","a,acc");
9589 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9591 jtab = newiTempLabel(NULL);
9592 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9593 pic16_emitcode("jmp","@a+dptr");
9594 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9596 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9597 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9599 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9600 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9601 pic16_emitpLabel(jtab->key);
9603 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9605 /* now generate the jump labels */
9606 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9607 jtab = setNextItem(IC_JTLABELS(ic))) {
9608 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9609 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9615 /*-----------------------------------------------------------------*/
9616 /* genMixedOperation - gen code for operators between mixed types */
9617 /*-----------------------------------------------------------------*/
9619 TSD - Written for the PIC port - but this unfortunately is buggy.
9620 This routine is good in that it is able to efficiently promote
9621 types to different (larger) sizes. Unfortunately, the temporary
9622 variables that are optimized out by this routine are sometimes
9623 used in other places. So until I know how to really parse the
9624 iCode tree, I'm going to not be using this routine :(.
9626 static int genMixedOperation (iCode *ic)
9629 operand *result = IC_RESULT(ic);
9630 sym_link *ctype = operandType(IC_LEFT(ic));
9631 operand *right = IC_RIGHT(ic);
9637 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9639 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9645 nextright = IC_RIGHT(nextic);
9646 nextleft = IC_LEFT(nextic);
9647 nextresult = IC_RESULT(nextic);
9649 pic16_aopOp(right,ic,FALSE);
9650 pic16_aopOp(result,ic,FALSE);
9651 pic16_aopOp(nextright, nextic, FALSE);
9652 pic16_aopOp(nextleft, nextic, FALSE);
9653 pic16_aopOp(nextresult, nextic, FALSE);
9655 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9661 pic16_emitcode(";remove right +","");
9663 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9669 pic16_emitcode(";remove left +","");
9673 big = AOP_SIZE(nextleft);
9674 small = AOP_SIZE(nextright);
9676 switch(nextic->op) {
9679 pic16_emitcode(";optimize a +","");
9680 /* if unsigned or not an integral type */
9681 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9682 pic16_emitcode(";add a bit to something","");
9685 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9687 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9688 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9689 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9691 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9699 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9700 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9701 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9704 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9706 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9707 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9708 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9709 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9710 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9713 pic16_emitcode("rlf","known_zero,w");
9720 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9721 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9722 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9724 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9734 pic16_freeAsmop(right,NULL,ic,TRUE);
9735 pic16_freeAsmop(result,NULL,ic,TRUE);
9736 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9737 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9739 nextic->generated = 1;
9746 /*-----------------------------------------------------------------*/
9747 /* genCast - gen code for casting */
9748 /*-----------------------------------------------------------------*/
9749 static void genCast (iCode *ic)
9751 operand *result = IC_RESULT(ic);
9752 sym_link *ctype = operandType(IC_LEFT(ic));
9753 sym_link *rtype = operandType(IC_RIGHT(ic));
9754 operand *right = IC_RIGHT(ic);
9757 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9758 /* if they are equivalent then do nothing */
9759 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9762 pic16_aopOp(right,ic,FALSE) ;
9763 pic16_aopOp(result,ic,FALSE);
9765 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9767 /* if the result is a bit */
9768 if (AOP_TYPE(result) == AOP_CRY) {
9769 /* if the right size is a literal then
9770 we know what the value is */
9771 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9772 if (AOP_TYPE(right) == AOP_LIT) {
9774 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9775 pic16_popGet(AOP(result),0));
9777 if (((int) operandLitValue(right)))
9778 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9779 AOP(result)->aopu.aop_dir,
9780 AOP(result)->aopu.aop_dir);
9782 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9783 AOP(result)->aopu.aop_dir,
9784 AOP(result)->aopu.aop_dir);
9789 /* the right is also a bit variable */
9790 if (AOP_TYPE(right) == AOP_CRY) {
9793 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9795 pic16_emitcode("clrc","");
9796 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9797 AOP(right)->aopu.aop_dir,
9798 AOP(right)->aopu.aop_dir);
9799 pic16_aopPut(AOP(result),"c",0);
9804 if (AOP_TYPE(right) == AOP_REG) {
9805 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9806 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9807 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9809 pic16_toBoolean(right);
9810 pic16_aopPut(AOP(result),"a",0);
9814 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9816 size = AOP_SIZE(result);
9818 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9820 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9821 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9822 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9825 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9830 /* if they are the same size : or less */
9831 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9833 /* if they are in the same place */
9834 if (pic16_sameRegs(AOP(right),AOP(result)))
9837 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9839 if (IS_PTR_CONST(rtype))
9841 if (IS_CODEPTR(rtype))
9843 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9845 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9847 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
9849 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9851 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9852 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9853 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9854 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9855 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9856 if(AOP_SIZE(result) <2)
9857 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9861 /* if they in different places then copy */
9862 size = AOP_SIZE(result);
9865 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9866 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9868 //pic16_aopPut(AOP(result),
9869 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9879 /* if the result is of type pointer */
9880 if (IS_PTR(ctype)) {
9883 sym_link *type = operandType(right);
9884 sym_link *etype = getSpec(type);
9885 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9887 /* pointer to generic pointer */
9888 if (IS_GENPTR(ctype)) {
9892 p_type = DCL_TYPE(type);
9894 /* we have to go by the storage class */
9895 p_type = PTR_TYPE(SPEC_OCLS(etype));
9897 /* if (SPEC_OCLS(etype)->codesp ) */
9898 /* p_type = CPOINTER ; */
9900 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9901 /* p_type = FPOINTER ; */
9903 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9904 /* p_type = PPOINTER; */
9906 /* if (SPEC_OCLS(etype) == idata ) */
9907 /* p_type = IPOINTER ; */
9909 /* p_type = POINTER ; */
9912 /* the first two bytes are known */
9913 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9914 size = GPTRSIZE - 1;
9917 if(offset < AOP_SIZE(right)) {
9918 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9919 if ((AOP_TYPE(right) == AOP_PCODE) &&
9920 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9921 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9922 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9924 pic16_aopPut(AOP(result),
9925 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9929 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9932 /* the last byte depending on type */
9936 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9939 pic16_emitcode(";BUG!? ","%d",__LINE__);
9943 pic16_emitcode(";BUG!? ","%d",__LINE__);
9947 pic16_emitcode(";BUG!? ","%d",__LINE__);
9952 /* this should never happen */
9953 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9954 "got unknown pointer type");
9957 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9961 /* just copy the pointers */
9962 size = AOP_SIZE(result);
9965 pic16_aopPut(AOP(result),
9966 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9975 /* so we now know that the size of destination is greater
9976 than the size of the source.
9977 Now, if the next iCode is an operator then we might be
9978 able to optimize the operation without performing a cast.
9980 if(genMixedOperation(ic))
9983 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9985 /* we move to result for the size of source */
9986 size = AOP_SIZE(right);
9989 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9990 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9994 /* now depending on the sign of the destination */
9995 size = AOP_SIZE(result) - AOP_SIZE(right);
9996 /* if unsigned or not an integral type */
9997 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9999 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
10001 /* we need to extend the sign :{ */
10004 /* Save one instruction of casting char to int */
10005 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
10006 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10007 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
10009 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
10012 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
10014 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
10016 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
10019 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
10024 pic16_freeAsmop(right,NULL,ic,TRUE);
10025 pic16_freeAsmop(result,NULL,ic,TRUE);
10029 /*-----------------------------------------------------------------*/
10030 /* genDjnz - generate decrement & jump if not zero instrucion */
10031 /*-----------------------------------------------------------------*/
10032 static int genDjnz (iCode *ic, iCode *ifx)
10034 symbol *lbl, *lbl1;
10035 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10040 /* if the if condition has a false label
10041 then we cannot save */
10045 /* if the minus is not of the form
10047 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
10048 !IS_OP_LITERAL(IC_RIGHT(ic)))
10051 if (operandLitValue(IC_RIGHT(ic)) != 1)
10054 /* if the size of this greater than one then no
10056 if (getSize(operandType(IC_RESULT(ic))) > 1)
10059 /* otherwise we can save BIG */
10060 lbl = newiTempLabel(NULL);
10061 lbl1= newiTempLabel(NULL);
10063 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10065 if (IS_AOP_PREG(IC_RESULT(ic))) {
10066 pic16_emitcode("dec","%s",
10067 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10068 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10069 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
10073 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
10074 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
10076 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
10077 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
10080 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
10081 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
10082 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
10083 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
10086 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10087 ifx->generated = 1;
10091 /*-----------------------------------------------------------------*/
10092 /* genReceive - generate code for a receive iCode */
10093 /*-----------------------------------------------------------------*/
10094 static void genReceive (iCode *ic)
10096 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
10098 if (isOperandInFarSpace(IC_RESULT(ic)) &&
10099 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
10100 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
10102 int size = getSize(operandType(IC_RESULT(ic)));
10103 int offset = pic16_fReturnSizePic - size;
10106 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
10107 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
10111 DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__);
10113 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10114 size = AOP_SIZE(IC_RESULT(ic));
10117 pic16_emitcode ("pop","acc");
10118 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
10121 DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__);
10124 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
10126 assignResultValue(IC_RESULT(ic));
10129 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
10132 /*-----------------------------------------------------------------*/
10133 /* genDummyRead - generate code for dummy read of volatiles */
10134 /*-----------------------------------------------------------------*/
10136 genDummyRead (iCode * ic)
10138 pic16_emitcode ("; genDummyRead","");
10139 pic16_emitcode ("; not implemented","");
10144 /*-----------------------------------------------------------------*/
10145 /* genpic16Code - generate code for pic16 based controllers */
10146 /*-----------------------------------------------------------------*/
10148 * At this point, ralloc.c has gone through the iCode and attempted
10149 * to optimize in a way suitable for a PIC. Now we've got to generate
10150 * PIC instructions that correspond to the iCode.
10152 * Once the instructions are generated, we'll pass through both the
10153 * peep hole optimizer and the pCode optimizer.
10154 *-----------------------------------------------------------------*/
10156 void genpic16Code (iCode *lic)
10161 lineHead = lineCurr = NULL;
10163 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
10164 pic16_addpBlock(pb);
10167 /* if debug information required */
10168 if (options.debug && currFunc) {
10170 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
10172 if (IS_STATIC(currFunc->etype)) {
10173 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
10174 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
10176 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
10177 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10186 for (ic = lic ; ic ; ic = ic->next ) {
10188 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10189 // DEBUGpic16_emitcode("; VR", "");
10190 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10191 if ( cln != ic->lineno ) {
10192 if ( options.debug ) {
10194 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10195 FileBaseName(ic->filename),ic->lineno,
10196 ic->level,ic->block);
10199 pic16_addpCode2pBlock(pb,
10200 pic16_newpCodeCSource(ic->lineno,
10202 printCLine(ic->filename, ic->lineno)));
10206 /* if the result is marked as
10207 spilt and rematerializable or code for
10208 this has already been generated then
10210 if (resultRemat(ic) || ic->generated )
10213 /* depending on the operation */
10232 /* IPOP happens only when trying to restore a
10233 spilt live range, if there is an ifx statement
10234 following this pop then the if statement might
10235 be using some of the registers being popped which
10236 would destroy the contents of the register so
10237 we need to check for this condition and handle it */
10239 ic->next->op == IFX &&
10240 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10241 genIfx (ic->next,ic);
10259 genEndFunction (ic);
10275 pic16_genPlus (ic) ;
10279 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10280 pic16_genMinus (ic);
10296 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10300 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10307 /* note these two are xlated by algebraic equivalence
10308 during parsing SDCC.y */
10309 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10310 "got '>=' or '<=' shouldn't have come here");
10314 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10326 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10330 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10334 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10358 genRightShift (ic);
10361 case GET_VALUE_AT_ADDRESS:
10366 if (POINTER_SET(ic))
10393 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x\tSEND",ic->op, ic->op);
10395 addSet(&_G.sendSet,ic);
10398 case DUMMY_READ_VOLATILE:
10408 /* now we are ready to call the
10409 peep hole optimizer */
10410 if (!options.nopeep) {
10411 peepHole (&lineHead);
10413 /* now do the actual printing */
10414 printLine (lineHead,codeOutFile);
10417 DFPRINTF((stderr,"printing pBlock\n\n"));
10418 pic16_printpBlock(stdout,pb);