1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic16
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
8 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them. Help stamp out software-hoarding!
29 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
30 Made everything static
31 -------------------------------------------------------------------------*/
37 #include "SDCCglobl.h"
41 #include "SDCCpeeph.h"
47 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
49 void pic16_genMult8X8_8 (operand *, operand *,operand *);
50 pCode *pic16_AssembleLine(char *line);
51 extern void pic16_printpBlock(FILE *of, pBlock *pb);
52 static asmop *newAsmop (short type);
53 static pCodeOp *popRegFromString(char *str, int size, int offset);
54 static void mov2w (asmop *aop, int offset);
55 static int aopIdx (asmop *aop, int offset);
57 static int labelOffset=0;
58 extern int pic16_debug_verbose;
59 static int optimized_for_speed = 0;
64 int options_no_movff = 1;
66 /* max_key keeps track of the largest label number used in
67 a function. This is then used to adjust the label offset
68 for the next function.
71 static int GpsuedoStkPtr=0;
73 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
74 unsigned int pic16aopLiteral (value *val, int offset);
75 const char *pic16_AopType(short type);
76 static iCode *ifxForOp ( operand *op, iCode *ic );
78 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
80 /* this is the down and dirty file with all kinds of
81 kludgy & hacky stuff. This is what it is all about
82 CODE GENERATION for a specific MCU . some of the
83 routines may be reusable, will have to see */
85 static char *zero = "#0x00";
86 static char *one = "#0x01";
87 static char *spname = "sp";
89 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic16;
94 static char *accUse[] = {"a","b"};
96 //static short rbank = -1;
108 /* Resolved ifx structure. This structure stores information
109 about an iCode ifx that makes it easier to generate code.
111 typedef struct resolvedIfx {
112 symbol *lbl; /* pointer to a label */
113 int condition; /* true or false ifx */
114 int generated; /* set true when the code associated with the ifx
118 extern int pic16_ptrRegReq ;
119 extern int pic16_nRegs;
120 extern FILE *codeOutFile;
121 static void saverbank (int, iCode *,bool);
123 static lineNode *lineHead = NULL;
124 static lineNode *lineCurr = NULL;
126 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
127 0xE0, 0xC0, 0x80, 0x00};
128 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
129 0x07, 0x03, 0x01, 0x00};
133 /*-----------------------------------------------------------------*/
134 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
135 /* exponent of 2 is returned, otherwise -1 is */
137 /* note that this is similar to the function `powof2' in SDCCsymt */
141 /*-----------------------------------------------------------------*/
142 static int my_powof2 (unsigned long num)
145 if( (num & (num-1)) == 0) {
158 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
161 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
163 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
164 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
166 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
168 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169 ((result) ? AOP_SIZE(result) : 0));
173 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
176 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
178 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
179 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
180 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
181 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
182 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
183 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
187 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
190 char lb[INITIAL_INLINEASM];
193 if(!pic16_debug_verbose)
200 sprintf(lb,"%s\t",inst);
202 sprintf(lb,"%s",inst);
203 vsprintf(lb+(strlen(lb)),fmt,ap);
207 while (isspace(*lbp)) lbp++;
210 lineCurr = (lineCurr ?
211 connectLine(lineCurr,newLineNode(lb)) :
212 (lineHead = newLineNode(lb)));
213 lineCurr->isInline = _G.inLine;
214 lineCurr->isDebug = _G.debugLine;
216 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
219 // fprintf(stderr, "%s\n", lb);
223 void pic16_emitpLabel(int key)
225 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
228 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
232 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
234 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
236 // fprintf(stderr, "%s\n", pcop->name);
239 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
242 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
246 /*-----------------------------------------------------------------*/
247 /* pic16_emitcode - writes the code into a file : for now it is simple */
248 /*-----------------------------------------------------------------*/
249 void pic16_emitcode (char *inst,char *fmt, ...)
252 char lb[INITIAL_INLINEASM];
259 sprintf(lb,"%s\t",inst);
261 sprintf(lb,"%s",inst);
262 vsprintf(lb+(strlen(lb)),fmt,ap);
266 while (isspace(*lbp)) lbp++;
269 lineCurr = (lineCurr ?
270 connectLine(lineCurr,newLineNode(lb)) :
271 (lineHead = newLineNode(lb)));
272 lineCurr->isInline = _G.inLine;
273 lineCurr->isDebug = _G.debugLine;
275 // VR fprintf(stderr, "lb = <%s>\n", lbp);
277 if(pic16_debug_verbose)
278 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
289 bool r0iu = FALSE , r1iu = FALSE;
290 bool r0ou = FALSE , r1ou = FALSE;
292 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
294 /* the logic: if r0 & r1 used in the instruction
295 then we are in trouble otherwise */
297 /* first check if r0 & r1 are used by this
298 instruction, in which case we are in trouble */
299 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
300 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
305 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
306 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
308 /* if no usage of r0 then return it */
309 if (!r0iu && !r0ou) {
310 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
311 (*aopp)->type = AOP_R0;
313 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
316 /* if no usage of r1 then return it */
317 if (!r1iu && !r1ou) {
318 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
319 (*aopp)->type = AOP_R1;
321 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
324 /* now we know they both have usage */
325 /* if r0 not used in this instruction */
327 /* push it if not already pushed */
329 //pic16_emitcode ("push","%s",
330 // pic16_regWithIdx(R0_IDX)->dname);
334 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
335 (*aopp)->type = AOP_R0;
337 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
340 /* if r1 not used then */
343 /* push it if not already pushed */
345 //pic16_emitcode ("push","%s",
346 // pic16_regWithIdx(R1_IDX)->dname);
350 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
351 (*aopp)->type = AOP_R1;
352 return pic16_regWithIdx(R1_IDX);
356 /* I said end of world but not quite end of world yet */
357 /* if this is a result then we can push it on the stack*/
359 (*aopp)->type = AOP_STK;
363 /* other wise this is true end of the world */
364 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
365 "getFreePtr should never reach here");
369 /*-----------------------------------------------------------------*/
370 /* newAsmop - creates a new asmOp */
371 /*-----------------------------------------------------------------*/
372 static asmop *newAsmop (short type)
376 aop = Safe_calloc(1,sizeof(asmop));
381 static void genSetDPTR(int n)
385 pic16_emitcode(";", "Select standard DPTR");
386 pic16_emitcode("mov", "dps, #0x00");
390 pic16_emitcode(";", "Select alternate DPTR");
391 pic16_emitcode("mov", "dps, #0x01");
395 /*-----------------------------------------------------------------*/
396 /* resolveIfx - converts an iCode ifx into a form more useful for */
397 /* generating code */
398 /*-----------------------------------------------------------------*/
399 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
404 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
406 resIfx->condition = 1; /* assume that the ifx is true */
407 resIfx->generated = 0; /* indicate that the ifx has not been used */
410 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
412 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
413 __FUNCTION__,__LINE__,resIfx->lbl->key);
417 resIfx->lbl = IC_TRUE(ifx);
419 resIfx->lbl = IC_FALSE(ifx);
420 resIfx->condition = 0;
424 DEBUGpic16_emitcode("; ***","ifx true is non-null");
426 DEBUGpic16_emitcode("; ***","ifx false is non-null");
430 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
433 /*-----------------------------------------------------------------*/
434 /* pointerCode - returns the code for a pointer type */
435 /*-----------------------------------------------------------------*/
436 static int pointerCode (sym_link *etype)
439 return PTR_TYPE(SPEC_OCLS(etype));
443 /*-----------------------------------------------------------------*/
444 /* aopForSym - for a true symbol */
445 /*-----------------------------------------------------------------*/
446 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
449 memmap *space= SPEC_OCLS(sym->etype);
451 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
452 /* if already has one */
454 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
458 /* assign depending on the storage class */
459 /* if it is on the stack or indirectly addressable */
460 /* space we need to assign either r0 or r1 to it */
461 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
462 sym->aop = aop = newAsmop(0);
463 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
464 aop->size = getSize(sym->type);
466 /* now assign the address of the variable to
467 the pointer register */
468 if (aop->type != AOP_STK) {
472 pic16_emitcode("push","acc");
474 pic16_emitcode("mov","a,_bp");
475 pic16_emitcode("add","a,#0x%02x",
477 ((char)(sym->stack - _G.nRegsSaved )) :
478 ((char)sym->stack)) & 0xff);
479 pic16_emitcode("mov","%s,a",
480 aop->aopu.aop_ptr->name);
483 pic16_emitcode("pop","acc");
485 pic16_emitcode("mov","%s,#%s",
486 aop->aopu.aop_ptr->name,
488 aop->paged = space->paged;
490 aop->aopu.aop_stk = sym->stack;
494 if (sym->onStack && options.stack10bit)
496 /* It's on the 10 bit stack, which is located in
500 //DEBUGpic16_emitcode(";","%d",__LINE__);
503 pic16_emitcode("push","acc");
505 pic16_emitcode("mov","a,_bp");
506 pic16_emitcode("add","a,#0x%02x",
508 ((char)(sym->stack - _G.nRegsSaved )) :
509 ((char)sym->stack)) & 0xff);
512 pic16_emitcode ("mov","dpx1,#0x40");
513 pic16_emitcode ("mov","dph1,#0x00");
514 pic16_emitcode ("mov","dpl1, a");
518 pic16_emitcode("pop","acc");
520 sym->aop = aop = newAsmop(AOP_DPTR2);
521 aop->size = getSize(sym->type);
525 //DEBUGpic16_emitcode(";","%d",__LINE__);
526 /* if in bit space */
527 if (IN_BITSPACE(space)) {
528 sym->aop = aop = newAsmop (AOP_CRY);
529 aop->aopu.aop_dir = sym->rname ;
530 aop->size = getSize(sym->type);
531 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
534 /* if it is in direct space */
535 if (IN_DIRSPACE(space)) {
536 sym->aop = aop = newAsmop (AOP_DIR);
537 aop->aopu.aop_dir = sym->rname ;
538 aop->size = getSize(sym->type);
539 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
543 /* special case for a function */
544 if (IS_FUNC(sym->type)) {
545 sym->aop = aop = newAsmop(AOP_IMMD);
546 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
547 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
548 strcpy(aop->aopu.aop_immd,sym->rname);
549 aop->size = FPTRSIZE;
550 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
555 /* only remaining is far space */
556 /* in which case DPTR gets the address */
557 sym->aop = aop = newAsmop(AOP_PCODE);
559 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
560 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
561 PCOI(aop->aopu.pcop)->index = 0;
563 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
564 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
566 pic16_allocDirReg (IC_LEFT(ic));
568 aop->size = FPTRSIZE;
570 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
571 sym->aop = aop = newAsmop(AOP_DPTR);
572 pic16_emitcode ("mov","dptr,#%s", sym->rname);
573 aop->size = getSize(sym->type);
575 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
578 /* if it is in code space */
579 if (IN_CODESPACE(space))
585 /*-----------------------------------------------------------------*/
586 /* aopForRemat - rematerialzes an object */
587 /*-----------------------------------------------------------------*/
588 static asmop *aopForRemat (operand *op) // x symbol *sym)
590 symbol *sym = OP_SYMBOL(op);
592 asmop *aop = newAsmop(AOP_PCODE);
596 ic = sym->rematiCode;
598 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
599 if(IS_OP_POINTER(op)) {
600 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
604 val += (int) operandLitValue(IC_RIGHT(ic));
605 } else if (ic->op == '-') {
606 val -= (int) operandLitValue(IC_RIGHT(ic));
610 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
613 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
614 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
615 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
616 PCOI(aop->aopu.pcop)->index = val;
618 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
619 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
620 val, IS_PTR_CONST(operandType(op)));
622 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
624 pic16_allocDirReg (IC_LEFT(ic));
629 static int aopIdx (asmop *aop, int offset)
634 if(aop->type != AOP_REG)
637 return aop->aopu.aop_reg[offset]->rIdx;
640 /*-----------------------------------------------------------------*/
641 /* regsInCommon - two operands have some registers in common */
642 /*-----------------------------------------------------------------*/
643 static bool regsInCommon (operand *op1, operand *op2)
648 /* if they have registers in common */
649 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
652 sym1 = OP_SYMBOL(op1);
653 sym2 = OP_SYMBOL(op2);
655 if (sym1->nRegs == 0 || sym2->nRegs == 0)
658 for (i = 0 ; i < sym1->nRegs ; i++) {
663 for (j = 0 ; j < sym2->nRegs ;j++ ) {
667 if (sym2->regs[j] == sym1->regs[i])
675 /*-----------------------------------------------------------------*/
676 /* operandsEqu - equivalent */
677 /*-----------------------------------------------------------------*/
678 static bool operandsEqu ( operand *op1, operand *op2)
682 /* if they not symbols */
683 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
686 sym1 = OP_SYMBOL(op1);
687 sym2 = OP_SYMBOL(op2);
689 /* if both are itemps & one is spilt
690 and the other is not then false */
691 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
692 sym1->isspilt != sym2->isspilt )
695 /* if they are the same */
699 if (strcmp(sym1->rname,sym2->rname) == 0)
703 /* if left is a tmp & right is not */
707 (sym1->usl.spillLoc == sym2))
714 (sym2->usl.spillLoc == sym1))
720 /*-----------------------------------------------------------------*/
721 /* pic16_sameRegs - two asmops have the same registers */
722 /*-----------------------------------------------------------------*/
723 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
730 if (aop1->type != AOP_REG ||
731 aop2->type != AOP_REG )
734 if (aop1->size != aop2->size )
737 for (i = 0 ; i < aop1->size ; i++ )
738 if (aop1->aopu.aop_reg[i] !=
739 aop2->aopu.aop_reg[i] )
745 /*-----------------------------------------------------------------*/
746 /* pic16_aopOp - allocates an asmop for an operand : */
747 /*-----------------------------------------------------------------*/
748 void pic16_aopOp (operand *op, iCode *ic, bool result)
757 DEBUGpic16_emitcode(";","%d",__LINE__);
758 /* if this a literal */
759 if (IS_OP_LITERAL(op)) {
760 op->aop = aop = newAsmop(AOP_LIT);
761 aop->aopu.aop_lit = op->operand.valOperand;
762 aop->size = getSize(operandType(op));
767 sym_link *type = operandType(op);
768 if(IS_PTR_CONST(type))
769 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
772 /* if already has a asmop then continue */
776 /* if the underlying symbol has a aop */
777 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
778 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
779 op->aop = OP_SYMBOL(op)->aop;
783 /* if this is a true symbol */
784 if (IS_TRUE_SYMOP(op)) {
785 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
786 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
790 /* this is a temporary : this has
796 e) can be a return use only */
800 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
801 /* if the type is a conditional */
802 if (sym->regType == REG_CND) {
803 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
808 /* if it is spilt then two situations
810 b) has a spill location */
811 if (sym->isspilt || sym->nRegs == 0) {
813 DEBUGpic16_emitcode(";","%d",__LINE__);
814 /* rematerialize it NOW */
817 sym->aop = op->aop = aop =
819 aop->size = getSize(sym->type);
820 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
826 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
827 aop->size = getSize(sym->type);
828 for ( i = 0 ; i < 2 ; i++ )
829 aop->aopu.aop_str[i] = accUse[i];
830 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
836 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
837 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
838 //pic16_allocDirReg (IC_LEFT(ic));
839 aop->size = getSize(sym->type);
844 aop = op->aop = sym->aop = newAsmop(AOP_STR);
845 aop->size = getSize(sym->type);
846 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
847 aop->aopu.aop_str[i] = fReturn[i];
849 DEBUGpic16_emitcode(";","%d",__LINE__);
853 /* else spill location */
854 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
855 /* force a new aop if sizes differ */
856 sym->usl.spillLoc->aop = NULL;
858 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
859 __FUNCTION__,__LINE__,
860 sym->usl.spillLoc->rname,
861 sym->rname, sym->usl.spillLoc->offset);
863 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
864 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
865 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
867 sym->usl.spillLoc->offset);
868 aop->size = getSize(sym->type);
874 sym_link *type = operandType(op);
875 if(IS_PTR_CONST(type))
876 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
879 /* must be in a register */
880 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
881 sym->aop = op->aop = aop = newAsmop(AOP_REG);
882 aop->size = sym->nRegs;
883 for ( i = 0 ; i < sym->nRegs ;i++)
884 aop->aopu.aop_reg[i] = sym->regs[i];
887 /*-----------------------------------------------------------------*/
888 /* pic16_freeAsmop - free up the asmop given to an operand */
889 /*----------------------------------------------------------------*/
890 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
907 /* depending on the asmop type only three cases need work AOP_RO
908 , AOP_R1 && AOP_STK */
914 pic16_emitcode ("pop","ar0");
918 bitVectUnSetBit(ic->rUsed,R0_IDX);
924 pic16_emitcode ("pop","ar1");
928 bitVectUnSetBit(ic->rUsed,R1_IDX);
934 int stk = aop->aopu.aop_stk + aop->size;
935 bitVectUnSetBit(ic->rUsed,R0_IDX);
936 bitVectUnSetBit(ic->rUsed,R1_IDX);
938 getFreePtr(ic,&aop,FALSE);
940 if (options.stack10bit)
942 /* I'm not sure what to do here yet... */
945 "*** Warning: probably generating bad code for "
946 "10 bit stack mode.\n");
950 pic16_emitcode ("mov","a,_bp");
951 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
952 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
954 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
958 pic16_emitcode("pop","acc");
959 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
961 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
964 pic16_freeAsmop(op,NULL,ic,TRUE);
966 pic16_emitcode("pop","ar0");
971 pic16_emitcode("pop","ar1");
979 /* all other cases just dealloc */
983 OP_SYMBOL(op)->aop = NULL;
984 /* if the symbol has a spill */
986 SPIL_LOC(op)->aop = NULL;
991 /*-----------------------------------------------------------------*/
992 /* pic16_aopGet - for fetching value of the aop */
993 /*-----------------------------------------------------------------*/
994 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
999 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1000 /* offset is greater than
1002 if (offset > (aop->size - 1) &&
1003 aop->type != AOP_LIT)
1006 /* depending on type */
1007 switch (aop->type) {
1011 DEBUGpic16_emitcode(";","%d",__LINE__);
1012 /* if we need to increment it */
1013 while (offset > aop->coff) {
1014 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1018 while (offset < aop->coff) {
1019 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1023 aop->coff = offset ;
1025 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1026 return (dname ? "acc" : "a");
1028 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1029 rs = Safe_calloc(1,strlen(s)+1);
1035 DEBUGpic16_emitcode(";","%d",__LINE__);
1036 if (aop->type == AOP_DPTR2)
1041 while (offset > aop->coff) {
1042 pic16_emitcode ("inc","dptr");
1046 while (offset < aop->coff) {
1047 pic16_emitcode("lcall","__decdptr");
1053 pic16_emitcode("clr","a");
1054 pic16_emitcode("movc","a,@a+dptr");
1057 pic16_emitcode("movx","a,@dptr");
1060 if (aop->type == AOP_DPTR2)
1065 return (dname ? "acc" : "a");
1070 sprintf (s,"%s",aop->aopu.aop_immd);
1073 sprintf(s,"(%s >> %d)",
1078 aop->aopu.aop_immd);
1079 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1080 rs = Safe_calloc(1,strlen(s)+1);
1086 sprintf(s,"(%s + %d)",
1089 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1091 sprintf(s,"%s",aop->aopu.aop_dir);
1092 rs = Safe_calloc(1,strlen(s)+1);
1098 // return aop->aopu.aop_reg[offset]->dname;
1100 return aop->aopu.aop_reg[offset]->name;
1103 //pic16_emitcode(";","%d",__LINE__);
1104 return aop->aopu.aop_dir;
1107 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1108 return "AOP_accumulator_bug";
1111 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1112 rs = Safe_calloc(1,strlen(s)+1);
1117 aop->coff = offset ;
1118 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1121 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1123 return aop->aopu.aop_str[offset];
1127 pCodeOp *pcop = aop->aopu.pcop;
1128 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1130 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1131 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1132 sprintf(s,"%s", pcop->name);
1134 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1137 rs = Safe_calloc(1,strlen(s)+1);
1143 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1144 "aopget got unsupported aop->type");
1149 /*-----------------------------------------------------------------*/
1150 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1151 /*-----------------------------------------------------------------*/
1152 pCodeOp *pic16_popGetTempReg(void)
1157 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1158 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1159 PCOR(pcop)->r->wasUsed=1;
1160 PCOR(pcop)->r->isFree=0;
1166 /*-----------------------------------------------------------------*/
1167 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1168 /*-----------------------------------------------------------------*/
1169 void pic16_popReleaseTempReg(pCodeOp *pcop)
1172 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1173 PCOR(pcop)->r->isFree = 1;
1176 /*-----------------------------------------------------------------*/
1177 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1178 /*-----------------------------------------------------------------*/
1179 pCodeOp *pic16_popGetLabel(unsigned int key)
1182 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1187 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1190 /*-----------------------------------------------------------------*/
1191 /* pic16_popCopyReg - copy a pcode operator */
1192 /*-----------------------------------------------------------------*/
1193 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1197 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1198 pcor->pcop.type = pc->pcop.type;
1200 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1201 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1203 pcor->pcop.name = NULL;
1206 pcor->rIdx = pc->rIdx;
1209 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1213 /*-----------------------------------------------------------------*/
1214 /* pic16_popGet - asm operator to pcode operator conversion */
1215 /*-----------------------------------------------------------------*/
1216 pCodeOp *pic16_popGetLit(unsigned int lit)
1219 return pic16_newpCodeOpLit(lit);
1223 /*-----------------------------------------------------------------*/
1224 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1229 return pic16_newpCodeOpImmd(name, offset,index, 0);
1233 /*-----------------------------------------------------------------*/
1234 /* pic16_popGet - asm operator to pcode operator conversion */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *pic16_popGetWithString(char *str)
1242 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1246 pcop = pic16_newpCodeOp(str,PO_STR);
1251 /*-----------------------------------------------------------------*/
1252 /* popRegFromString - */
1253 /*-----------------------------------------------------------------*/
1254 static pCodeOp *popRegFromString(char *str, int size, int offset)
1257 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1258 pcop->type = PO_DIR;
1260 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1261 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1266 pcop->name = Safe_calloc(1,strlen(str)+1);
1267 strcpy(pcop->name,str);
1269 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1271 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1272 if(PCOR(pcop)->r == NULL) {
1273 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1276 //fprintf(stderr, "allocating new register -> %s\n", str);
1278 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1280 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1282 PCOR(pcop)->instance = offset;
1287 static pCodeOp *popRegFromIdx(int rIdx)
1291 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1292 __FUNCTION__,__LINE__,rIdx);
1294 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1296 PCOR(pcop)->rIdx = rIdx;
1297 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1298 PCOR(pcop)->r->isFree = 0;
1299 PCOR(pcop)->r->wasUsed = 1;
1301 pcop->type = PCOR(pcop)->r->pc_type;
1307 /*---------------------------------------------------------------------------------*/
1308 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1310 /*---------------------------------------------------------------------------------*/
1311 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1316 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1317 temp = pic16_popGet(aop_dst, offset);
1318 pcop2->pcop2 = temp;
1324 /*-----------------------------------------------------------------*/
1325 /* pic16_popGet - asm operator to pcode operator conversion */
1326 /*-----------------------------------------------------------------*/
1327 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1329 //char *s = buffer ;
1334 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1335 /* offset is greater than
1338 if (offset > (aop->size - 1) &&
1339 aop->type != AOP_LIT)
1340 return NULL; //zero;
1342 /* depending on type */
1343 switch (aop->type) {
1350 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1354 DEBUGpic16_emitcode(";","%d",__LINE__);
1355 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1358 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1361 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1362 pcop->type = PO_DIR;
1366 sprintf(s,"(%s + %d)",
1370 sprintf(s,"%s",aop->aopu.aop_dir);
1371 pcop->name = Safe_calloc(1,strlen(s)+1);
1372 strcpy(pcop->name,s);
1374 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1375 strcpy(pcop->name,aop->aopu.aop_dir);
1376 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1377 if(PCOR(pcop)->r == NULL) {
1378 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1379 PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1380 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1382 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1384 PCOR(pcop)->instance = offset;
1391 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1393 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1394 PCOR(pcop)->rIdx = rIdx;
1395 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1396 PCOR(pcop)->r->wasUsed=1;
1397 PCOR(pcop)->r->isFree=0;
1399 PCOR(pcop)->instance = offset;
1400 pcop->type = PCOR(pcop)->r->pc_type;
1401 //rs = aop->aopu.aop_reg[offset]->name;
1402 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1407 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1408 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1409 //if(PCOR(pcop)->r == NULL)
1410 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1414 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1417 DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1418 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1420 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1421 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1422 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1423 pcop->type = PCOR(pcop)->r->pc_type;
1424 pcop->name = PCOR(pcop)->r->name;
1430 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1432 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1433 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1434 PCOI(pcop)->offset = offset;
1438 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1439 "pic16_popGet got unsupported aop->type");
1442 /*-----------------------------------------------------------------*/
1443 /* pic16_aopPut - puts a string for a aop */
1444 /*-----------------------------------------------------------------*/
1445 void pic16_aopPut (asmop *aop, char *s, int offset)
1450 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1452 if (aop->size && offset > ( aop->size - 1)) {
1453 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1454 "pic16_aopPut got offset > aop->size");
1458 /* will assign value to value */
1459 /* depending on where it is ofcourse */
1460 switch (aop->type) {
1463 sprintf(d,"(%s + %d)",
1464 aop->aopu.aop_dir,offset);
1465 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1468 sprintf(d,"%s",aop->aopu.aop_dir);
1471 DEBUGpic16_emitcode(";","%d",__LINE__);
1473 pic16_emitcode("movf","%s,w",s);
1474 pic16_emitcode("movwf","%s",d);
1477 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1478 if(offset >= aop->size) {
1479 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1482 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1485 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1492 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1493 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1496 strcmp(s,"r0") == 0 ||
1497 strcmp(s,"r1") == 0 ||
1498 strcmp(s,"r2") == 0 ||
1499 strcmp(s,"r3") == 0 ||
1500 strcmp(s,"r4") == 0 ||
1501 strcmp(s,"r5") == 0 ||
1502 strcmp(s,"r6") == 0 ||
1503 strcmp(s,"r7") == 0 )
1504 pic16_emitcode("mov","%s,%s ; %d",
1505 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1509 if(strcmp(s,"W")==0 )
1510 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1512 pic16_emitcode("movwf","%s",
1513 aop->aopu.aop_reg[offset]->name);
1515 if(strcmp(s,zero)==0) {
1516 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1518 } else if(strcmp(s,"W")==0) {
1519 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1520 pcop->type = PO_GPR_REGISTER;
1522 PCOR(pcop)->rIdx = -1;
1523 PCOR(pcop)->r = NULL;
1525 DEBUGpic16_emitcode(";","%d",__LINE__);
1526 pcop->name = Safe_strdup(s);
1527 pic16_emitpcode(POC_MOVFW,pcop);
1528 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1529 } else if(strcmp(s,one)==0) {
1530 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1531 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1533 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1541 if (aop->type == AOP_DPTR2)
1547 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1548 "pic16_aopPut writting to code space");
1552 while (offset > aop->coff) {
1554 pic16_emitcode ("inc","dptr");
1557 while (offset < aop->coff) {
1559 pic16_emitcode("lcall","__decdptr");
1564 /* if not in accumulater */
1567 pic16_emitcode ("movx","@dptr,a");
1569 if (aop->type == AOP_DPTR2)
1577 while (offset > aop->coff) {
1579 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1581 while (offset < aop->coff) {
1583 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1589 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1594 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1596 if (strcmp(s,"r0") == 0 ||
1597 strcmp(s,"r1") == 0 ||
1598 strcmp(s,"r2") == 0 ||
1599 strcmp(s,"r3") == 0 ||
1600 strcmp(s,"r4") == 0 ||
1601 strcmp(s,"r5") == 0 ||
1602 strcmp(s,"r6") == 0 ||
1603 strcmp(s,"r7") == 0 ) {
1605 sprintf(buffer,"a%s",s);
1606 pic16_emitcode("mov","@%s,%s",
1607 aop->aopu.aop_ptr->name,buffer);
1609 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1614 if (strcmp(s,"a") == 0)
1615 pic16_emitcode("push","acc");
1617 pic16_emitcode("push","%s",s);
1622 /* if bit variable */
1623 if (!aop->aopu.aop_dir) {
1624 pic16_emitcode("clr","a");
1625 pic16_emitcode("rlc","a");
1628 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1631 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1634 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1636 lbl = newiTempLabel(NULL);
1638 if (strcmp(s,"a")) {
1641 pic16_emitcode("clr","c");
1642 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1643 pic16_emitcode("cpl","c");
1644 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1645 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1652 if (strcmp(aop->aopu.aop_str[offset],s))
1653 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1658 if (!offset && (strcmp(s,"acc") == 0))
1661 if (strcmp(aop->aopu.aop_str[offset],s))
1662 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1666 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1667 "pic16_aopPut got unsupported aop->type");
1673 /*-----------------------------------------------------------------*/
1674 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1675 /*-----------------------------------------------------------------*/
1676 static void mov2w (asmop *aop, int offset)
1682 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1684 if ( aop->type == AOP_PCODE ||
1685 aop->type == AOP_LIT )
1686 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1688 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1692 /*-----------------------------------------------------------------*/
1693 /* reAdjustPreg - points a register back to where it should */
1694 /*-----------------------------------------------------------------*/
1695 static void reAdjustPreg (asmop *aop)
1699 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1701 if ((size = aop->size) <= 1)
1704 switch (aop->type) {
1708 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1712 if (aop->type == AOP_DPTR2)
1718 pic16_emitcode("lcall","__decdptr");
1721 if (aop->type == AOP_DPTR2)
1733 /*-----------------------------------------------------------------*/
1734 /* opIsGptr: returns non-zero if the passed operand is */
1735 /* a generic pointer type. */
1736 /*-----------------------------------------------------------------*/
1737 static int opIsGptr(operand *op)
1739 sym_link *type = operandType(op);
1741 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1742 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1750 /*-----------------------------------------------------------------*/
1751 /* pic16_getDataSize - get the operand data size */
1752 /*-----------------------------------------------------------------*/
1753 int pic16_getDataSize(operand *op)
1755 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1758 return AOP_SIZE(op);
1760 // tsd- in the pic port, the genptr size is 1, so this code here
1761 // fails. ( in the 8051 port, the size was 4).
1764 size = AOP_SIZE(op);
1765 if (size == GPTRSIZE)
1767 sym_link *type = operandType(op);
1768 if (IS_GENPTR(type))
1770 /* generic pointer; arithmetic operations
1771 * should ignore the high byte (pointer type).
1774 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1781 /*-----------------------------------------------------------------*/
1782 /* pic16_outAcc - output Acc */
1783 /*-----------------------------------------------------------------*/
1784 void pic16_outAcc(operand *result)
1787 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1788 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1791 size = pic16_getDataSize(result);
1793 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1796 /* unsigned or positive */
1798 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1803 /*-----------------------------------------------------------------*/
1804 /* pic16_outBitC - output a bit C */
1805 /*-----------------------------------------------------------------*/
1806 void pic16_outBitC(operand *result)
1809 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1810 /* if the result is bit */
1811 if (AOP_TYPE(result) == AOP_CRY)
1812 pic16_aopPut(AOP(result),"c",0);
1814 pic16_emitcode("clr","a ; %d", __LINE__);
1815 pic16_emitcode("rlc","a");
1816 pic16_outAcc(result);
1820 /*-----------------------------------------------------------------*/
1821 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1822 /*-----------------------------------------------------------------*/
1823 void pic16_toBoolean(operand *oper)
1825 int size = AOP_SIZE(oper) - 1;
1828 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1830 if ( AOP_TYPE(oper) != AOP_ACC) {
1831 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1834 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1839 /*-----------------------------------------------------------------*/
1840 /* genNot - generate code for ! operation */
1841 /*-----------------------------------------------------------------*/
1842 static void genNot (iCode *ic)
1847 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1848 /* assign asmOps to operand & result */
1849 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1850 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1852 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1853 /* if in bit space then a special case */
1854 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1855 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1856 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1857 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1859 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1860 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1861 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1866 size = AOP_SIZE(IC_LEFT(ic));
1868 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1869 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1870 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1873 pic16_toBoolean(IC_LEFT(ic));
1875 tlbl = newiTempLabel(NULL);
1876 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1877 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1878 pic16_outBitC(IC_RESULT(ic));
1881 /* release the aops */
1882 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1883 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1887 /*-----------------------------------------------------------------*/
1888 /* genCpl - generate code for complement */
1889 /*-----------------------------------------------------------------*/
1890 static void genCpl (iCode *ic)
1896 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1897 /* assign asmOps to operand & result */
1898 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1899 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1901 /* if both are in bit space then
1903 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1904 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1906 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1907 pic16_emitcode("cpl","c");
1908 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1912 size = AOP_SIZE(IC_RESULT(ic));
1915 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1917 pic16_emitcode("cpl","a");
1918 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1920 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1921 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
1923 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1924 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1932 /* release the aops */
1933 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1934 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1937 /*-----------------------------------------------------------------*/
1938 /* genUminusFloat - unary minus for floating points */
1939 /*-----------------------------------------------------------------*/
1940 static void genUminusFloat(operand *op,operand *result)
1942 int size ,offset =0 ;
1945 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1946 /* for this we just need to flip the
1947 first it then copy the rest in place */
1948 size = AOP_SIZE(op) - 1;
1949 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1953 pic16_emitcode("cpl","acc.7");
1954 pic16_aopPut(AOP(result),"a",3);
1957 pic16_aopPut(AOP(result),
1958 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1964 /*-----------------------------------------------------------------*/
1965 /* genUminus - unary minus code generation */
1966 /*-----------------------------------------------------------------*/
1967 static void genUminus (iCode *ic)
1970 sym_link *optype, *rtype;
1973 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1975 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1976 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1978 /* if both in bit space then special
1980 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1981 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1983 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1984 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
1985 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1990 optype = operandType(IC_LEFT(ic));
1991 rtype = operandType(IC_RESULT(ic));
1993 /* if float then do float stuff */
1994 if (IS_FLOAT(optype)) {
1995 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1999 /* otherwise subtract from zero by taking the 2's complement */
2000 size = AOP_SIZE(IC_LEFT(ic));
2002 for(i=0; i<size; i++) {
2003 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2004 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2006 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2007 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2011 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2012 for(i=1; i<size; i++) {
2014 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2018 /* release the aops */
2019 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2020 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2023 /*-----------------------------------------------------------------*/
2024 /* saveRegisters - will look for a call and save the registers */
2025 /*-----------------------------------------------------------------*/
2026 static void saveRegisters(iCode *lic)
2033 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2035 for (ic = lic ; ic ; ic = ic->next)
2036 if (ic->op == CALL || ic->op == PCALL)
2040 fprintf(stderr,"found parameter push with no function call\n");
2044 /* if the registers have been saved already then
2046 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2049 /* find the registers in use at this time
2050 and push them away to safety */
2051 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2055 if (options.useXstack) {
2056 if (bitVectBitValue(rsave,R0_IDX))
2057 pic16_emitcode("mov","b,r0");
2058 pic16_emitcode("mov","r0,%s",spname);
2059 for (i = 0 ; i < pic16_nRegs ; i++) {
2060 if (bitVectBitValue(rsave,i)) {
2062 pic16_emitcode("mov","a,b");
2064 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2065 pic16_emitcode("movx","@r0,a");
2066 pic16_emitcode("inc","r0");
2069 pic16_emitcode("mov","%s,r0",spname);
2070 if (bitVectBitValue(rsave,R0_IDX))
2071 pic16_emitcode("mov","r0,b");
2073 //for (i = 0 ; i < pic16_nRegs ; i++) {
2074 // if (bitVectBitValue(rsave,i))
2075 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2078 dtype = operandType(IC_LEFT(ic));
2079 if (currFunc && dtype &&
2080 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2081 IFFUNC_ISISR(currFunc->type) &&
2084 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2087 /*-----------------------------------------------------------------*/
2088 /* unsaveRegisters - pop the pushed registers */
2089 /*-----------------------------------------------------------------*/
2090 static void unsaveRegisters (iCode *ic)
2095 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2096 /* find the registers in use at this time
2097 and push them away to safety */
2098 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2101 if (options.useXstack) {
2102 pic16_emitcode("mov","r0,%s",spname);
2103 for (i = pic16_nRegs ; i >= 0 ; i--) {
2104 if (bitVectBitValue(rsave,i)) {
2105 pic16_emitcode("dec","r0");
2106 pic16_emitcode("movx","a,@r0");
2108 pic16_emitcode("mov","b,a");
2110 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2114 pic16_emitcode("mov","%s,r0",spname);
2115 if (bitVectBitValue(rsave,R0_IDX))
2116 pic16_emitcode("mov","r0,b");
2118 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2119 // if (bitVectBitValue(rsave,i))
2120 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2126 /*-----------------------------------------------------------------*/
2128 /*-----------------------------------------------------------------*/
2129 static void pushSide(operand * oper, int size)
2133 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2135 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2136 if (AOP_TYPE(oper) != AOP_REG &&
2137 AOP_TYPE(oper) != AOP_DIR &&
2139 pic16_emitcode("mov","a,%s",l);
2140 pic16_emitcode("push","acc");
2142 pic16_emitcode("push","%s",l);
2147 /*-----------------------------------------------------------------*/
2148 /* assignResultValue - */
2149 /*-----------------------------------------------------------------*/
2150 static void assignResultValue(operand * oper)
2152 int size = AOP_SIZE(oper);
2154 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2156 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2158 if(!GpsuedoStkPtr) {
2159 /* The last byte in the assignment is in W */
2161 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2166 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2168 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2173 /*-----------------------------------------------------------------*/
2174 /* genIpush - genrate code for pushing this gets a little complex */
2175 /*-----------------------------------------------------------------*/
2176 static void genIpush (iCode *ic)
2179 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2181 int size, offset = 0 ;
2185 /* if this is not a parm push : ie. it is spill push
2186 and spill push is always done on the local stack */
2187 if (!ic->parmPush) {
2189 /* and the item is spilt then do nothing */
2190 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2193 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2194 size = AOP_SIZE(IC_LEFT(ic));
2195 /* push it on the stack */
2197 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2202 pic16_emitcode("push","%s",l);
2207 /* this is a paramter push: in this case we call
2208 the routine to find the call and save those
2209 registers that need to be saved */
2212 /* then do the push */
2213 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2216 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2217 size = AOP_SIZE(IC_LEFT(ic));
2220 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2221 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2222 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2224 pic16_emitcode("mov","a,%s",l);
2225 pic16_emitcode("push","acc");
2227 pic16_emitcode("push","%s",l);
2230 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2234 /*-----------------------------------------------------------------*/
2235 /* genIpop - recover the registers: can happen only for spilling */
2236 /*-----------------------------------------------------------------*/
2237 static void genIpop (iCode *ic)
2239 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2244 /* if the temp was not pushed then */
2245 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2248 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2249 size = AOP_SIZE(IC_LEFT(ic));
2252 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2255 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2259 /*-----------------------------------------------------------------*/
2260 /* unsaverbank - restores the resgister bank from stack */
2261 /*-----------------------------------------------------------------*/
2262 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2264 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2270 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2272 if (options.useXstack) {
2274 r = getFreePtr(ic,&aop,FALSE);
2277 pic16_emitcode("mov","%s,_spx",r->name);
2278 pic16_emitcode("movx","a,@%s",r->name);
2279 pic16_emitcode("mov","psw,a");
2280 pic16_emitcode("dec","%s",r->name);
2283 pic16_emitcode ("pop","psw");
2286 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2287 if (options.useXstack) {
2288 pic16_emitcode("movx","a,@%s",r->name);
2289 //pic16_emitcode("mov","(%s+%d),a",
2290 // regspic16[i].base,8*bank+regspic16[i].offset);
2291 pic16_emitcode("dec","%s",r->name);
2294 pic16_emitcode("pop",""); //"(%s+%d)",
2295 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2298 if (options.useXstack) {
2300 pic16_emitcode("mov","_spx,%s",r->name);
2301 pic16_freeAsmop(NULL,aop,ic,TRUE);
2307 /*-----------------------------------------------------------------*/
2308 /* saverbank - saves an entire register bank on the stack */
2309 /*-----------------------------------------------------------------*/
2310 static void saverbank (int bank, iCode *ic, bool pushPsw)
2312 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2318 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2319 if (options.useXstack) {
2322 r = getFreePtr(ic,&aop,FALSE);
2323 pic16_emitcode("mov","%s,_spx",r->name);
2327 for (i = 0 ; i < pic16_nRegs ;i++) {
2328 if (options.useXstack) {
2329 pic16_emitcode("inc","%s",r->name);
2330 //pic16_emitcode("mov","a,(%s+%d)",
2331 // regspic16[i].base,8*bank+regspic16[i].offset);
2332 pic16_emitcode("movx","@%s,a",r->name);
2334 pic16_emitcode("push","");// "(%s+%d)",
2335 //regspic16[i].base,8*bank+regspic16[i].offset);
2339 if (options.useXstack) {
2340 pic16_emitcode("mov","a,psw");
2341 pic16_emitcode("movx","@%s,a",r->name);
2342 pic16_emitcode("inc","%s",r->name);
2343 pic16_emitcode("mov","_spx,%s",r->name);
2344 pic16_freeAsmop (NULL,aop,ic,TRUE);
2347 pic16_emitcode("push","psw");
2349 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2355 /*-----------------------------------------------------------------*/
2356 /* genCall - generates a call statement */
2357 /*-----------------------------------------------------------------*/
2358 static void genCall (iCode *ic)
2362 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2364 /* if caller saves & we have not saved then */
2368 /* if we are calling a function that is not using
2369 the same register bank then we need to save the
2370 destination registers on the stack */
2371 dtype = operandType(IC_LEFT(ic));
2372 if (currFunc && dtype &&
2373 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2374 IFFUNC_ISISR(currFunc->type) &&
2377 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2379 /* if send set is not empty the assign */
2382 /* For the Pic port, there is no data stack.
2383 * So parameters passed to functions are stored
2384 * in registers. (The pCode optimizer will get
2385 * rid of most of these :).
2387 int psuedoStkPtr=-1;
2388 int firstTimeThruLoop = 1;
2390 _G.sendSet = reverseSet(_G.sendSet);
2392 /* First figure how many parameters are getting passed */
2393 for (sic = setFirstItem(_G.sendSet) ; sic ;
2394 sic = setNextItem(_G.sendSet)) {
2396 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2397 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2398 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2401 for (sic = setFirstItem(_G.sendSet) ; sic ;
2402 sic = setNextItem(_G.sendSet)) {
2403 int size, offset = 0;
2405 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2406 size = AOP_SIZE(IC_LEFT(sic));
2409 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2410 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2412 if(!firstTimeThruLoop) {
2413 /* If this is not the first time we've been through the loop
2414 * then we need to save the parameter in a temporary
2415 * register. The last byte of the last parameter is
2417 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2420 firstTimeThruLoop=0;
2422 //if (strcmp(l,fReturn[offset])) {
2423 mov2w (AOP(IC_LEFT(sic)), offset);
2425 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2426 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2427 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2429 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2434 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2439 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2440 OP_SYMBOL(IC_LEFT(ic))->rname :
2441 OP_SYMBOL(IC_LEFT(ic))->name));
2444 /* if we need assign a result value */
2445 if ((IS_ITEMP(IC_RESULT(ic)) &&
2446 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2447 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2448 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2451 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2454 assignResultValue(IC_RESULT(ic));
2456 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2457 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2459 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2462 /* adjust the stack for parameters if
2464 if (ic->parmBytes) {
2466 if (ic->parmBytes > 3) {
2467 pic16_emitcode("mov","a,%s",spname);
2468 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2469 pic16_emitcode("mov","%s,a",spname);
2471 for ( i = 0 ; i < ic->parmBytes ;i++)
2472 pic16_emitcode("dec","%s",spname);
2476 /* if register bank was saved then pop them */
2478 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2480 /* if we hade saved some registers then unsave them */
2481 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2482 unsaveRegisters (ic);
2487 /*-----------------------------------------------------------------*/
2488 /* genPcall - generates a call by pointer statement */
2489 /*-----------------------------------------------------------------*/
2490 static void genPcall (iCode *ic)
2493 symbol *rlbl = newiTempLabel(NULL);
2496 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2497 /* if caller saves & we have not saved then */
2501 /* if we are calling a function that is not using
2502 the same register bank then we need to save the
2503 destination registers on the stack */
2504 dtype = operandType(IC_LEFT(ic));
2505 if (currFunc && dtype &&
2506 IFFUNC_ISISR(currFunc->type) &&
2507 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2508 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2511 /* push the return address on to the stack */
2512 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2513 pic16_emitcode("push","acc");
2514 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2515 pic16_emitcode("push","acc");
2517 if (options.model == MODEL_FLAT24)
2519 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2520 pic16_emitcode("push","acc");
2523 /* now push the calling address */
2524 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2526 pushSide(IC_LEFT(ic), FPTRSIZE);
2528 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2530 /* if send set is not empty the assign */
2534 for (sic = setFirstItem(_G.sendSet) ; sic ;
2535 sic = setNextItem(_G.sendSet)) {
2536 int size, offset = 0;
2537 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2538 size = AOP_SIZE(IC_LEFT(sic));
2540 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2542 if (strcmp(l,fReturn[offset]))
2543 pic16_emitcode("mov","%s,%s",
2548 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2553 pic16_emitcode("ret","");
2554 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2557 /* if we need assign a result value */
2558 if ((IS_ITEMP(IC_RESULT(ic)) &&
2559 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2560 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2561 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2564 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2567 assignResultValue(IC_RESULT(ic));
2569 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2572 /* adjust the stack for parameters if
2574 if (ic->parmBytes) {
2576 if (ic->parmBytes > 3) {
2577 pic16_emitcode("mov","a,%s",spname);
2578 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2579 pic16_emitcode("mov","%s,a",spname);
2581 for ( i = 0 ; i < ic->parmBytes ;i++)
2582 pic16_emitcode("dec","%s",spname);
2586 /* if register bank was saved then unsave them */
2587 if (currFunc && dtype &&
2588 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2589 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2591 /* if we hade saved some registers then
2594 unsaveRegisters (ic);
2598 /*-----------------------------------------------------------------*/
2599 /* resultRemat - result is rematerializable */
2600 /*-----------------------------------------------------------------*/
2601 static int resultRemat (iCode *ic)
2603 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2604 if (SKIP_IC(ic) || ic->op == IFX)
2607 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2608 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2609 if (sym->remat && !POINTER_SET(ic))
2616 #if defined(__BORLANDC__) || defined(_MSC_VER)
2617 #define STRCASECMP stricmp
2619 #define STRCASECMP strcasecmp
2623 /*-----------------------------------------------------------------*/
2624 /* inExcludeList - return 1 if the string is in exclude Reg list */
2625 /*-----------------------------------------------------------------*/
2626 static bool inExcludeList(char *s)
2628 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2631 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2632 if (options.excludeRegs[i] &&
2633 STRCASECMP(options.excludeRegs[i],"none") == 0)
2636 for ( i = 0 ; options.excludeRegs[i]; i++) {
2637 if (options.excludeRegs[i] &&
2638 STRCASECMP(s,options.excludeRegs[i]) == 0)
2645 /*-----------------------------------------------------------------*/
2646 /* genFunction - generated code for function entry */
2647 /*-----------------------------------------------------------------*/
2648 static void genFunction (iCode *ic)
2653 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2655 labelOffset += (max_key+4);
2659 /* create the function header */
2660 pic16_emitcode(";","-----------------------------------------");
2661 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2662 pic16_emitcode(";","-----------------------------------------");
2664 pic16_emitcode("","%s:",sym->rname);
2665 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2667 ftype = operandType(IC_LEFT(ic));
2669 /* if critical function then turn interrupts off */
2670 if (IFFUNC_ISCRITICAL(ftype))
2671 pic16_emitcode("clr","ea");
2673 /* here we need to generate the equates for the
2674 register bank if required */
2676 if (FUNC_REGBANK(ftype) != rbank) {
2679 rbank = FUNC_REGBANK(ftype);
2680 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2681 if (strcmp(regspic16[i].base,"0") == 0)
2682 pic16_emitcode("","%s = 0x%02x",
2684 8*rbank+regspic16[i].offset);
2686 pic16_emitcode ("","%s = %s + 0x%02x",
2689 8*rbank+regspic16[i].offset);
2694 /* if this is an interrupt service routine then
2695 save acc, b, dpl, dph */
2696 if (IFFUNC_ISISR(sym->type)) {
2699 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2701 /* what is the reason of having these 3 NOPS? VR - 030701 */
2702 pic16_emitpcodeNULLop(POC_NOP);
2703 pic16_emitpcodeNULLop(POC_NOP);
2704 pic16_emitpcodeNULLop(POC_NOP);
2707 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2708 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2709 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2710 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2712 pic16_pBlockConvert2ISR(pb);
2714 if (!inExcludeList("acc"))
2715 pic16_emitcode ("push","acc");
2716 if (!inExcludeList("b"))
2717 pic16_emitcode ("push","b");
2718 if (!inExcludeList("dpl"))
2719 pic16_emitcode ("push","dpl");
2720 if (!inExcludeList("dph"))
2721 pic16_emitcode ("push","dph");
2722 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2724 pic16_emitcode ("push", "dpx");
2725 /* Make sure we're using standard DPTR */
2726 pic16_emitcode ("push", "dps");
2727 pic16_emitcode ("mov", "dps, #0x00");
2728 if (options.stack10bit)
2730 /* This ISR could conceivably use DPTR2. Better save it. */
2731 pic16_emitcode ("push", "dpl1");
2732 pic16_emitcode ("push", "dph1");
2733 pic16_emitcode ("push", "dpx1");
2736 /* if this isr has no bank i.e. is going to
2737 run with bank 0 , then we need to save more
2739 if (!FUNC_REGBANK(sym->type)) {
2741 /* if this function does not call any other
2742 function then we can be economical and
2743 save only those registers that are used */
2744 if (! IFFUNC_HASFCALL(sym->type)) {
2747 /* if any registers used */
2748 if (sym->regsUsed) {
2749 /* save the registers used */
2750 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2751 if (bitVectBitValue(sym->regsUsed,i) ||
2752 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2753 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2758 /* this function has a function call cannot
2759 determines register usage so we will have the
2761 saverbank(0,ic,FALSE);
2766 /* if callee-save to be used for this function
2767 then save the registers being used in this function */
2768 if (IFFUNC_CALLEESAVES(sym->type)) {
2771 /* if any registers used */
2772 if (sym->regsUsed) {
2773 /* save the registers used */
2774 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2775 if (bitVectBitValue(sym->regsUsed,i) ||
2776 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2777 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2785 /* set the register bank to the desired value */
2786 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2787 pic16_emitcode("push","psw");
2788 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2791 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2793 if (options.useXstack) {
2794 pic16_emitcode("mov","r0,%s",spname);
2795 pic16_emitcode("mov","a,_bp");
2796 pic16_emitcode("movx","@r0,a");
2797 pic16_emitcode("inc","%s",spname);
2801 /* set up the stack */
2802 pic16_emitcode ("push","_bp"); /* save the callers stack */
2804 pic16_emitcode ("mov","_bp,%s",spname);
2807 /* adjust the stack for the function */
2812 werror(W_STACK_OVERFLOW,sym->name);
2814 if (i > 3 && sym->recvSize < 4) {
2816 pic16_emitcode ("mov","a,sp");
2817 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2818 pic16_emitcode ("mov","sp,a");
2823 pic16_emitcode("inc","sp");
2828 pic16_emitcode ("mov","a,_spx");
2829 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2830 pic16_emitcode ("mov","_spx,a");
2835 /*-----------------------------------------------------------------*/
2836 /* genEndFunction - generates epilogue for functions */
2837 /*-----------------------------------------------------------------*/
2838 static void genEndFunction (iCode *ic)
2840 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2842 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2844 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2846 pic16_emitcode ("mov","%s,_bp",spname);
2849 /* if use external stack but some variables were
2850 added to the local stack then decrement the
2852 if (options.useXstack && sym->stack) {
2853 pic16_emitcode("mov","a,sp");
2854 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2855 pic16_emitcode("mov","sp,a");
2859 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2860 if (options.useXstack) {
2861 pic16_emitcode("mov","r0,%s",spname);
2862 pic16_emitcode("movx","a,@r0");
2863 pic16_emitcode("mov","_bp,a");
2864 pic16_emitcode("dec","%s",spname);
2868 pic16_emitcode ("pop","_bp");
2872 /* restore the register bank */
2873 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2874 pic16_emitcode ("pop","psw");
2876 if (IFFUNC_ISISR(sym->type)) {
2878 /* now we need to restore the registers */
2879 /* if this isr has no bank i.e. is going to
2880 run with bank 0 , then we need to save more
2882 if (!FUNC_REGBANK(sym->type)) {
2884 /* if this function does not call any other
2885 function then we can be economical and
2886 save only those registers that are used */
2887 if (! IFFUNC_HASFCALL(sym->type)) {
2890 /* if any registers used */
2891 if (sym->regsUsed) {
2892 /* save the registers used */
2893 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2894 if (bitVectBitValue(sym->regsUsed,i) ||
2895 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2896 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2901 /* this function has a function call cannot
2902 determines register usage so we will have the
2904 unsaverbank(0,ic,FALSE);
2908 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2910 if (options.stack10bit)
2912 pic16_emitcode ("pop", "dpx1");
2913 pic16_emitcode ("pop", "dph1");
2914 pic16_emitcode ("pop", "dpl1");
2916 pic16_emitcode ("pop", "dps");
2917 pic16_emitcode ("pop", "dpx");
2919 if (!inExcludeList("dph"))
2920 pic16_emitcode ("pop","dph");
2921 if (!inExcludeList("dpl"))
2922 pic16_emitcode ("pop","dpl");
2923 if (!inExcludeList("b"))
2924 pic16_emitcode ("pop","b");
2925 if (!inExcludeList("acc"))
2926 pic16_emitcode ("pop","acc");
2928 if (IFFUNC_ISCRITICAL(sym->type))
2929 pic16_emitcode("setb","ea");
2932 /* if debug then send end of function */
2933 /* if (options.debug && currFunc) { */
2936 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2937 FileBaseName(ic->filename),currFunc->lastLine,
2938 ic->level,ic->block);
2939 if (IS_STATIC(currFunc->etype))
2940 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2942 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2946 // pic16_emitcode ("reti","");
2948 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2949 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2950 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
2951 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
2952 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2955 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2958 pic16_emitpcodeNULLop(POC_RETFIE);
2962 if (IFFUNC_ISCRITICAL(sym->type))
2963 pic16_emitcode("setb","ea");
2965 if (IFFUNC_CALLEESAVES(sym->type)) {
2968 /* if any registers used */
2969 if (sym->regsUsed) {
2970 /* save the registers used */
2971 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2972 if (bitVectBitValue(sym->regsUsed,i) ||
2973 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2974 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2980 /* if debug then send end of function */
2983 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2984 FileBaseName(ic->filename),currFunc->lastLine,
2985 ic->level,ic->block);
2986 if (IS_STATIC(currFunc->etype))
2987 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2989 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2993 pic16_emitcode ("return","");
2994 pic16_emitpcodeNULLop(POC_RETURN);
2996 /* Mark the end of a function */
2997 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3002 /*-----------------------------------------------------------------*/
3003 /* genRet - generate code for return statement */
3004 /*-----------------------------------------------------------------*/
3005 static void genRet (iCode *ic)
3007 int size,offset = 0 , pushed = 0;
3009 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3010 /* if we have no return value then
3011 just generate the "ret" */
3015 /* we have something to return then
3016 move the return value into place */
3017 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3018 size = AOP_SIZE(IC_LEFT(ic));
3022 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3024 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3026 pic16_emitcode("push","%s",l);
3029 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3031 if (strcmp(fReturn[offset],l)) {
3032 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3033 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3034 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3036 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3039 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3049 if (strcmp(fReturn[pushed],"a"))
3050 pic16_emitcode("pop",fReturn[pushed]);
3052 pic16_emitcode("pop","acc");
3055 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3058 /* generate a jump to the return label
3059 if the next is not the return statement */
3060 if (!(ic->next && ic->next->op == LABEL &&
3061 IC_LABEL(ic->next) == returnLabel)) {
3063 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3064 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3069 /*-----------------------------------------------------------------*/
3070 /* genLabel - generates a label */
3071 /*-----------------------------------------------------------------*/
3072 static void genLabel (iCode *ic)
3074 /* special case never generate */
3075 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3076 if (IC_LABEL(ic) == entryLabel)
3079 pic16_emitpLabel(IC_LABEL(ic)->key);
3080 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3083 /*-----------------------------------------------------------------*/
3084 /* genGoto - generates a goto */
3085 /*-----------------------------------------------------------------*/
3087 static void genGoto (iCode *ic)
3089 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3090 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3094 /*-----------------------------------------------------------------*/
3095 /* genMultbits :- multiplication of bits */
3096 /*-----------------------------------------------------------------*/
3097 static void genMultbits (operand *left,
3101 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3103 if(!pic16_sameRegs(AOP(result),AOP(right)))
3104 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3106 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3107 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3108 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3113 /*-----------------------------------------------------------------*/
3114 /* genMultOneByte : 8 bit multiplication & division */
3115 /*-----------------------------------------------------------------*/
3116 static void genMultOneByte (operand *left,
3120 sym_link *opetype = operandType(result);
3125 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3126 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3127 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3129 /* (if two literals, the value is computed before) */
3130 /* if one literal, literal on the right */
3131 if (AOP_TYPE(left) == AOP_LIT){
3137 size = AOP_SIZE(result);
3140 if (AOP_TYPE(right) == AOP_LIT){
3141 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3142 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3143 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3144 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3145 pic16_emitcode("call","genMultLit");
3147 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3148 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3149 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3150 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3151 pic16_emitcode("call","pic16_genMult8X8_8");
3154 pic16_genMult8X8_8 (left, right,result);
3157 /* signed or unsigned */
3158 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3159 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3161 //pic16_emitcode("mul","ab");
3162 /* if result size = 1, mul signed = mul unsigned */
3163 //pic16_aopPut(AOP(result),"a",0);
3165 } else { // (size > 1)
3167 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3168 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3169 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3170 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3172 if (SPEC_USIGN(opetype)){
3173 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3174 pic16_genUMult8X8_16 (left, right, result, NULL);
3177 /* for filling the MSBs */
3178 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3179 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3183 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3185 pic16_emitcode("mov","a,b");
3187 /* adjust the MSB if left or right neg */
3189 /* if one literal */
3190 if (AOP_TYPE(right) == AOP_LIT){
3191 pic16_emitcode("multiply ","right is a lit");
3192 /* AND literal negative */
3193 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3194 /* adjust MSB (c==0 after mul) */
3195 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3199 pic16_genSMult8X8_16 (left, right, result, NULL);
3203 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3205 pic16_emitcode("rlc","a");
3206 pic16_emitcode("subb","a,acc");
3214 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3215 //pic16_aopPut(AOP(result),"a",offset++);
3219 /*-----------------------------------------------------------------*/
3220 /* genMult - generates code for multiplication */
3221 /*-----------------------------------------------------------------*/
3222 static void genMult (iCode *ic)
3224 operand *left = IC_LEFT(ic);
3225 operand *right = IC_RIGHT(ic);
3226 operand *result= IC_RESULT(ic);
3228 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3229 /* assign the amsops */
3230 pic16_aopOp (left,ic,FALSE);
3231 pic16_aopOp (right,ic,FALSE);
3232 pic16_aopOp (result,ic,TRUE);
3234 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3236 /* special cases first */
3238 if (AOP_TYPE(left) == AOP_CRY &&
3239 AOP_TYPE(right)== AOP_CRY) {
3240 genMultbits(left,right,result);
3244 /* if both are of size == 1 */
3245 if (AOP_SIZE(left) == 1 &&
3246 AOP_SIZE(right) == 1 ) {
3247 genMultOneByte(left,right,result);
3251 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3253 /* should have been converted to function call */
3257 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3258 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3259 pic16_freeAsmop(result,NULL,ic,TRUE);
3262 /*-----------------------------------------------------------------*/
3263 /* genDivbits :- division of bits */
3264 /*-----------------------------------------------------------------*/
3265 static void genDivbits (operand *left,
3272 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3273 /* the result must be bit */
3274 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3275 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3279 pic16_emitcode("div","ab");
3280 pic16_emitcode("rrc","a");
3281 pic16_aopPut(AOP(result),"c",0);
3284 /*-----------------------------------------------------------------*/
3285 /* genDivOneByte : 8 bit division */
3286 /*-----------------------------------------------------------------*/
3287 static void genDivOneByte (operand *left,
3291 sym_link *opetype = operandType(result);
3296 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3297 size = AOP_SIZE(result) - 1;
3299 /* signed or unsigned */
3300 if (SPEC_USIGN(opetype)) {
3301 /* unsigned is easy */
3302 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3303 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3305 pic16_emitcode("div","ab");
3306 pic16_aopPut(AOP(result),"a",0);
3308 pic16_aopPut(AOP(result),zero,offset++);
3312 /* signed is a little bit more difficult */
3314 /* save the signs of the operands */
3315 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3317 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3318 pic16_emitcode("push","acc"); /* save it on the stack */
3320 /* now sign adjust for both left & right */
3321 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3323 lbl = newiTempLabel(NULL);
3324 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3325 pic16_emitcode("cpl","a");
3326 pic16_emitcode("inc","a");
3327 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3328 pic16_emitcode("mov","b,a");
3330 /* sign adjust left side */
3331 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3334 lbl = newiTempLabel(NULL);
3335 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3336 pic16_emitcode("cpl","a");
3337 pic16_emitcode("inc","a");
3338 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3340 /* now the division */
3341 pic16_emitcode("div","ab");
3342 /* we are interested in the lower order
3344 pic16_emitcode("mov","b,a");
3345 lbl = newiTempLabel(NULL);
3346 pic16_emitcode("pop","acc");
3347 /* if there was an over flow we don't
3348 adjust the sign of the result */
3349 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3350 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3352 pic16_emitcode("clr","a");
3353 pic16_emitcode("subb","a,b");
3354 pic16_emitcode("mov","b,a");
3355 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3357 /* now we are done */
3358 pic16_aopPut(AOP(result),"b",0);
3360 pic16_emitcode("mov","c,b.7");
3361 pic16_emitcode("subb","a,acc");
3364 pic16_aopPut(AOP(result),"a",offset++);
3368 /*-----------------------------------------------------------------*/
3369 /* genDiv - generates code for division */
3370 /*-----------------------------------------------------------------*/
3371 static void genDiv (iCode *ic)
3373 operand *left = IC_LEFT(ic);
3374 operand *right = IC_RIGHT(ic);
3375 operand *result= IC_RESULT(ic);
3377 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3378 /* assign the amsops */
3379 pic16_aopOp (left,ic,FALSE);
3380 pic16_aopOp (right,ic,FALSE);
3381 pic16_aopOp (result,ic,TRUE);
3383 /* special cases first */
3385 if (AOP_TYPE(left) == AOP_CRY &&
3386 AOP_TYPE(right)== AOP_CRY) {
3387 genDivbits(left,right,result);
3391 /* if both are of size == 1 */
3392 if (AOP_SIZE(left) == 1 &&
3393 AOP_SIZE(right) == 1 ) {
3394 genDivOneByte(left,right,result);
3398 /* should have been converted to function call */
3401 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3402 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3403 pic16_freeAsmop(result,NULL,ic,TRUE);
3406 /*-----------------------------------------------------------------*/
3407 /* genModbits :- modulus of bits */
3408 /*-----------------------------------------------------------------*/
3409 static void genModbits (operand *left,
3416 /* the result must be bit */
3417 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3418 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3422 pic16_emitcode("div","ab");
3423 pic16_emitcode("mov","a,b");
3424 pic16_emitcode("rrc","a");
3425 pic16_aopPut(AOP(result),"c",0);
3428 /*-----------------------------------------------------------------*/
3429 /* genModOneByte : 8 bit modulus */
3430 /*-----------------------------------------------------------------*/
3431 static void genModOneByte (operand *left,
3435 sym_link *opetype = operandType(result);
3439 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3440 /* signed or unsigned */
3441 if (SPEC_USIGN(opetype)) {
3442 /* unsigned is easy */
3443 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3444 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3446 pic16_emitcode("div","ab");
3447 pic16_aopPut(AOP(result),"b",0);
3451 /* signed is a little bit more difficult */
3453 /* save the signs of the operands */
3454 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3457 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3458 pic16_emitcode("push","acc"); /* save it on the stack */
3460 /* now sign adjust for both left & right */
3461 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3464 lbl = newiTempLabel(NULL);
3465 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3466 pic16_emitcode("cpl","a");
3467 pic16_emitcode("inc","a");
3468 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3469 pic16_emitcode("mov","b,a");
3471 /* sign adjust left side */
3472 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3475 lbl = newiTempLabel(NULL);
3476 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3477 pic16_emitcode("cpl","a");
3478 pic16_emitcode("inc","a");
3479 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3481 /* now the multiplication */
3482 pic16_emitcode("div","ab");
3483 /* we are interested in the lower order
3485 lbl = newiTempLabel(NULL);
3486 pic16_emitcode("pop","acc");
3487 /* if there was an over flow we don't
3488 adjust the sign of the result */
3489 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3490 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3492 pic16_emitcode("clr","a");
3493 pic16_emitcode("subb","a,b");
3494 pic16_emitcode("mov","b,a");
3495 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3497 /* now we are done */
3498 pic16_aopPut(AOP(result),"b",0);
3502 /*-----------------------------------------------------------------*/
3503 /* genMod - generates code for division */
3504 /*-----------------------------------------------------------------*/
3505 static void genMod (iCode *ic)
3507 operand *left = IC_LEFT(ic);
3508 operand *right = IC_RIGHT(ic);
3509 operand *result= IC_RESULT(ic);
3511 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3512 /* assign the amsops */
3513 pic16_aopOp (left,ic,FALSE);
3514 pic16_aopOp (right,ic,FALSE);
3515 pic16_aopOp (result,ic,TRUE);
3517 /* special cases first */
3519 if (AOP_TYPE(left) == AOP_CRY &&
3520 AOP_TYPE(right)== AOP_CRY) {
3521 genModbits(left,right,result);
3525 /* if both are of size == 1 */
3526 if (AOP_SIZE(left) == 1 &&
3527 AOP_SIZE(right) == 1 ) {
3528 genModOneByte(left,right,result);
3532 /* should have been converted to function call */
3536 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3537 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3538 pic16_freeAsmop(result,NULL,ic,TRUE);
3541 /*-----------------------------------------------------------------*/
3542 /* genIfxJump :- will create a jump depending on the ifx */
3543 /*-----------------------------------------------------------------*/
3545 note: May need to add parameter to indicate when a variable is in bit space.
3547 static void genIfxJump (iCode *ic, char *jval)
3550 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3551 /* if true label then we jump if condition
3553 if ( IC_TRUE(ic) ) {
3555 if(strcmp(jval,"a") == 0)
3557 else if (strcmp(jval,"c") == 0)
3560 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3561 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3564 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3565 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3569 /* false label is present */
3570 if(strcmp(jval,"a") == 0)
3572 else if (strcmp(jval,"c") == 0)
3575 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3576 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3579 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3580 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3585 /* mark the icode as generated */
3589 /*-----------------------------------------------------------------*/
3591 /*-----------------------------------------------------------------*/
3592 static void genSkip(iCode *ifx,int status_bit)
3597 if ( IC_TRUE(ifx) ) {
3598 switch(status_bit) {
3613 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3614 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3618 switch(status_bit) {
3632 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3633 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3639 /*-----------------------------------------------------------------*/
3641 /*-----------------------------------------------------------------*/
3642 static void genSkipc(resolvedIfx *rifx)
3652 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3653 rifx->generated = 1;
3656 /*-----------------------------------------------------------------*/
3658 /*-----------------------------------------------------------------*/
3659 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3664 if( (rifx->condition ^ invert_condition) & 1)
3669 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3670 rifx->generated = 1;
3673 /*-----------------------------------------------------------------*/
3675 /*-----------------------------------------------------------------*/
3676 static void genSkipz(iCode *ifx, int condition)
3687 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3689 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3692 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3694 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3697 /*-----------------------------------------------------------------*/
3699 /*-----------------------------------------------------------------*/
3700 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3706 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3708 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3711 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3712 rifx->generated = 1;
3716 /*-----------------------------------------------------------------*/
3717 /* genChkZeroes :- greater or less than comparison */
3718 /* For each byte in a literal that is zero, inclusive or the */
3719 /* the corresponding byte in the operand with W */
3720 /* returns true if any of the bytes are zero */
3721 /*-----------------------------------------------------------------*/
3722 static int genChkZeroes(operand *op, int lit, int size)
3729 i = (lit >> (size*8)) & 0xff;
3733 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3735 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3744 /*-----------------------------------------------------------------*/
3745 /* genCmp :- greater or less than comparison */
3746 /*-----------------------------------------------------------------*/
3747 static void genCmp (operand *left,operand *right,
3748 operand *result, iCode *ifx, int sign)
3750 int size; //, offset = 0 ;
3751 unsigned long lit = 0L,i = 0;
3752 resolvedIfx rFalseIfx;
3753 // resolvedIfx rTrueIfx;
3755 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3758 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3759 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3763 resolveIfx(&rFalseIfx,ifx);
3764 truelbl = newiTempLabel(NULL);
3765 size = max(AOP_SIZE(left),AOP_SIZE(right));
3767 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3771 /* if literal is on the right then swap with left */
3772 if ((AOP_TYPE(right) == AOP_LIT)) {
3773 operand *tmp = right ;
3774 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3775 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3778 lit = (lit - 1) & mask;
3781 rFalseIfx.condition ^= 1;
3784 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3785 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3789 //if(IC_TRUE(ifx) == NULL)
3790 /* if left & right are bit variables */
3791 if (AOP_TYPE(left) == AOP_CRY &&
3792 AOP_TYPE(right) == AOP_CRY ) {
3793 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3794 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3796 /* subtract right from left if at the
3797 end the carry flag is set then we know that
3798 left is greater than right */
3802 symbol *lbl = newiTempLabel(NULL);
3805 if(AOP_TYPE(right) == AOP_LIT) {
3807 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3809 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3816 genSkipCond(&rFalseIfx,left,size-1,7);
3818 /* no need to compare to 0...*/
3819 /* NOTE: this is a de-generate compare that most certainly
3820 * creates some dead code. */
3821 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3823 if(ifx) ifx->generated = 1;
3830 //i = (lit >> (size*8)) & 0xff;
3831 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3833 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3835 i = ((0-lit) & 0xff);
3838 /* lit is 0x7f, all signed chars are less than
3839 * this except for 0x7f itself */
3840 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3841 genSkipz2(&rFalseIfx,0);
3843 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3844 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3845 genSkipc(&rFalseIfx);
3850 genSkipz2(&rFalseIfx,1);
3852 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3853 genSkipc(&rFalseIfx);
3857 if(ifx) ifx->generated = 1;
3861 /* chars are out of the way. now do ints and longs */
3864 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3871 genSkipCond(&rFalseIfx,left,size,7);
3872 if(ifx) ifx->generated = 1;
3877 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3879 //rFalseIfx.condition ^= 1;
3880 //genSkipCond(&rFalseIfx,left,size,7);
3881 //rFalseIfx.condition ^= 1;
3883 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3884 if(rFalseIfx.condition)
3885 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3887 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3889 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3890 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3891 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3894 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3896 if(rFalseIfx.condition) {
3898 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3904 genSkipc(&rFalseIfx);
3905 pic16_emitpLabel(truelbl->key);
3906 if(ifx) ifx->generated = 1;
3913 if( (lit & 0xff) == 0) {
3914 /* lower byte is zero */
3915 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3916 i = ((lit >> 8) & 0xff) ^0x80;
3917 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3918 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3919 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3920 genSkipc(&rFalseIfx);
3923 if(ifx) ifx->generated = 1;
3928 /* Special cases for signed longs */
3929 if( (lit & 0xffffff) == 0) {
3930 /* lower byte is zero */
3931 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3932 i = ((lit >> 8*3) & 0xff) ^0x80;
3933 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3934 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3935 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3936 genSkipc(&rFalseIfx);
3939 if(ifx) ifx->generated = 1;
3947 if(lit & (0x80 << (size*8))) {
3948 /* lit is negative */
3949 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3951 //genSkipCond(&rFalseIfx,left,size,7);
3953 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3955 if(rFalseIfx.condition)
3956 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3958 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3962 /* lit is positive */
3963 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3964 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3965 if(rFalseIfx.condition)
3966 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3968 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3973 This works, but is only good for ints.
3974 It also requires a "known zero" register.
3975 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3976 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3977 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
3978 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3979 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3980 genSkipc(&rFalseIfx);
3982 pic16_emitpLabel(truelbl->key);
3983 if(ifx) ifx->generated = 1;
3987 /* There are no more special cases, so perform a general compare */
3989 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3990 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3994 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3996 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3998 //rFalseIfx.condition ^= 1;
3999 genSkipc(&rFalseIfx);
4001 pic16_emitpLabel(truelbl->key);
4003 if(ifx) ifx->generated = 1;
4010 /* sign is out of the way. So now do an unsigned compare */
4011 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4014 /* General case - compare to an unsigned literal on the right.*/
4016 i = (lit >> (size*8)) & 0xff;
4017 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4018 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4020 i = (lit >> (size*8)) & 0xff;
4023 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4025 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4027 /* this byte of the lit is zero,
4028 *if it's not the last then OR in the variable */
4030 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4035 pic16_emitpLabel(lbl->key);
4036 //if(emitFinalCheck)
4037 genSkipc(&rFalseIfx);
4039 pic16_emitpLabel(truelbl->key);
4041 if(ifx) ifx->generated = 1;
4048 if(AOP_TYPE(left) == AOP_LIT) {
4049 //symbol *lbl = newiTempLabel(NULL);
4051 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4054 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4057 if((lit == 0) && (sign == 0)){
4060 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4062 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4064 genSkipz2(&rFalseIfx,0);
4065 if(ifx) ifx->generated = 1;
4072 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4073 /* degenerate compare can never be true */
4074 if(rFalseIfx.condition == 0)
4075 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4077 if(ifx) ifx->generated = 1;
4082 /* signed comparisons to a literal byte */
4084 int lp1 = (lit+1) & 0xff;
4086 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4089 rFalseIfx.condition ^= 1;
4090 genSkipCond(&rFalseIfx,right,0,7);
4093 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4094 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4095 genSkipz2(&rFalseIfx,1);
4098 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4099 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4100 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4101 rFalseIfx.condition ^= 1;
4102 genSkipc(&rFalseIfx);
4106 /* unsigned comparisons to a literal byte */
4108 switch(lit & 0xff ) {
4110 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4111 genSkipz2(&rFalseIfx,0);
4114 rFalseIfx.condition ^= 1;
4115 genSkipCond(&rFalseIfx,right,0,7);
4119 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4120 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4121 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4122 rFalseIfx.condition ^= 1;
4123 if (AOP_TYPE(result) == AOP_CRY)
4124 genSkipc(&rFalseIfx);
4126 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4127 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4133 if(ifx) ifx->generated = 1;
4139 /* Size is greater than 1 */
4147 /* this means lit = 0xffffffff, or -1 */
4150 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4151 rFalseIfx.condition ^= 1;
4152 genSkipCond(&rFalseIfx,right,size,7);
4153 if(ifx) ifx->generated = 1;
4160 if(rFalseIfx.condition) {
4161 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4162 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4165 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4167 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4171 if(rFalseIfx.condition) {
4172 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4173 pic16_emitpLabel(truelbl->key);
4175 rFalseIfx.condition ^= 1;
4176 genSkipCond(&rFalseIfx,right,s,7);
4179 if(ifx) ifx->generated = 1;
4183 if((size == 1) && (0 == (lp1&0xff))) {
4184 /* lower byte of signed word is zero */
4185 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4186 i = ((lp1 >> 8) & 0xff) ^0x80;
4187 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4188 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4189 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4190 rFalseIfx.condition ^= 1;
4191 genSkipc(&rFalseIfx);
4194 if(ifx) ifx->generated = 1;
4198 if(lit & (0x80 << (size*8))) {
4199 /* Lit is less than zero */
4200 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4201 //rFalseIfx.condition ^= 1;
4202 //genSkipCond(&rFalseIfx,left,size,7);
4203 //rFalseIfx.condition ^= 1;
4204 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4205 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4207 if(rFalseIfx.condition)
4208 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4210 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4214 /* Lit is greater than or equal to zero */
4215 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4216 //rFalseIfx.condition ^= 1;
4217 //genSkipCond(&rFalseIfx,right,size,7);
4218 //rFalseIfx.condition ^= 1;
4220 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4221 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4223 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4224 if(rFalseIfx.condition)
4225 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4227 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4232 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4233 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4237 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4239 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4241 rFalseIfx.condition ^= 1;
4242 //rFalseIfx.condition = 1;
4243 genSkipc(&rFalseIfx);
4245 pic16_emitpLabel(truelbl->key);
4247 if(ifx) ifx->generated = 1;
4252 /* compare word or long to an unsigned literal on the right.*/
4257 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4260 break; /* handled above */
4263 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4265 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4266 genSkipz2(&rFalseIfx,0);
4270 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4272 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4275 if(rFalseIfx.condition)
4276 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4278 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4281 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4282 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4284 rFalseIfx.condition ^= 1;
4285 genSkipc(&rFalseIfx);
4288 pic16_emitpLabel(truelbl->key);
4290 if(ifx) ifx->generated = 1;
4296 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4297 i = (lit >> (size*8)) & 0xff;
4299 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4300 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4303 i = (lit >> (size*8)) & 0xff;
4306 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4308 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4310 /* this byte of the lit is zero,
4311 *if it's not the last then OR in the variable */
4313 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4318 pic16_emitpLabel(lbl->key);
4320 rFalseIfx.condition ^= 1;
4321 genSkipc(&rFalseIfx);
4325 pic16_emitpLabel(truelbl->key);
4326 if(ifx) ifx->generated = 1;
4330 /* Compare two variables */
4332 DEBUGpic16_emitcode(";sign","%d",sign);
4336 /* Sigh. thus sucks... */
4338 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4339 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4340 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4341 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4342 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4343 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4345 /* Signed char comparison */
4346 /* Special thanks to Nikolai Golovchenko for this snippet */
4347 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4348 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4349 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4350 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4351 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4352 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4354 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4355 genSkipc(&rFalseIfx);
4357 if(ifx) ifx->generated = 1;
4363 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4364 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4368 /* The rest of the bytes of a multi-byte compare */
4372 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4375 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4376 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4381 pic16_emitpLabel(lbl->key);
4383 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4384 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4385 (AOP_TYPE(result) == AOP_REG)) {
4386 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4387 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4389 genSkipc(&rFalseIfx);
4391 //genSkipc(&rFalseIfx);
4392 if(ifx) ifx->generated = 1;
4399 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4400 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4401 pic16_outBitC(result);
4403 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4404 /* if the result is used in the next
4405 ifx conditional branch then generate
4406 code a little differently */
4408 genIfxJump (ifx,"c");
4410 pic16_outBitC(result);
4411 /* leave the result in acc */
4416 /*-----------------------------------------------------------------*/
4417 /* genCmpGt :- greater than comparison */
4418 /*-----------------------------------------------------------------*/
4419 static void genCmpGt (iCode *ic, iCode *ifx)
4421 operand *left, *right, *result;
4422 sym_link *letype , *retype;
4425 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4427 right= IC_RIGHT(ic);
4428 result = IC_RESULT(ic);
4430 letype = getSpec(operandType(left));
4431 retype =getSpec(operandType(right));
4432 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4433 /* assign the amsops */
4434 pic16_aopOp (left,ic,FALSE);
4435 pic16_aopOp (right,ic,FALSE);
4436 pic16_aopOp (result,ic,TRUE);
4438 genCmp(right, left, result, ifx, sign);
4440 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4442 pic16_freeAsmop(result,NULL,ic,TRUE);
4445 /*-----------------------------------------------------------------*/
4446 /* genCmpLt - less than comparisons */
4447 /*-----------------------------------------------------------------*/
4448 static void genCmpLt (iCode *ic, iCode *ifx)
4450 operand *left, *right, *result;
4451 sym_link *letype , *retype;
4454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4456 right= IC_RIGHT(ic);
4457 result = IC_RESULT(ic);
4459 letype = getSpec(operandType(left));
4460 retype =getSpec(operandType(right));
4461 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4463 /* assign the amsops */
4464 pic16_aopOp (left,ic,FALSE);
4465 pic16_aopOp (right,ic,FALSE);
4466 pic16_aopOp (result,ic,TRUE);
4468 genCmp(left, right, result, ifx, sign);
4470 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4472 pic16_freeAsmop(result,NULL,ic,TRUE);
4475 /*-----------------------------------------------------------------*/
4476 /* genc16bit2lit - compare a 16 bit value to a literal */
4477 /*-----------------------------------------------------------------*/
4478 static void genc16bit2lit(operand *op, int lit, int offset)
4482 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4483 if( (lit&0xff) == 0)
4488 switch( BYTEofLONG(lit,i)) {
4490 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4493 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4496 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4499 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4500 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4505 switch( BYTEofLONG(lit,i)) {
4507 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4511 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4515 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4518 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4520 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4526 /*-----------------------------------------------------------------*/
4527 /* gencjneshort - compare and jump if not equal */
4528 /*-----------------------------------------------------------------*/
4529 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4531 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4533 int res_offset = 0; /* the result may be a different size then left or right */
4534 int res_size = AOP_SIZE(result);
4538 unsigned long lit = 0L;
4539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4540 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4542 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4543 resolveIfx(&rIfx,ifx);
4544 lbl = newiTempLabel(NULL);
4547 /* if the left side is a literal or
4548 if the right is in a pointer register and left
4550 if ((AOP_TYPE(left) == AOP_LIT) ||
4551 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4556 if(AOP_TYPE(right) == AOP_LIT)
4557 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4559 /* if the right side is a literal then anything goes */
4560 if (AOP_TYPE(right) == AOP_LIT &&
4561 AOP_TYPE(left) != AOP_DIR ) {
4564 genc16bit2lit(left, lit, 0);
4566 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4571 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4572 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4574 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4578 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4580 if(res_offset < res_size-1)
4588 /* if the right side is in a register or in direct space or
4589 if the left is a pointer register & right is not */
4590 else if (AOP_TYPE(right) == AOP_REG ||
4591 AOP_TYPE(right) == AOP_DIR ||
4592 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4593 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4594 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4595 int lbl_key = lbl->key;
4598 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4599 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4601 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4602 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4603 __FUNCTION__,__LINE__);
4607 /* switch(size) { */
4609 /* genc16bit2lit(left, lit, 0); */
4611 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4616 if((AOP_TYPE(left) == AOP_DIR) &&
4617 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4619 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4620 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4622 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4624 switch (lit & 0xff) {
4626 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4629 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4630 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4631 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4635 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4636 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4637 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4638 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4642 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4643 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4648 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4651 if(AOP_TYPE(result) == AOP_CRY) {
4652 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4657 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4659 /* fix me. probably need to check result size too */
4660 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4665 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4666 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4673 if(res_offset < res_size-1)
4678 } else if(AOP_TYPE(right) == AOP_REG &&
4679 AOP_TYPE(left) != AOP_DIR){
4682 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4683 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4684 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4689 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4691 if(res_offset < res_size-1)
4696 /* right is a pointer reg need both a & b */
4698 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4700 pic16_emitcode("mov","b,%s",l);
4701 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4702 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4707 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4709 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4711 pic16_emitpLabel(lbl->key);
4713 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4720 /*-----------------------------------------------------------------*/
4721 /* gencjne - compare and jump if not equal */
4722 /*-----------------------------------------------------------------*/
4723 static void gencjne(operand *left, operand *right, iCode *ifx)
4725 symbol *tlbl = newiTempLabel(NULL);
4727 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4728 gencjneshort(left, right, lbl);
4730 pic16_emitcode("mov","a,%s",one);
4731 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4732 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4733 pic16_emitcode("clr","a");
4734 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4736 pic16_emitpLabel(lbl->key);
4737 pic16_emitpLabel(tlbl->key);
4742 /*-----------------------------------------------------------------*/
4743 /* genCmpEq - generates code for equal to */
4744 /*-----------------------------------------------------------------*/
4745 static void genCmpEq (iCode *ic, iCode *ifx)
4747 operand *left, *right, *result;
4748 unsigned long lit = 0L;
4751 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4754 DEBUGpic16_emitcode ("; ifx is non-null","");
4756 DEBUGpic16_emitcode ("; ifx is null","");
4758 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4759 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4760 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4762 size = max(AOP_SIZE(left),AOP_SIZE(right));
4764 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4766 /* if literal, literal on the right or
4767 if the right is in a pointer register and left
4769 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4770 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4771 operand *tmp = right ;
4777 if(ifx && !AOP_SIZE(result)){
4779 /* if they are both bit variables */
4780 if (AOP_TYPE(left) == AOP_CRY &&
4781 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4782 if(AOP_TYPE(right) == AOP_LIT){
4783 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4785 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4786 pic16_emitcode("cpl","c");
4787 } else if(lit == 1L) {
4788 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4790 pic16_emitcode("clr","c");
4792 /* AOP_TYPE(right) == AOP_CRY */
4794 symbol *lbl = newiTempLabel(NULL);
4795 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4796 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4797 pic16_emitcode("cpl","c");
4798 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4800 /* if true label then we jump if condition
4802 tlbl = newiTempLabel(NULL);
4803 if ( IC_TRUE(ifx) ) {
4804 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4805 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4807 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4808 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4810 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4813 /* left and right are both bit variables, result is carry */
4816 resolveIfx(&rIfx,ifx);
4818 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4819 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4820 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4821 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4826 /* They're not both bit variables. Is the right a literal? */
4827 if(AOP_TYPE(right) == AOP_LIT) {
4828 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4833 switch(lit & 0xff) {
4835 if ( IC_TRUE(ifx) ) {
4836 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4838 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4840 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4841 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4845 if ( IC_TRUE(ifx) ) {
4846 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4848 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4850 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4851 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4855 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4857 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4862 /* end of size == 1 */
4866 genc16bit2lit(left,lit,offset);
4869 /* end of size == 2 */
4874 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4875 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4876 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4877 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4881 /* search for patterns that can be optimized */
4883 genc16bit2lit(left,lit,0);
4886 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4888 genc16bit2lit(left,lit,2);
4890 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4891 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4904 } else if(AOP_TYPE(right) == AOP_CRY ) {
4905 /* we know the left is not a bit, but that the right is */
4906 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4907 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4908 pic16_popGet(AOP(right),offset));
4909 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4911 /* if the two are equal, then W will be 0 and the Z bit is set
4912 * we could test Z now, or go ahead and check the high order bytes if
4913 * the variable we're comparing is larger than a byte. */
4916 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4918 if ( IC_TRUE(ifx) ) {
4920 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4921 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4924 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4925 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4929 /* They're both variables that are larger than bits */
4932 tlbl = newiTempLabel(NULL);
4935 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4936 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4938 if ( IC_TRUE(ifx) ) {
4941 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4942 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4945 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4946 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4950 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4951 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4955 if(s>1 && IC_TRUE(ifx)) {
4956 pic16_emitpLabel(tlbl->key);
4957 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4961 /* mark the icode as generated */
4966 /* if they are both bit variables */
4967 if (AOP_TYPE(left) == AOP_CRY &&
4968 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4969 if(AOP_TYPE(right) == AOP_LIT){
4970 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4972 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4973 pic16_emitcode("cpl","c");
4974 } else if(lit == 1L) {
4975 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4977 pic16_emitcode("clr","c");
4979 /* AOP_TYPE(right) == AOP_CRY */
4981 symbol *lbl = newiTempLabel(NULL);
4982 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4983 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4984 pic16_emitcode("cpl","c");
4985 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4988 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4989 pic16_outBitC(result);
4993 genIfxJump (ifx,"c");
4996 /* if the result is used in an arithmetic operation
4997 then put the result in place */
4998 pic16_outBitC(result);
5001 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5002 gencjne(left,right,result,ifx);
5005 gencjne(left,right,newiTempLabel(NULL));
5007 if(IC_TRUE(ifx)->key)
5008 gencjne(left,right,IC_TRUE(ifx)->key);
5010 gencjne(left,right,IC_FALSE(ifx)->key);
5014 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5015 pic16_aopPut(AOP(result),"a",0);
5020 genIfxJump (ifx,"a");
5024 /* if the result is used in an arithmetic operation
5025 then put the result in place */
5027 if (AOP_TYPE(result) != AOP_CRY)
5028 pic16_outAcc(result);
5030 /* leave the result in acc */
5034 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5035 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5036 pic16_freeAsmop(result,NULL,ic,TRUE);
5039 /*-----------------------------------------------------------------*/
5040 /* ifxForOp - returns the icode containing the ifx for operand */
5041 /*-----------------------------------------------------------------*/
5042 static iCode *ifxForOp ( operand *op, iCode *ic )
5044 /* if true symbol then needs to be assigned */
5045 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5046 if (IS_TRUE_SYMOP(op))
5049 /* if this has register type condition and
5050 the next instruction is ifx with the same operand
5051 and live to of the operand is upto the ifx only then */
5053 ic->next->op == IFX &&
5054 IC_COND(ic->next)->key == op->key &&
5055 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5059 ic->next->op == IFX &&
5060 IC_COND(ic->next)->key == op->key) {
5061 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5065 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5067 ic->next->op == IFX)
5068 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5071 ic->next->op == IFX &&
5072 IC_COND(ic->next)->key == op->key) {
5073 DEBUGpic16_emitcode ("; "," key is okay");
5074 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5075 OP_SYMBOL(op)->liveTo,
5082 /*-----------------------------------------------------------------*/
5083 /* genAndOp - for && operation */
5084 /*-----------------------------------------------------------------*/
5085 static void genAndOp (iCode *ic)
5087 operand *left,*right, *result;
5090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5091 /* note here that && operations that are in an
5092 if statement are taken away by backPatchLabels
5093 only those used in arthmetic operations remain */
5094 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5095 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5096 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5098 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5100 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5101 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5102 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5104 /* if both are bit variables */
5105 /* if (AOP_TYPE(left) == AOP_CRY && */
5106 /* AOP_TYPE(right) == AOP_CRY ) { */
5107 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5108 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5109 /* pic16_outBitC(result); */
5111 /* tlbl = newiTempLabel(NULL); */
5112 /* pic16_toBoolean(left); */
5113 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5114 /* pic16_toBoolean(right); */
5115 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5116 /* pic16_outBitAcc(result); */
5119 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5120 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5121 pic16_freeAsmop(result,NULL,ic,TRUE);
5125 /*-----------------------------------------------------------------*/
5126 /* genOrOp - for || operation */
5127 /*-----------------------------------------------------------------*/
5130 modified this code, but it doesn't appear to ever get called
5133 static void genOrOp (iCode *ic)
5135 operand *left,*right, *result;
5138 /* note here that || operations that are in an
5139 if statement are taken away by backPatchLabels
5140 only those used in arthmetic operations remain */
5141 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5142 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5143 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5144 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5146 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5148 /* if both are bit variables */
5149 if (AOP_TYPE(left) == AOP_CRY &&
5150 AOP_TYPE(right) == AOP_CRY ) {
5151 pic16_emitcode("clrc","");
5152 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5153 AOP(left)->aopu.aop_dir,
5154 AOP(left)->aopu.aop_dir);
5155 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5156 AOP(right)->aopu.aop_dir,
5157 AOP(right)->aopu.aop_dir);
5158 pic16_emitcode("setc","");
5161 tlbl = newiTempLabel(NULL);
5162 pic16_toBoolean(left);
5164 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5165 pic16_toBoolean(right);
5166 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5168 pic16_outBitAcc(result);
5171 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5172 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5173 pic16_freeAsmop(result,NULL,ic,TRUE);
5176 /*-----------------------------------------------------------------*/
5177 /* isLiteralBit - test if lit == 2^n */
5178 /*-----------------------------------------------------------------*/
5179 static int isLiteralBit(unsigned long lit)
5181 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5182 0x100L,0x200L,0x400L,0x800L,
5183 0x1000L,0x2000L,0x4000L,0x8000L,
5184 0x10000L,0x20000L,0x40000L,0x80000L,
5185 0x100000L,0x200000L,0x400000L,0x800000L,
5186 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5187 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5190 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5191 for(idx = 0; idx < 32; idx++)
5197 /*-----------------------------------------------------------------*/
5198 /* continueIfTrue - */
5199 /*-----------------------------------------------------------------*/
5200 static void continueIfTrue (iCode *ic)
5202 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5204 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5208 /*-----------------------------------------------------------------*/
5210 /*-----------------------------------------------------------------*/
5211 static void jumpIfTrue (iCode *ic)
5213 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5215 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5219 /*-----------------------------------------------------------------*/
5220 /* jmpTrueOrFalse - */
5221 /*-----------------------------------------------------------------*/
5222 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5224 // ugly but optimized by peephole
5225 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5227 symbol *nlbl = newiTempLabel(NULL);
5228 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5229 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5230 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5231 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5234 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5235 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5240 /*-----------------------------------------------------------------*/
5241 /* genAnd - code for and */
5242 /*-----------------------------------------------------------------*/
5243 static void genAnd (iCode *ic, iCode *ifx)
5245 operand *left, *right, *result;
5247 unsigned long lit = 0L;
5252 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5253 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5254 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5255 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5257 resolveIfx(&rIfx,ifx);
5259 /* if left is a literal & right is not then exchange them */
5260 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5261 AOP_NEEDSACC(left)) {
5262 operand *tmp = right ;
5267 /* if result = right then exchange them */
5268 if(pic16_sameRegs(AOP(result),AOP(right))){
5269 operand *tmp = right ;
5274 /* if right is bit then exchange them */
5275 if (AOP_TYPE(right) == AOP_CRY &&
5276 AOP_TYPE(left) != AOP_CRY){
5277 operand *tmp = right ;
5281 if(AOP_TYPE(right) == AOP_LIT)
5282 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5284 size = AOP_SIZE(result);
5286 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5289 // result = bit & yy;
5290 if (AOP_TYPE(left) == AOP_CRY){
5291 // c = bit & literal;
5292 if(AOP_TYPE(right) == AOP_LIT){
5294 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5297 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5300 if(size && (AOP_TYPE(result) == AOP_CRY)){
5301 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5304 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5308 pic16_emitcode("clr","c");
5311 if (AOP_TYPE(right) == AOP_CRY){
5313 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5314 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5317 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5319 pic16_emitcode("rrc","a");
5320 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5326 pic16_outBitC(result);
5328 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5329 genIfxJump(ifx, "c");
5333 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5334 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5335 if((AOP_TYPE(right) == AOP_LIT) &&
5336 (AOP_TYPE(result) == AOP_CRY) &&
5337 (AOP_TYPE(left) != AOP_CRY)){
5338 int posbit = isLiteralBit(lit);
5342 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5345 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5351 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5352 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5354 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5355 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5358 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5359 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5360 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5367 symbol *tlbl = newiTempLabel(NULL);
5368 int sizel = AOP_SIZE(left);
5370 pic16_emitcode("setb","c");
5372 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5373 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5375 if((posbit = isLiteralBit(bytelit)) != 0)
5376 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5378 if(bytelit != 0x0FFL)
5379 pic16_emitcode("anl","a,%s",
5380 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5381 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5386 // bit = left & literal
5388 pic16_emitcode("clr","c");
5389 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5391 // if(left & literal)
5394 jmpTrueOrFalse(ifx, tlbl);
5398 pic16_outBitC(result);
5402 /* if left is same as result */
5403 if(pic16_sameRegs(AOP(result),AOP(left))){
5405 for(;size--; offset++,lit>>=8) {
5406 if(AOP_TYPE(right) == AOP_LIT){
5407 switch(lit & 0xff) {
5409 /* and'ing with 0 has clears the result */
5410 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5411 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5414 /* and'ing with 0xff is a nop when the result and left are the same */
5419 int p = my_powof2( (~lit) & 0xff );
5421 /* only one bit is set in the literal, so use a bcf instruction */
5422 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5423 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5426 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5427 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5428 if(know_W != (lit&0xff))
5429 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5431 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5436 if (AOP_TYPE(left) == AOP_ACC) {
5437 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5439 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5440 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5447 // left & result in different registers
5448 if(AOP_TYPE(result) == AOP_CRY){
5450 // if(size), result in bit
5451 // if(!size && ifx), conditional oper: if(left & right)
5452 symbol *tlbl = newiTempLabel(NULL);
5453 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5455 pic16_emitcode("setb","c");
5457 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5458 pic16_emitcode("anl","a,%s",
5459 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5460 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5465 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5466 pic16_outBitC(result);
5468 jmpTrueOrFalse(ifx, tlbl);
5470 for(;(size--);offset++) {
5472 // result = left & right
5473 if(AOP_TYPE(right) == AOP_LIT){
5474 int t = (lit >> (offset*8)) & 0x0FFL;
5477 pic16_emitcode("clrf","%s",
5478 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5479 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5482 pic16_emitcode("movf","%s,w",
5483 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5484 pic16_emitcode("movwf","%s",
5485 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5486 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5487 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5490 pic16_emitcode("movlw","0x%x",t);
5491 pic16_emitcode("andwf","%s,w",
5492 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5493 pic16_emitcode("movwf","%s",
5494 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5496 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5497 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5498 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5503 if (AOP_TYPE(left) == AOP_ACC) {
5504 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5505 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5507 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5508 pic16_emitcode("andwf","%s,w",
5509 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5510 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5511 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5513 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5514 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5520 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5521 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5522 pic16_freeAsmop(result,NULL,ic,TRUE);
5525 /*-----------------------------------------------------------------*/
5526 /* genOr - code for or */
5527 /*-----------------------------------------------------------------*/
5528 static void genOr (iCode *ic, iCode *ifx)
5530 operand *left, *right, *result;
5532 unsigned long lit = 0L;
5534 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5536 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5537 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5538 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5540 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5542 /* if left is a literal & right is not then exchange them */
5543 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5544 AOP_NEEDSACC(left)) {
5545 operand *tmp = right ;
5550 /* if result = right then exchange them */
5551 if(pic16_sameRegs(AOP(result),AOP(right))){
5552 operand *tmp = right ;
5557 /* if right is bit then exchange them */
5558 if (AOP_TYPE(right) == AOP_CRY &&
5559 AOP_TYPE(left) != AOP_CRY){
5560 operand *tmp = right ;
5565 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5567 if(AOP_TYPE(right) == AOP_LIT)
5568 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5570 size = AOP_SIZE(result);
5574 if (AOP_TYPE(left) == AOP_CRY){
5575 if(AOP_TYPE(right) == AOP_LIT){
5576 // c = bit & literal;
5578 // lit != 0 => result = 1
5579 if(AOP_TYPE(result) == AOP_CRY){
5581 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5582 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5583 // AOP(result)->aopu.aop_dir,
5584 // AOP(result)->aopu.aop_dir);
5586 continueIfTrue(ifx);
5590 // lit == 0 => result = left
5591 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5593 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5596 if (AOP_TYPE(right) == AOP_CRY){
5597 if(pic16_sameRegs(AOP(result),AOP(left))){
5599 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5600 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5601 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5603 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5604 AOP(result)->aopu.aop_dir,
5605 AOP(result)->aopu.aop_dir);
5606 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5607 AOP(right)->aopu.aop_dir,
5608 AOP(right)->aopu.aop_dir);
5609 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5610 AOP(result)->aopu.aop_dir,
5611 AOP(result)->aopu.aop_dir);
5613 if( AOP_TYPE(result) == AOP_ACC) {
5614 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5615 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5616 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5617 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5621 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5622 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5623 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5624 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5626 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5627 AOP(result)->aopu.aop_dir,
5628 AOP(result)->aopu.aop_dir);
5629 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5630 AOP(right)->aopu.aop_dir,
5631 AOP(right)->aopu.aop_dir);
5632 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5633 AOP(left)->aopu.aop_dir,
5634 AOP(left)->aopu.aop_dir);
5635 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5636 AOP(result)->aopu.aop_dir,
5637 AOP(result)->aopu.aop_dir);
5642 symbol *tlbl = newiTempLabel(NULL);
5643 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5646 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5647 if( AOP_TYPE(right) == AOP_ACC) {
5648 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5650 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5651 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5656 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5657 pic16_emitcode(";XXX setb","c");
5658 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5659 AOP(left)->aopu.aop_dir,tlbl->key+100);
5660 pic16_toBoolean(right);
5661 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5662 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5663 jmpTrueOrFalse(ifx, tlbl);
5667 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5674 pic16_outBitC(result);
5676 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5677 genIfxJump(ifx, "c");
5681 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5682 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5683 if((AOP_TYPE(right) == AOP_LIT) &&
5684 (AOP_TYPE(result) == AOP_CRY) &&
5685 (AOP_TYPE(left) != AOP_CRY)){
5687 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5690 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5692 continueIfTrue(ifx);
5695 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5696 // lit = 0, result = boolean(left)
5698 pic16_emitcode(";XXX setb","c");
5699 pic16_toBoolean(right);
5701 symbol *tlbl = newiTempLabel(NULL);
5702 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5704 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5706 genIfxJump (ifx,"a");
5710 pic16_outBitC(result);
5714 /* if left is same as result */
5715 if(pic16_sameRegs(AOP(result),AOP(left))){
5717 for(;size--; offset++,lit>>=8) {
5718 if(AOP_TYPE(right) == AOP_LIT){
5719 if((lit & 0xff) == 0)
5720 /* or'ing with 0 has no effect */
5723 int p = my_powof2(lit & 0xff);
5725 /* only one bit is set in the literal, so use a bsf instruction */
5726 pic16_emitpcode(POC_BSF,
5727 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5729 if(know_W != (lit & 0xff))
5730 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5731 know_W = lit & 0xff;
5732 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5737 if (AOP_TYPE(left) == AOP_ACC) {
5738 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5739 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5741 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5742 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5744 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5745 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5751 // left & result in different registers
5752 if(AOP_TYPE(result) == AOP_CRY){
5754 // if(size), result in bit
5755 // if(!size && ifx), conditional oper: if(left | right)
5756 symbol *tlbl = newiTempLabel(NULL);
5757 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5758 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5762 pic16_emitcode(";XXX setb","c");
5764 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5765 pic16_emitcode(";XXX orl","a,%s",
5766 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5767 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5772 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5773 pic16_outBitC(result);
5775 jmpTrueOrFalse(ifx, tlbl);
5776 } else for(;(size--);offset++){
5778 // result = left & right
5779 if(AOP_TYPE(right) == AOP_LIT){
5780 int t = (lit >> (offset*8)) & 0x0FFL;
5783 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5784 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5786 pic16_emitcode("movf","%s,w",
5787 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5788 pic16_emitcode("movwf","%s",
5789 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5792 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5793 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5794 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5796 pic16_emitcode("movlw","0x%x",t);
5797 pic16_emitcode("iorwf","%s,w",
5798 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5799 pic16_emitcode("movwf","%s",
5800 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5806 // faster than result <- left, anl result,right
5807 // and better if result is SFR
5808 if (AOP_TYPE(left) == AOP_ACC) {
5809 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5810 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5812 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5813 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5815 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5816 pic16_emitcode("iorwf","%s,w",
5817 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5819 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5820 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5825 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5826 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5827 pic16_freeAsmop(result,NULL,ic,TRUE);
5830 /*-----------------------------------------------------------------*/
5831 /* genXor - code for xclusive or */
5832 /*-----------------------------------------------------------------*/
5833 static void genXor (iCode *ic, iCode *ifx)
5835 operand *left, *right, *result;
5837 unsigned long lit = 0L;
5839 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5841 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5842 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5843 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5845 /* if left is a literal & right is not ||
5846 if left needs acc & right does not */
5847 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5848 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5849 operand *tmp = right ;
5854 /* if result = right then exchange them */
5855 if(pic16_sameRegs(AOP(result),AOP(right))){
5856 operand *tmp = right ;
5861 /* if right is bit then exchange them */
5862 if (AOP_TYPE(right) == AOP_CRY &&
5863 AOP_TYPE(left) != AOP_CRY){
5864 operand *tmp = right ;
5868 if(AOP_TYPE(right) == AOP_LIT)
5869 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5871 size = AOP_SIZE(result);
5875 if (AOP_TYPE(left) == AOP_CRY){
5876 if(AOP_TYPE(right) == AOP_LIT){
5877 // c = bit & literal;
5879 // lit>>1 != 0 => result = 1
5880 if(AOP_TYPE(result) == AOP_CRY){
5882 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
5883 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5885 continueIfTrue(ifx);
5888 pic16_emitcode("setb","c");
5892 // lit == 0, result = left
5893 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5895 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5897 // lit == 1, result = not(left)
5898 if(size && pic16_sameRegs(AOP(result),AOP(left))){
5899 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
5900 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
5901 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5904 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5905 pic16_emitcode("cpl","c");
5912 symbol *tlbl = newiTempLabel(NULL);
5913 if (AOP_TYPE(right) == AOP_CRY){
5915 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5918 int sizer = AOP_SIZE(right);
5920 // if val>>1 != 0, result = 1
5921 pic16_emitcode("setb","c");
5923 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5925 // test the msb of the lsb
5926 pic16_emitcode("anl","a,#0xfe");
5927 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5931 pic16_emitcode("rrc","a");
5933 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5934 pic16_emitcode("cpl","c");
5935 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5940 pic16_outBitC(result);
5942 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5943 genIfxJump(ifx, "c");
5947 if(pic16_sameRegs(AOP(result),AOP(left))){
5948 /* if left is same as result */
5949 for(;size--; offset++) {
5950 if(AOP_TYPE(right) == AOP_LIT){
5951 int t = (lit >> (offset*8)) & 0x0FFL;
5955 if (IS_AOP_PREG(left)) {
5956 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5957 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5958 pic16_aopPut(AOP(result),"a",offset);
5960 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5961 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5962 pic16_emitcode("xrl","%s,%s",
5963 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5964 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5967 if (AOP_TYPE(left) == AOP_ACC)
5968 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5970 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5971 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5973 if (IS_AOP_PREG(left)) {
5974 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5975 pic16_aopPut(AOP(result),"a",offset);
5977 pic16_emitcode("xrl","%s,a",
5978 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5984 // left & result in different registers
5985 if(AOP_TYPE(result) == AOP_CRY){
5987 // if(size), result in bit
5988 // if(!size && ifx), conditional oper: if(left ^ right)
5989 symbol *tlbl = newiTempLabel(NULL);
5990 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5992 pic16_emitcode("setb","c");
5994 if((AOP_TYPE(right) == AOP_LIT) &&
5995 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5996 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5998 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5999 pic16_emitcode("xrl","a,%s",
6000 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6002 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6007 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6008 pic16_outBitC(result);
6010 jmpTrueOrFalse(ifx, tlbl);
6011 } else for(;(size--);offset++){
6013 // result = left & right
6014 if(AOP_TYPE(right) == AOP_LIT){
6015 int t = (lit >> (offset*8)) & 0x0FFL;
6018 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6019 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6020 pic16_emitcode("movf","%s,w",
6021 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6022 pic16_emitcode("movwf","%s",
6023 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6026 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6027 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6028 pic16_emitcode("comf","%s,w",
6029 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6030 pic16_emitcode("movwf","%s",
6031 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6034 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6035 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6036 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6037 pic16_emitcode("movlw","0x%x",t);
6038 pic16_emitcode("xorwf","%s,w",
6039 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6040 pic16_emitcode("movwf","%s",
6041 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6047 // faster than result <- left, anl result,right
6048 // and better if result is SFR
6049 if (AOP_TYPE(left) == AOP_ACC) {
6050 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6051 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6053 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6054 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6055 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6056 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6058 if ( AOP_TYPE(result) != AOP_ACC){
6059 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6060 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6066 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6067 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6068 pic16_freeAsmop(result,NULL,ic,TRUE);
6071 /*-----------------------------------------------------------------*/
6072 /* genInline - write the inline code out */
6073 /*-----------------------------------------------------------------*/
6074 static void genInline (iCode *ic)
6076 char *buffer, *bp, *bp1;
6078 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6080 _G.inLine += (!options.asmpeep);
6082 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6083 strcpy(buffer,IC_INLINE(ic));
6085 /* emit each line as a code */
6091 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6098 pic16_emitcode(bp1,"");
6104 if ((bp1 != bp) && *bp1)
6105 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6109 _G.inLine -= (!options.asmpeep);
6112 /*-----------------------------------------------------------------*/
6113 /* genRRC - rotate right with carry */
6114 /*-----------------------------------------------------------------*/
6115 static void genRRC (iCode *ic)
6117 operand *left , *result ;
6118 int size, offset = 0, same;
6120 /* rotate right with carry */
6122 result=IC_RESULT(ic);
6123 pic16_aopOp (left,ic,FALSE);
6124 pic16_aopOp (result,ic,FALSE);
6126 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6128 same = pic16_sameRegs(AOP(result),AOP(left));
6130 size = AOP_SIZE(result);
6132 /* get the lsb and put it into the carry */
6133 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6140 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6142 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6143 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6149 pic16_freeAsmop(left,NULL,ic,TRUE);
6150 pic16_freeAsmop(result,NULL,ic,TRUE);
6153 /*-----------------------------------------------------------------*/
6154 /* genRLC - generate code for rotate left with carry */
6155 /*-----------------------------------------------------------------*/
6156 static void genRLC (iCode *ic)
6158 operand *left , *result ;
6159 int size, offset = 0;
6162 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6163 /* rotate right with carry */
6165 result=IC_RESULT(ic);
6166 pic16_aopOp (left,ic,FALSE);
6167 pic16_aopOp (result,ic,FALSE);
6169 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6171 same = pic16_sameRegs(AOP(result),AOP(left));
6173 /* move it to the result */
6174 size = AOP_SIZE(result);
6176 /* get the msb and put it into the carry */
6177 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6184 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6186 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6187 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6194 pic16_freeAsmop(left,NULL,ic,TRUE);
6195 pic16_freeAsmop(result,NULL,ic,TRUE);
6198 /*-----------------------------------------------------------------*/
6199 /* genGetHbit - generates code get highest order bit */
6200 /*-----------------------------------------------------------------*/
6201 static void genGetHbit (iCode *ic)
6203 operand *left, *result;
6205 result=IC_RESULT(ic);
6206 pic16_aopOp (left,ic,FALSE);
6207 pic16_aopOp (result,ic,FALSE);
6209 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6210 /* get the highest order byte into a */
6211 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6212 if(AOP_TYPE(result) == AOP_CRY){
6213 pic16_emitcode("rlc","a");
6214 pic16_outBitC(result);
6217 pic16_emitcode("rl","a");
6218 pic16_emitcode("anl","a,#0x01");
6219 pic16_outAcc(result);
6223 pic16_freeAsmop(left,NULL,ic,TRUE);
6224 pic16_freeAsmop(result,NULL,ic,TRUE);
6227 /*-----------------------------------------------------------------*/
6228 /* AccRol - rotate left accumulator by known count */
6229 /*-----------------------------------------------------------------*/
6230 static void AccRol (int shCount)
6232 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6233 shCount &= 0x0007; // shCount : 0..7
6238 pic16_emitcode("rl","a");
6241 pic16_emitcode("rl","a");
6242 pic16_emitcode("rl","a");
6245 pic16_emitcode("swap","a");
6246 pic16_emitcode("rr","a");
6249 pic16_emitcode("swap","a");
6252 pic16_emitcode("swap","a");
6253 pic16_emitcode("rl","a");
6256 pic16_emitcode("rr","a");
6257 pic16_emitcode("rr","a");
6260 pic16_emitcode("rr","a");
6265 /*-----------------------------------------------------------------*/
6266 /* AccLsh - left shift accumulator by known count */
6267 /*-----------------------------------------------------------------*/
6268 static void AccLsh (int shCount)
6270 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6273 pic16_emitcode("add","a,acc");
6276 pic16_emitcode("add","a,acc");
6277 pic16_emitcode("add","a,acc");
6279 /* rotate left accumulator */
6281 /* and kill the lower order bits */
6282 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6287 /*-----------------------------------------------------------------*/
6288 /* AccRsh - right shift accumulator by known count */
6289 /*-----------------------------------------------------------------*/
6290 static void AccRsh (int shCount)
6292 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6296 pic16_emitcode("rrc","a");
6298 /* rotate right accumulator */
6299 AccRol(8 - shCount);
6300 /* and kill the higher order bits */
6301 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6307 /*-----------------------------------------------------------------*/
6308 /* AccSRsh - signed right shift accumulator by known count */
6309 /*-----------------------------------------------------------------*/
6310 static void AccSRsh (int shCount)
6313 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6316 pic16_emitcode("mov","c,acc.7");
6317 pic16_emitcode("rrc","a");
6318 } else if(shCount == 2){
6319 pic16_emitcode("mov","c,acc.7");
6320 pic16_emitcode("rrc","a");
6321 pic16_emitcode("mov","c,acc.7");
6322 pic16_emitcode("rrc","a");
6324 tlbl = newiTempLabel(NULL);
6325 /* rotate right accumulator */
6326 AccRol(8 - shCount);
6327 /* and kill the higher order bits */
6328 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6329 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6330 pic16_emitcode("orl","a,#0x%02x",
6331 (unsigned char)~SRMask[shCount]);
6332 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6337 /*-----------------------------------------------------------------*/
6338 /* shiftR1Left2Result - shift right one byte from left to result */
6339 /*-----------------------------------------------------------------*/
6340 static void shiftR1Left2ResultSigned (operand *left, int offl,
6341 operand *result, int offr,
6346 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6348 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6352 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6354 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6356 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6357 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6363 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6365 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6367 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6368 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6370 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6371 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6377 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6379 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6380 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6383 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6384 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6385 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6387 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6388 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6390 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6394 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6395 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6396 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6397 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6398 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6402 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6404 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6405 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6407 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6408 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6409 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6410 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6411 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6416 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6417 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6418 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6419 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6420 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6421 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6423 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6424 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6425 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6426 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6427 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6433 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6434 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6435 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6436 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6438 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6439 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6440 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6448 /*-----------------------------------------------------------------*/
6449 /* shiftR1Left2Result - shift right one byte from left to result */
6450 /*-----------------------------------------------------------------*/
6451 static void shiftR1Left2Result (operand *left, int offl,
6452 operand *result, int offr,
6453 int shCount, int sign)
6457 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6459 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6461 /* Copy the msb into the carry if signed. */
6463 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6473 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6475 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6476 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6482 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6484 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6485 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6488 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6493 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6495 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6496 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6499 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6500 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6501 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6502 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6506 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6507 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6508 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6512 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6513 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6514 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6516 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6521 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6522 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6523 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6524 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6525 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6530 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6531 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6532 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6541 /*-----------------------------------------------------------------*/
6542 /* shiftL1Left2Result - shift left one byte from left to result */
6543 /*-----------------------------------------------------------------*/
6544 static void shiftL1Left2Result (operand *left, int offl,
6545 operand *result, int offr, int shCount)
6550 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6552 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6553 DEBUGpic16_emitcode ("; ***","same = %d",same);
6554 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6556 /* shift left accumulator */
6557 //AccLsh(shCount); // don't comment out just yet...
6558 // pic16_aopPut(AOP(result),"a",offr);
6562 /* Shift left 1 bit position */
6563 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6565 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6567 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6568 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6572 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6573 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6574 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6575 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6578 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6579 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6580 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6581 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6582 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6585 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6586 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6587 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6590 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6591 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6592 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6593 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6596 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6597 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6598 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6599 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6600 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6603 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6604 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6605 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6609 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6614 /*-----------------------------------------------------------------*/
6615 /* movLeft2Result - move byte from left to result */
6616 /*-----------------------------------------------------------------*/
6617 static void movLeft2Result (operand *left, int offl,
6618 operand *result, int offr)
6621 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6622 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6623 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6625 if (*l == '@' && (IS_AOP_PREG(result))) {
6626 pic16_emitcode("mov","a,%s",l);
6627 pic16_aopPut(AOP(result),"a",offr);
6629 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6630 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6635 /*-----------------------------------------------------------------*/
6636 /* shiftL2Left2Result - shift left two bytes from left to result */
6637 /*-----------------------------------------------------------------*/
6638 static void shiftL2Left2Result (operand *left, int offl,
6639 operand *result, int offr, int shCount)
6643 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6645 if(pic16_sameRegs(AOP(result), AOP(left))) {
6653 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6654 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6655 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6659 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6660 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6666 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6667 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6668 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6669 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6670 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6671 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6672 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6674 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6675 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6679 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6680 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6681 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6682 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6683 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6684 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6685 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6686 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6687 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6688 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6691 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6692 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6693 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6694 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6695 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6705 /* note, use a mov/add for the shift since the mov has a
6706 chance of getting optimized out */
6707 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6708 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6709 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6710 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6711 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6715 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6716 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6722 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6723 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6724 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6725 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6726 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6727 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6728 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6729 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6733 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6734 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6738 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6739 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6740 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6741 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6743 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6744 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6745 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6746 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6747 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6748 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6749 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6750 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6753 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6754 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6755 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6756 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6757 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6762 /*-----------------------------------------------------------------*/
6763 /* shiftR2Left2Result - shift right two bytes from left to result */
6764 /*-----------------------------------------------------------------*/
6765 static void shiftR2Left2Result (operand *left, int offl,
6766 operand *result, int offr,
6767 int shCount, int sign)
6771 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6772 same = pic16_sameRegs(AOP(result), AOP(left));
6774 if(same && ((offl + MSB16) == offr)){
6776 /* don't crash result[offr] */
6777 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6778 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6781 movLeft2Result(left,offl, result, offr);
6782 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6785 /* a:x >> shCount (x = lsb(result))*/
6788 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6790 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6799 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6804 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6805 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6807 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6808 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6809 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6810 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6815 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6818 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6819 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6826 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6827 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6828 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6830 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6831 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6832 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6833 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6835 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6836 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6837 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6839 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6840 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6841 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6842 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6843 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6847 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6848 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6852 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6853 pic16_emitpcode(POC_BTFSC,
6854 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6855 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6863 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6864 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6866 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6867 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6868 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6869 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6871 pic16_emitpcode(POC_BTFSC,
6872 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6873 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6875 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6876 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6877 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6878 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6880 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6881 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6882 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6883 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6884 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6885 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6886 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6887 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6889 pic16_emitpcode(POC_BTFSC,
6890 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6891 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6893 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6894 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6901 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6902 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6903 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6904 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6907 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6909 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6914 /*-----------------------------------------------------------------*/
6915 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6916 /*-----------------------------------------------------------------*/
6917 static void shiftLLeftOrResult (operand *left, int offl,
6918 operand *result, int offr, int shCount)
6920 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6921 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6922 /* shift left accumulator */
6924 /* or with result */
6925 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6926 /* back to result */
6927 pic16_aopPut(AOP(result),"a",offr);
6930 /*-----------------------------------------------------------------*/
6931 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6932 /*-----------------------------------------------------------------*/
6933 static void shiftRLeftOrResult (operand *left, int offl,
6934 operand *result, int offr, int shCount)
6936 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6937 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6938 /* shift right accumulator */
6940 /* or with result */
6941 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6942 /* back to result */
6943 pic16_aopPut(AOP(result),"a",offr);
6946 /*-----------------------------------------------------------------*/
6947 /* genlshOne - left shift a one byte quantity by known count */
6948 /*-----------------------------------------------------------------*/
6949 static void genlshOne (operand *result, operand *left, int shCount)
6951 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6952 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6955 /*-----------------------------------------------------------------*/
6956 /* genlshTwo - left shift two bytes by known amount != 0 */
6957 /*-----------------------------------------------------------------*/
6958 static void genlshTwo (operand *result,operand *left, int shCount)
6962 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6963 size = pic16_getDataSize(result);
6965 /* if shCount >= 8 */
6971 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6973 movLeft2Result(left, LSB, result, MSB16);
6975 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6978 /* 1 <= shCount <= 7 */
6981 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6983 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6987 /*-----------------------------------------------------------------*/
6988 /* shiftLLong - shift left one long from left to result */
6989 /* offl = LSB or MSB16 */
6990 /*-----------------------------------------------------------------*/
6991 static void shiftLLong (operand *left, operand *result, int offr )
6994 int size = AOP_SIZE(result);
6996 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6997 if(size >= LSB+offr){
6998 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7000 pic16_emitcode("add","a,acc");
7001 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7002 size >= MSB16+offr && offr != LSB )
7003 pic16_emitcode("xch","a,%s",
7004 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7006 pic16_aopPut(AOP(result),"a",LSB+offr);
7009 if(size >= MSB16+offr){
7010 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7011 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7014 pic16_emitcode("rlc","a");
7015 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7016 size >= MSB24+offr && offr != LSB)
7017 pic16_emitcode("xch","a,%s",
7018 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7020 pic16_aopPut(AOP(result),"a",MSB16+offr);
7023 if(size >= MSB24+offr){
7024 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7025 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7028 pic16_emitcode("rlc","a");
7029 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7030 size >= MSB32+offr && offr != LSB )
7031 pic16_emitcode("xch","a,%s",
7032 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7034 pic16_aopPut(AOP(result),"a",MSB24+offr);
7037 if(size > MSB32+offr){
7038 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7039 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7042 pic16_emitcode("rlc","a");
7043 pic16_aopPut(AOP(result),"a",MSB32+offr);
7046 pic16_aopPut(AOP(result),zero,LSB);
7049 /*-----------------------------------------------------------------*/
7050 /* genlshFour - shift four byte by a known amount != 0 */
7051 /*-----------------------------------------------------------------*/
7052 static void genlshFour (operand *result, operand *left, int shCount)
7056 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7057 size = AOP_SIZE(result);
7059 /* if shifting more that 3 bytes */
7060 if (shCount >= 24 ) {
7063 /* lowest order of left goes to the highest
7064 order of the destination */
7065 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7067 movLeft2Result(left, LSB, result, MSB32);
7068 pic16_aopPut(AOP(result),zero,LSB);
7069 pic16_aopPut(AOP(result),zero,MSB16);
7070 pic16_aopPut(AOP(result),zero,MSB32);
7074 /* more than two bytes */
7075 else if ( shCount >= 16 ) {
7076 /* lower order two bytes goes to higher order two bytes */
7078 /* if some more remaining */
7080 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7082 movLeft2Result(left, MSB16, result, MSB32);
7083 movLeft2Result(left, LSB, result, MSB24);
7085 pic16_aopPut(AOP(result),zero,MSB16);
7086 pic16_aopPut(AOP(result),zero,LSB);
7090 /* if more than 1 byte */
7091 else if ( shCount >= 8 ) {
7092 /* lower order three bytes goes to higher order three bytes */
7096 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7098 movLeft2Result(left, LSB, result, MSB16);
7100 else{ /* size = 4 */
7102 movLeft2Result(left, MSB24, result, MSB32);
7103 movLeft2Result(left, MSB16, result, MSB24);
7104 movLeft2Result(left, LSB, result, MSB16);
7105 pic16_aopPut(AOP(result),zero,LSB);
7107 else if(shCount == 1)
7108 shiftLLong(left, result, MSB16);
7110 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7111 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7112 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7113 pic16_aopPut(AOP(result),zero,LSB);
7118 /* 1 <= shCount <= 7 */
7119 else if(shCount <= 2){
7120 shiftLLong(left, result, LSB);
7122 shiftLLong(result, result, LSB);
7124 /* 3 <= shCount <= 7, optimize */
7126 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7127 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7128 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7132 /*-----------------------------------------------------------------*/
7133 /* genLeftShiftLiteral - left shifting by known count */
7134 /*-----------------------------------------------------------------*/
7135 static void genLeftShiftLiteral (operand *left,
7140 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7143 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7144 pic16_freeAsmop(right,NULL,ic,TRUE);
7146 pic16_aopOp(left,ic,FALSE);
7147 pic16_aopOp(result,ic,FALSE);
7149 size = getSize(operandType(result));
7152 pic16_emitcode("; shift left ","result %d, left %d",size,
7156 /* I suppose that the left size >= result size */
7159 movLeft2Result(left, size, result, size);
7163 else if(shCount >= (size * 8))
7165 pic16_aopPut(AOP(result),zero,size);
7169 genlshOne (result,left,shCount);
7174 genlshTwo (result,left,shCount);
7178 genlshFour (result,left,shCount);
7182 pic16_freeAsmop(left,NULL,ic,TRUE);
7183 pic16_freeAsmop(result,NULL,ic,TRUE);
7186 /*-----------------------------------------------------------------*
7187 * genMultiAsm - repeat assembly instruction for size of register.
7188 * if endian == 1, then the high byte (i.e base address + size of
7189 * register) is used first else the low byte is used first;
7190 *-----------------------------------------------------------------*/
7191 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7209 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7214 /*-----------------------------------------------------------------*/
7215 /* genLeftShift - generates code for left shifting */
7216 /*-----------------------------------------------------------------*/
7217 static void genLeftShift (iCode *ic)
7219 operand *left,*right, *result;
7222 symbol *tlbl , *tlbl1;
7225 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7227 right = IC_RIGHT(ic);
7229 result = IC_RESULT(ic);
7231 pic16_aopOp(right,ic,FALSE);
7233 /* if the shift count is known then do it
7234 as efficiently as possible */
7235 if (AOP_TYPE(right) == AOP_LIT) {
7236 genLeftShiftLiteral (left,right,result,ic);
7240 /* shift count is unknown then we have to form
7241 a loop get the loop count in B : Note: we take
7242 only the lower order byte since shifting
7243 more that 32 bits make no sense anyway, ( the
7244 largest size of an object can be only 32 bits ) */
7247 pic16_aopOp(left,ic,FALSE);
7248 pic16_aopOp(result,ic,FALSE);
7250 /* now move the left to the result if they are not the
7252 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7253 AOP_SIZE(result) > 1) {
7255 size = AOP_SIZE(result);
7258 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7259 if (*l == '@' && (IS_AOP_PREG(result))) {
7261 pic16_emitcode("mov","a,%s",l);
7262 pic16_aopPut(AOP(result),"a",offset);
7264 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7265 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7266 //pic16_aopPut(AOP(result),l,offset);
7272 size = AOP_SIZE(result);
7274 /* if it is only one byte then */
7276 if(optimized_for_speed) {
7277 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7278 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7279 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7280 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7281 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7282 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7283 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7284 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7285 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7286 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7287 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7288 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7291 tlbl = newiTempLabel(NULL);
7292 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7293 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7294 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7297 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7298 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7299 pic16_emitpLabel(tlbl->key);
7300 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7301 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7303 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7308 if (pic16_sameRegs(AOP(left),AOP(result))) {
7310 tlbl = newiTempLabel(NULL);
7311 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7312 genMultiAsm(POC_RRCF, result, size,1);
7313 pic16_emitpLabel(tlbl->key);
7314 genMultiAsm(POC_RLCF, result, size,0);
7315 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7317 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7321 //tlbl = newiTempLabel(NULL);
7323 //tlbl1 = newiTempLabel(NULL);
7325 //reAdjustPreg(AOP(result));
7327 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7328 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7329 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7331 //pic16_emitcode("add","a,acc");
7332 //pic16_aopPut(AOP(result),"a",offset++);
7334 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7336 // pic16_emitcode("rlc","a");
7337 // pic16_aopPut(AOP(result),"a",offset++);
7339 //reAdjustPreg(AOP(result));
7341 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7342 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7345 tlbl = newiTempLabel(NULL);
7346 tlbl1= newiTempLabel(NULL);
7348 size = AOP_SIZE(result);
7351 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7353 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7355 /* offset should be 0, 1 or 3 */
7356 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7358 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7360 pic16_emitpcode(POC_MOVWF, pctemp);
7363 pic16_emitpLabel(tlbl->key);
7366 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7368 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7370 pic16_emitpcode(POC_DECFSZ, pctemp);
7371 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7372 pic16_emitpLabel(tlbl1->key);
7374 pic16_popReleaseTempReg(pctemp);
7378 pic16_freeAsmop (right,NULL,ic,TRUE);
7379 pic16_freeAsmop(left,NULL,ic,TRUE);
7380 pic16_freeAsmop(result,NULL,ic,TRUE);
7383 /*-----------------------------------------------------------------*/
7384 /* genrshOne - right shift a one byte quantity by known count */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshOne (operand *result, operand *left,
7387 int shCount, int sign)
7389 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7390 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7393 /*-----------------------------------------------------------------*/
7394 /* genrshTwo - right shift two bytes by known amount != 0 */
7395 /*-----------------------------------------------------------------*/
7396 static void genrshTwo (operand *result,operand *left,
7397 int shCount, int sign)
7399 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7400 /* if shCount >= 8 */
7404 shiftR1Left2Result(left, MSB16, result, LSB,
7407 movLeft2Result(left, MSB16, result, LSB);
7409 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7412 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7413 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7417 /* 1 <= shCount <= 7 */
7419 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7422 /*-----------------------------------------------------------------*/
7423 /* shiftRLong - shift right one long from left to result */
7424 /* offl = LSB or MSB16 */
7425 /*-----------------------------------------------------------------*/
7426 static void shiftRLong (operand *left, int offl,
7427 operand *result, int sign)
7429 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7431 pic16_emitcode("clr","c");
7432 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7434 pic16_emitcode("mov","c,acc.7");
7435 pic16_emitcode("rrc","a");
7436 pic16_aopPut(AOP(result),"a",MSB32-offl);
7438 /* add sign of "a" */
7439 pic16_addSign(result, MSB32, sign);
7441 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7442 pic16_emitcode("rrc","a");
7443 pic16_aopPut(AOP(result),"a",MSB24-offl);
7445 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7446 pic16_emitcode("rrc","a");
7447 pic16_aopPut(AOP(result),"a",MSB16-offl);
7450 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7451 pic16_emitcode("rrc","a");
7452 pic16_aopPut(AOP(result),"a",LSB);
7456 /*-----------------------------------------------------------------*/
7457 /* genrshFour - shift four byte by a known amount != 0 */
7458 /*-----------------------------------------------------------------*/
7459 static void genrshFour (operand *result, operand *left,
7460 int shCount, int sign)
7462 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7463 /* if shifting more that 3 bytes */
7464 if(shCount >= 24 ) {
7467 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7469 movLeft2Result(left, MSB32, result, LSB);
7471 pic16_addSign(result, MSB16, sign);
7473 else if(shCount >= 16){
7476 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7478 movLeft2Result(left, MSB24, result, LSB);
7479 movLeft2Result(left, MSB32, result, MSB16);
7481 pic16_addSign(result, MSB24, sign);
7483 else if(shCount >= 8){
7486 shiftRLong(left, MSB16, result, sign);
7487 else if(shCount == 0){
7488 movLeft2Result(left, MSB16, result, LSB);
7489 movLeft2Result(left, MSB24, result, MSB16);
7490 movLeft2Result(left, MSB32, result, MSB24);
7491 pic16_addSign(result, MSB32, sign);
7494 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7495 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7496 /* the last shift is signed */
7497 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7498 pic16_addSign(result, MSB32, sign);
7501 else{ /* 1 <= shCount <= 7 */
7503 shiftRLong(left, LSB, result, sign);
7505 shiftRLong(result, LSB, result, sign);
7508 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7509 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7510 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7515 /*-----------------------------------------------------------------*/
7516 /* genRightShiftLiteral - right shifting by known count */
7517 /*-----------------------------------------------------------------*/
7518 static void genRightShiftLiteral (operand *left,
7524 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7527 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7528 pic16_freeAsmop(right,NULL,ic,TRUE);
7530 pic16_aopOp(left,ic,FALSE);
7531 pic16_aopOp(result,ic,FALSE);
7534 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7538 lsize = pic16_getDataSize(left);
7539 res_size = pic16_getDataSize(result);
7540 /* test the LEFT size !!! */
7542 /* I suppose that the left size >= result size */
7545 movLeft2Result(left, lsize, result, res_size);
7548 else if(shCount >= (lsize * 8)){
7551 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7553 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7554 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7559 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7560 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7561 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7563 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7568 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7575 genrshOne (result,left,shCount,sign);
7579 genrshTwo (result,left,shCount,sign);
7583 genrshFour (result,left,shCount,sign);
7591 pic16_freeAsmop(left,NULL,ic,TRUE);
7592 pic16_freeAsmop(result,NULL,ic,TRUE);
7595 /*-----------------------------------------------------------------*/
7596 /* genSignedRightShift - right shift of signed number */
7597 /*-----------------------------------------------------------------*/
7598 static void genSignedRightShift (iCode *ic)
7600 operand *right, *left, *result;
7603 symbol *tlbl, *tlbl1 ;
7606 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7608 /* we do it the hard way put the shift count in b
7609 and loop thru preserving the sign */
7610 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7612 right = IC_RIGHT(ic);
7614 result = IC_RESULT(ic);
7616 pic16_aopOp(right,ic,FALSE);
7617 pic16_aopOp(left,ic,FALSE);
7618 pic16_aopOp(result,ic,FALSE);
7621 if ( AOP_TYPE(right) == AOP_LIT) {
7622 genRightShiftLiteral (left,right,result,ic,1);
7625 /* shift count is unknown then we have to form
7626 a loop get the loop count in B : Note: we take
7627 only the lower order byte since shifting
7628 more that 32 bits make no sense anyway, ( the
7629 largest size of an object can be only 32 bits ) */
7631 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7632 //pic16_emitcode("inc","b");
7633 //pic16_freeAsmop (right,NULL,ic,TRUE);
7634 //pic16_aopOp(left,ic,FALSE);
7635 //pic16_aopOp(result,ic,FALSE);
7637 /* now move the left to the result if they are not the
7639 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7640 AOP_SIZE(result) > 1) {
7642 size = AOP_SIZE(result);
7646 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7647 if (*l == '@' && IS_AOP_PREG(result)) {
7649 pic16_emitcode("mov","a,%s",l);
7650 pic16_aopPut(AOP(result),"a",offset);
7652 pic16_aopPut(AOP(result),l,offset);
7654 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7655 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7661 /* mov the highest order bit to OVR */
7662 tlbl = newiTempLabel(NULL);
7663 tlbl1= newiTempLabel(NULL);
7665 size = AOP_SIZE(result);
7668 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7670 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7672 /* offset should be 0, 1 or 3 */
7673 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7675 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7677 pic16_emitpcode(POC_MOVWF, pctemp);
7680 pic16_emitpLabel(tlbl->key);
7682 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7683 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7686 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7689 pic16_emitpcode(POC_DECFSZ, pctemp);
7690 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7691 pic16_emitpLabel(tlbl1->key);
7693 pic16_popReleaseTempReg(pctemp);
7695 size = AOP_SIZE(result);
7697 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7698 pic16_emitcode("rlc","a");
7699 pic16_emitcode("mov","ov,c");
7700 /* if it is only one byte then */
7702 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7704 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7705 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7706 pic16_emitcode("mov","c,ov");
7707 pic16_emitcode("rrc","a");
7708 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7709 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7710 pic16_aopPut(AOP(result),"a",0);
7714 reAdjustPreg(AOP(result));
7715 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7716 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7717 pic16_emitcode("mov","c,ov");
7719 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7721 pic16_emitcode("rrc","a");
7722 pic16_aopPut(AOP(result),"a",offset--);
7724 reAdjustPreg(AOP(result));
7725 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7726 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7731 pic16_freeAsmop(left,NULL,ic,TRUE);
7732 pic16_freeAsmop(result,NULL,ic,TRUE);
7733 pic16_freeAsmop(right,NULL,ic,TRUE);
7736 /*-----------------------------------------------------------------*/
7737 /* genRightShift - generate code for right shifting */
7738 /*-----------------------------------------------------------------*/
7739 static void genRightShift (iCode *ic)
7741 operand *right, *left, *result;
7745 symbol *tlbl, *tlbl1 ;
7747 /* if signed then we do it the hard way preserve the
7748 sign bit moving it inwards */
7749 retype = getSpec(operandType(IC_RESULT(ic)));
7750 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7752 if (!SPEC_USIGN(retype)) {
7753 genSignedRightShift (ic);
7757 /* signed & unsigned types are treated the same : i.e. the
7758 signed is NOT propagated inwards : quoting from the
7759 ANSI - standard : "for E1 >> E2, is equivalent to division
7760 by 2**E2 if unsigned or if it has a non-negative value,
7761 otherwise the result is implementation defined ", MY definition
7762 is that the sign does not get propagated */
7764 right = IC_RIGHT(ic);
7766 result = IC_RESULT(ic);
7768 pic16_aopOp(right,ic,FALSE);
7770 /* if the shift count is known then do it
7771 as efficiently as possible */
7772 if (AOP_TYPE(right) == AOP_LIT) {
7773 genRightShiftLiteral (left,right,result,ic, 0);
7777 /* shift count is unknown then we have to form
7778 a loop get the loop count in B : Note: we take
7779 only the lower order byte since shifting
7780 more that 32 bits make no sense anyway, ( the
7781 largest size of an object can be only 32 bits ) */
7783 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7784 pic16_emitcode("inc","b");
7785 pic16_aopOp(left,ic,FALSE);
7786 pic16_aopOp(result,ic,FALSE);
7788 /* now move the left to the result if they are not the
7790 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7791 AOP_SIZE(result) > 1) {
7793 size = AOP_SIZE(result);
7796 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7797 if (*l == '@' && IS_AOP_PREG(result)) {
7799 pic16_emitcode("mov","a,%s",l);
7800 pic16_aopPut(AOP(result),"a",offset);
7802 pic16_aopPut(AOP(result),l,offset);
7807 tlbl = newiTempLabel(NULL);
7808 tlbl1= newiTempLabel(NULL);
7809 size = AOP_SIZE(result);
7812 /* if it is only one byte then */
7815 tlbl = newiTempLabel(NULL);
7816 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7817 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7818 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7821 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7822 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7823 pic16_emitpLabel(tlbl->key);
7824 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7825 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7827 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7832 reAdjustPreg(AOP(result));
7833 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7834 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7837 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7839 pic16_emitcode("rrc","a");
7840 pic16_aopPut(AOP(result),"a",offset--);
7842 reAdjustPreg(AOP(result));
7844 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7845 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7848 pic16_freeAsmop(left,NULL,ic,TRUE);
7849 pic16_freeAsmop (right,NULL,ic,TRUE);
7850 pic16_freeAsmop(result,NULL,ic,TRUE);
7853 /*-----------------------------------------------------------------*/
7854 /* genUnpackBits - generates code for unpacking bits */
7855 /*-----------------------------------------------------------------*/
7856 static void genUnpackBits (operand *result, char *rname, int ptype)
7863 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7864 etype = getSpec(operandType(result));
7866 /* read the first byte */
7871 pic16_emitcode("mov","a,@%s",rname);
7875 pic16_emitcode("movx","a,@%s",rname);
7879 pic16_emitcode("movx","a,@dptr");
7883 pic16_emitcode("clr","a");
7884 pic16_emitcode("movc","a","@a+dptr");
7888 pic16_emitcode("lcall","__gptrget");
7892 /* if we have bitdisplacement then it fits */
7893 /* into this byte completely or if length is */
7894 /* less than a byte */
7895 if ((shCnt = SPEC_BSTR(etype)) ||
7896 (SPEC_BLEN(etype) <= 8)) {
7898 /* shift right acc */
7901 pic16_emitcode("anl","a,#0x%02x",
7902 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7903 pic16_aopPut(AOP(result),"a",offset);
7907 /* bit field did not fit in a byte */
7908 rlen = SPEC_BLEN(etype) - 8;
7909 pic16_aopPut(AOP(result),"a",offset++);
7916 pic16_emitcode("inc","%s",rname);
7917 pic16_emitcode("mov","a,@%s",rname);
7921 pic16_emitcode("inc","%s",rname);
7922 pic16_emitcode("movx","a,@%s",rname);
7926 pic16_emitcode("inc","dptr");
7927 pic16_emitcode("movx","a,@dptr");
7931 pic16_emitcode("clr","a");
7932 pic16_emitcode("inc","dptr");
7933 pic16_emitcode("movc","a","@a+dptr");
7937 pic16_emitcode("inc","dptr");
7938 pic16_emitcode("lcall","__gptrget");
7943 /* if we are done */
7947 pic16_aopPut(AOP(result),"a",offset++);
7952 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7953 pic16_aopPut(AOP(result),"a",offset);
7960 /*-----------------------------------------------------------------*/
7961 /* genDataPointerGet - generates code when ptr offset is known */
7962 /*-----------------------------------------------------------------*/
7963 static void genDataPointerGet (operand *left,
7967 int size , offset = 0;
7970 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7973 /* optimization - most of the time, left and result are the same
7974 * address, but different types. for the pic code, we could omit
7978 pic16_aopOp(result,ic,TRUE);
7980 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7982 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7984 size = AOP_SIZE(result);
7987 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7991 pic16_freeAsmop(left,NULL,ic,TRUE);
7992 pic16_freeAsmop(result,NULL,ic,TRUE);
7995 /*-----------------------------------------------------------------*/
7996 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
7997 /*-----------------------------------------------------------------*/
7998 static void genNearPointerGet (operand *left,
8003 //regs *preg = NULL ;
8005 sym_link *rtype, *retype;
8006 sym_link *ltype = operandType(left);
8009 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8011 rtype = operandType(result);
8012 retype= getSpec(rtype);
8014 pic16_aopOp(left,ic,FALSE);
8016 /* if left is rematerialisable and
8017 result is not bit variable type and
8018 the left is pointer to data space i.e
8019 lower 128 bytes of space */
8020 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8021 !IS_BITVAR(retype) &&
8022 DCL_TYPE(ltype) == POINTER) {
8023 //genDataPointerGet (left,result,ic);
8027 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8029 /* if the value is already in a pointer register
8030 then don't need anything more */
8031 if (!AOP_INPREG(AOP(left))) {
8032 /* otherwise get a free pointer register */
8033 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8036 preg = getFreePtr(ic,&aop,FALSE);
8037 pic16_emitcode("mov","%s,%s",
8039 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8040 rname = preg->name ;
8044 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8046 pic16_aopOp (result,ic,FALSE);
8048 /* if bitfield then unpack the bits */
8049 if (IS_BITVAR(retype))
8050 genUnpackBits (result,rname,POINTER);
8052 /* we have can just get the values */
8053 int size = AOP_SIZE(result);
8056 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8058 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8059 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8061 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8062 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8064 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8068 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8070 pic16_emitcode("mov","a,@%s",rname);
8071 pic16_aopPut(AOP(result),"a",offset);
8073 sprintf(buffer,"@%s",rname);
8074 pic16_aopPut(AOP(result),buffer,offset);
8078 pic16_emitcode("inc","%s",rname);
8083 /* now some housekeeping stuff */
8085 /* we had to allocate for this iCode */
8086 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8087 pic16_freeAsmop(NULL,aop,ic,TRUE);
8089 /* we did not allocate which means left
8090 already in a pointer register, then
8091 if size > 0 && this could be used again
8092 we have to point it back to where it
8094 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8095 if (AOP_SIZE(result) > 1 &&
8096 !OP_SYMBOL(left)->remat &&
8097 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8099 int size = AOP_SIZE(result) - 1;
8101 pic16_emitcode("dec","%s",rname);
8106 pic16_freeAsmop(left,NULL,ic,TRUE);
8107 pic16_freeAsmop(result,NULL,ic,TRUE);
8111 /*-----------------------------------------------------------------*/
8112 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8113 /*-----------------------------------------------------------------*/
8114 static void genPagedPointerGet (operand *left,
8121 sym_link *rtype, *retype;
8123 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8125 rtype = operandType(result);
8126 retype= getSpec(rtype);
8128 pic16_aopOp(left,ic,FALSE);
8130 /* if the value is already in a pointer register
8131 then don't need anything more */
8132 if (!AOP_INPREG(AOP(left))) {
8133 /* otherwise get a free pointer register */
8135 preg = getFreePtr(ic,&aop,FALSE);
8136 pic16_emitcode("mov","%s,%s",
8138 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8139 rname = preg->name ;
8141 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8143 pic16_freeAsmop(left,NULL,ic,TRUE);
8144 pic16_aopOp (result,ic,FALSE);
8146 /* if bitfield then unpack the bits */
8147 if (IS_BITVAR(retype))
8148 genUnpackBits (result,rname,PPOINTER);
8150 /* we have can just get the values */
8151 int size = AOP_SIZE(result);
8156 pic16_emitcode("movx","a,@%s",rname);
8157 pic16_aopPut(AOP(result),"a",offset);
8162 pic16_emitcode("inc","%s",rname);
8166 /* now some housekeeping stuff */
8168 /* we had to allocate for this iCode */
8169 pic16_freeAsmop(NULL,aop,ic,TRUE);
8171 /* we did not allocate which means left
8172 already in a pointer register, then
8173 if size > 0 && this could be used again
8174 we have to point it back to where it
8176 if (AOP_SIZE(result) > 1 &&
8177 !OP_SYMBOL(left)->remat &&
8178 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8180 int size = AOP_SIZE(result) - 1;
8182 pic16_emitcode("dec","%s",rname);
8187 pic16_freeAsmop(result,NULL,ic,TRUE);
8192 /*-----------------------------------------------------------------*/
8193 /* genFarPointerGet - gget value from far space */
8194 /*-----------------------------------------------------------------*/
8195 static void genFarPointerGet (operand *left,
8196 operand *result, iCode *ic)
8199 sym_link *retype = getSpec(operandType(result));
8201 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8203 pic16_aopOp(left,ic,FALSE);
8205 /* if the operand is already in dptr
8206 then we do nothing else we move the value to dptr */
8207 if (AOP_TYPE(left) != AOP_STR) {
8208 /* if this is remateriazable */
8209 if (AOP_TYPE(left) == AOP_IMMD)
8210 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8211 else { /* we need to get it byte by byte */
8212 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8213 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8214 if (options.model == MODEL_FLAT24)
8216 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8220 /* so dptr know contains the address */
8221 pic16_freeAsmop(left,NULL,ic,TRUE);
8222 pic16_aopOp(result,ic,FALSE);
8224 /* if bit then unpack */
8225 if (IS_BITVAR(retype))
8226 genUnpackBits(result,"dptr",FPOINTER);
8228 size = AOP_SIZE(result);
8232 pic16_emitcode("movx","a,@dptr");
8233 pic16_aopPut(AOP(result),"a",offset++);
8235 pic16_emitcode("inc","dptr");
8239 pic16_freeAsmop(result,NULL,ic,TRUE);
8242 /*-----------------------------------------------------------------*/
8243 /* genCodePointerGet - get value from code space */
8244 /*-----------------------------------------------------------------*/
8245 static void genCodePointerGet (operand *left,
8246 operand *result, iCode *ic)
8249 sym_link *retype = getSpec(operandType(result));
8251 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8253 pic16_aopOp(left,ic,FALSE);
8255 /* if the operand is already in dptr
8256 then we do nothing else we move the value to dptr */
8257 if (AOP_TYPE(left) != AOP_STR) {
8258 /* if this is remateriazable */
8259 if (AOP_TYPE(left) == AOP_IMMD)
8260 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8261 else { /* we need to get it byte by byte */
8262 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8263 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8264 if (options.model == MODEL_FLAT24)
8266 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8270 /* so dptr know contains the address */
8271 pic16_freeAsmop(left,NULL,ic,TRUE);
8272 pic16_aopOp(result,ic,FALSE);
8274 /* if bit then unpack */
8275 if (IS_BITVAR(retype))
8276 genUnpackBits(result,"dptr",CPOINTER);
8278 size = AOP_SIZE(result);
8282 pic16_emitcode("clr","a");
8283 pic16_emitcode("movc","a,@a+dptr");
8284 pic16_aopPut(AOP(result),"a",offset++);
8286 pic16_emitcode("inc","dptr");
8290 pic16_freeAsmop(result,NULL,ic,TRUE);
8293 /*-----------------------------------------------------------------*/
8294 /* genGenPointerGet - gget value from generic pointer space */
8295 /*-----------------------------------------------------------------*/
8296 static void genGenPointerGet (operand *left,
8297 operand *result, iCode *ic)
8300 sym_link *retype = getSpec(operandType(result));
8302 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8303 pic16_aopOp(left,ic,FALSE);
8304 pic16_aopOp(result,ic,FALSE);
8307 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8309 /* if the operand is already in dptr
8310 then we do nothing else we move the value to dptr */
8311 // if (AOP_TYPE(left) != AOP_STR) {
8312 /* if this is remateriazable */
8313 if (AOP_TYPE(left) == AOP_IMMD) {
8314 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8315 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8317 else { /* we need to get it byte by byte */
8319 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8320 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8322 size = AOP_SIZE(result);
8326 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8327 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8329 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8334 /* so dptr know contains the address */
8336 /* if bit then unpack */
8337 //if (IS_BITVAR(retype))
8338 // genUnpackBits(result,"dptr",GPOINTER);
8341 pic16_freeAsmop(left,NULL,ic,TRUE);
8342 pic16_freeAsmop(result,NULL,ic,TRUE);
8346 /*-----------------------------------------------------------------*/
8347 /* genConstPointerGet - get value from const generic pointer space */
8348 /*-----------------------------------------------------------------*/
8349 static void genConstPointerGet (operand *left,
8350 operand *result, iCode *ic)
8352 //sym_link *retype = getSpec(operandType(result));
8353 symbol *albl = newiTempLabel(NULL);
8354 symbol *blbl = newiTempLabel(NULL);
8357 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8358 pic16_aopOp(left,ic,FALSE);
8359 pic16_aopOp(result,ic,FALSE);
8362 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8364 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8366 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8367 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8368 pic16_emitpLabel(albl->key);
8370 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8372 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8373 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8374 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8375 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8377 pic16_emitpLabel(blbl->key);
8379 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8382 pic16_freeAsmop(left,NULL,ic,TRUE);
8383 pic16_freeAsmop(result,NULL,ic,TRUE);
8386 /*-----------------------------------------------------------------*/
8387 /* genPointerGet - generate code for pointer get */
8388 /*-----------------------------------------------------------------*/
8389 static void genPointerGet (iCode *ic)
8391 operand *left, *result ;
8392 sym_link *type, *etype;
8395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8398 result = IC_RESULT(ic) ;
8400 /* depending on the type of pointer we need to
8401 move it to the correct pointer register */
8402 type = operandType(left);
8403 etype = getSpec(type);
8405 if (IS_PTR_CONST(type))
8406 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8408 /* if left is of type of pointer then it is simple */
8409 if (IS_PTR(type) && !IS_FUNC(type->next))
8410 p_type = DCL_TYPE(type);
8412 /* we have to go by the storage class */
8413 p_type = PTR_TYPE(SPEC_OCLS(etype));
8415 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8417 if (SPEC_OCLS(etype)->codesp ) {
8418 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8419 //p_type = CPOINTER ;
8422 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8423 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8424 /*p_type = FPOINTER ;*/
8426 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8427 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8428 /* p_type = PPOINTER; */
8430 if (SPEC_OCLS(etype) == idata )
8431 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8432 /* p_type = IPOINTER; */
8434 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8435 /* p_type = POINTER ; */
8438 /* now that we have the pointer type we assign
8439 the pointer values */
8444 genNearPointerGet (left,result,ic);
8448 genPagedPointerGet(left,result,ic);
8452 genFarPointerGet (left,result,ic);
8456 genConstPointerGet (left,result,ic);
8457 //pic16_emitcodePointerGet (left,result,ic);
8461 if (IS_PTR_CONST(type))
8462 genConstPointerGet (left,result,ic);
8464 genGenPointerGet (left,result,ic);
8470 /*-----------------------------------------------------------------*/
8471 /* genPackBits - generates code for packed bit storage */
8472 /*-----------------------------------------------------------------*/
8473 static void genPackBits (sym_link *etype ,
8475 char *rname, int p_type)
8483 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8484 blen = SPEC_BLEN(etype);
8485 bstr = SPEC_BSTR(etype);
8487 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8490 /* if the bit lenth is less than or */
8491 /* it exactly fits a byte then */
8492 if (SPEC_BLEN(etype) <= 8 ) {
8493 shCount = SPEC_BSTR(etype) ;
8495 /* shift left acc */
8498 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8503 pic16_emitcode ("mov","b,a");
8504 pic16_emitcode("mov","a,@%s",rname);
8508 pic16_emitcode ("mov","b,a");
8509 pic16_emitcode("movx","a,@dptr");
8513 pic16_emitcode ("push","b");
8514 pic16_emitcode ("push","acc");
8515 pic16_emitcode ("lcall","__gptrget");
8516 pic16_emitcode ("pop","b");
8520 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8521 ((unsigned char)(0xFF << (blen+bstr)) |
8522 (unsigned char)(0xFF >> (8-bstr)) ) );
8523 pic16_emitcode ("orl","a,b");
8524 if (p_type == GPOINTER)
8525 pic16_emitcode("pop","b");
8531 pic16_emitcode("mov","@%s,a",rname);
8535 pic16_emitcode("movx","@dptr,a");
8539 DEBUGpic16_emitcode(";lcall","__gptrput");
8544 if ( SPEC_BLEN(etype) <= 8 )
8547 pic16_emitcode("inc","%s",rname);
8548 rLen = SPEC_BLEN(etype) ;
8550 /* now generate for lengths greater than one byte */
8553 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8563 pic16_emitcode("mov","@%s,a",rname);
8565 pic16_emitcode("mov","@%s,%s",rname,l);
8570 pic16_emitcode("movx","@dptr,a");
8575 DEBUGpic16_emitcode(";lcall","__gptrput");
8578 pic16_emitcode ("inc","%s",rname);
8583 /* last last was not complete */
8585 /* save the byte & read byte */
8588 pic16_emitcode ("mov","b,a");
8589 pic16_emitcode("mov","a,@%s",rname);
8593 pic16_emitcode ("mov","b,a");
8594 pic16_emitcode("movx","a,@dptr");
8598 pic16_emitcode ("push","b");
8599 pic16_emitcode ("push","acc");
8600 pic16_emitcode ("lcall","__gptrget");
8601 pic16_emitcode ("pop","b");
8605 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8606 pic16_emitcode ("orl","a,b");
8609 if (p_type == GPOINTER)
8610 pic16_emitcode("pop","b");
8615 pic16_emitcode("mov","@%s,a",rname);
8619 pic16_emitcode("movx","@dptr,a");
8623 DEBUGpic16_emitcode(";lcall","__gptrput");
8627 /*-----------------------------------------------------------------*/
8628 /* genDataPointerSet - remat pointer to data space */
8629 /*-----------------------------------------------------------------*/
8630 static void genDataPointerSet(operand *right,
8634 int size, offset = 0 ;
8635 char *l, buffer[256];
8637 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8638 pic16_aopOp(right,ic,FALSE);
8640 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8641 size = AOP_SIZE(right);
8643 if ( AOP_TYPE(result) == AOP_PCODE) {
8644 fprintf(stderr,"genDataPointerSet %s, %d\n",
8645 AOP(result)->aopu.pcop->name,
8646 PCOI(AOP(result)->aopu.pcop)->offset);
8650 // tsd, was l+1 - the underline `_' prefix was being stripped
8653 sprintf(buffer,"(%s + %d)",l,offset);
8654 fprintf(stderr,"oops %s\n",buffer);
8656 sprintf(buffer,"%s",l);
8658 if (AOP_TYPE(right) == AOP_LIT) {
8659 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8660 lit = lit >> (8*offset);
8662 pic16_emitcode("movlw","%d",lit);
8663 pic16_emitcode("movwf","%s",buffer);
8665 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8666 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8667 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8670 pic16_emitcode("clrf","%s",buffer);
8671 //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8672 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8675 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8676 pic16_emitcode("movwf","%s",buffer);
8678 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8679 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8680 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8687 pic16_freeAsmop(right,NULL,ic,TRUE);
8688 pic16_freeAsmop(result,NULL,ic,TRUE);
8691 /*-----------------------------------------------------------------*/
8692 /* genNearPointerSet - pic16_emitcode for near pointer put */
8693 /*-----------------------------------------------------------------*/
8694 static void genNearPointerSet (operand *right,
8701 sym_link *ptype = operandType(result);
8704 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8705 retype= getSpec(operandType(right));
8707 pic16_aopOp(result,ic,FALSE);
8710 /* if the result is rematerializable &
8711 in data space & not a bit variable */
8712 //if (AOP_TYPE(result) == AOP_IMMD &&
8713 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8714 DCL_TYPE(ptype) == POINTER &&
8715 !IS_BITVAR(retype)) {
8716 genDataPointerSet (right,result,ic);
8717 pic16_freeAsmop(result,NULL,ic,TRUE);
8721 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8722 pic16_aopOp(right,ic,FALSE);
8723 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8725 /* if the value is already in a pointer register
8726 then don't need anything more */
8727 if (!AOP_INPREG(AOP(result))) {
8728 /* otherwise get a free pointer register */
8729 //aop = newAsmop(0);
8730 //preg = getFreePtr(ic,&aop,FALSE);
8731 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8732 //pic16_emitcode("mov","%s,%s",
8734 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8735 //rname = preg->name ;
8736 //pic16_emitcode("movwf","fsr0");
8737 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8738 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8739 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8740 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8744 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8747 /* if bitfield then unpack the bits */
8748 if (IS_BITVAR(retype)) {
8749 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8750 "The programmer is obviously confused");
8751 //genPackBits (retype,right,rname,POINTER);
8755 /* we have can just get the values */
8756 int size = AOP_SIZE(right);
8759 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8761 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8764 //pic16_emitcode("mov","@%s,a",rname);
8765 pic16_emitcode("movf","indf0,w ;1");
8768 if (AOP_TYPE(right) == AOP_LIT) {
8769 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8771 pic16_emitcode("movlw","%s",l);
8772 pic16_emitcode("movwf","indf0 ;2");
8774 pic16_emitcode("clrf","indf0");
8776 pic16_emitcode("movf","%s,w",l);
8777 pic16_emitcode("movwf","indf0 ;2");
8779 //pic16_emitcode("mov","@%s,%s",rname,l);
8782 pic16_emitcode("incf","fsr0,f ;3");
8783 //pic16_emitcode("inc","%s",rname);
8788 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8789 /* now some housekeeping stuff */
8791 /* we had to allocate for this iCode */
8792 pic16_freeAsmop(NULL,aop,ic,TRUE);
8794 /* we did not allocate which means left
8795 already in a pointer register, then
8796 if size > 0 && this could be used again
8797 we have to point it back to where it
8799 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8800 if (AOP_SIZE(right) > 1 &&
8801 !OP_SYMBOL(result)->remat &&
8802 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8804 int size = AOP_SIZE(right) - 1;
8806 pic16_emitcode("decf","fsr0,f");
8807 //pic16_emitcode("dec","%s",rname);
8811 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8814 pic16_freeAsmop(right,NULL,ic,TRUE);
8815 pic16_freeAsmop(result,NULL,ic,TRUE);
8818 /*-----------------------------------------------------------------*/
8819 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8820 /*-----------------------------------------------------------------*/
8821 static void genPagedPointerSet (operand *right,
8830 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8832 retype= getSpec(operandType(right));
8834 pic16_aopOp(result,ic,FALSE);
8836 /* if the value is already in a pointer register
8837 then don't need anything more */
8838 if (!AOP_INPREG(AOP(result))) {
8839 /* otherwise get a free pointer register */
8841 preg = getFreePtr(ic,&aop,FALSE);
8842 pic16_emitcode("mov","%s,%s",
8844 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8845 rname = preg->name ;
8847 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8849 pic16_freeAsmop(result,NULL,ic,TRUE);
8850 pic16_aopOp (right,ic,FALSE);
8852 /* if bitfield then unpack the bits */
8853 if (IS_BITVAR(retype))
8854 genPackBits (retype,right,rname,PPOINTER);
8856 /* we have can just get the values */
8857 int size = AOP_SIZE(right);
8861 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8864 pic16_emitcode("movx","@%s,a",rname);
8867 pic16_emitcode("inc","%s",rname);
8873 /* now some housekeeping stuff */
8875 /* we had to allocate for this iCode */
8876 pic16_freeAsmop(NULL,aop,ic,TRUE);
8878 /* we did not allocate which means left
8879 already in a pointer register, then
8880 if size > 0 && this could be used again
8881 we have to point it back to where it
8883 if (AOP_SIZE(right) > 1 &&
8884 !OP_SYMBOL(result)->remat &&
8885 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8887 int size = AOP_SIZE(right) - 1;
8889 pic16_emitcode("dec","%s",rname);
8894 pic16_freeAsmop(right,NULL,ic,TRUE);
8899 /*-----------------------------------------------------------------*/
8900 /* genFarPointerSet - set value from far space */
8901 /*-----------------------------------------------------------------*/
8902 static void genFarPointerSet (operand *right,
8903 operand *result, iCode *ic)
8906 sym_link *retype = getSpec(operandType(right));
8908 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8909 pic16_aopOp(result,ic,FALSE);
8911 /* if the operand is already in dptr
8912 then we do nothing else we move the value to dptr */
8913 if (AOP_TYPE(result) != AOP_STR) {
8914 /* if this is remateriazable */
8915 if (AOP_TYPE(result) == AOP_IMMD)
8916 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8917 else { /* we need to get it byte by byte */
8918 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8919 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8920 if (options.model == MODEL_FLAT24)
8922 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8926 /* so dptr know contains the address */
8927 pic16_freeAsmop(result,NULL,ic,TRUE);
8928 pic16_aopOp(right,ic,FALSE);
8930 /* if bit then unpack */
8931 if (IS_BITVAR(retype))
8932 genPackBits(retype,right,"dptr",FPOINTER);
8934 size = AOP_SIZE(right);
8938 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8940 pic16_emitcode("movx","@dptr,a");
8942 pic16_emitcode("inc","dptr");
8946 pic16_freeAsmop(right,NULL,ic,TRUE);
8949 /*-----------------------------------------------------------------*/
8950 /* genGenPointerSet - set value from generic pointer space */
8951 /*-----------------------------------------------------------------*/
8952 static void genGenPointerSet (operand *right,
8953 operand *result, iCode *ic)
8956 sym_link *retype = getSpec(operandType(right));
8958 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8960 pic16_aopOp(result,ic,FALSE);
8961 pic16_aopOp(right,ic,FALSE);
8962 size = AOP_SIZE(right);
8964 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8966 /* if the operand is already in dptr
8967 then we do nothing else we move the value to dptr */
8968 if (AOP_TYPE(result) != AOP_STR) {
8969 /* if this is remateriazable */
8970 if (AOP_TYPE(result) == AOP_IMMD) {
8971 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8972 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8974 else { /* we need to get it byte by byte */
8975 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8976 size = AOP_SIZE(right);
8979 /* hack hack! see if this the FSR. If so don't load W */
8980 if(AOP_TYPE(right) != AOP_ACC) {
8983 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
8984 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8986 if(AOP_SIZE(result) > 1) {
8987 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8988 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
8989 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8994 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
8996 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
8997 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9001 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9002 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9005 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9012 if(aopIdx(AOP(result),0) != 4) {
9014 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9018 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9023 /* so dptr know contains the address */
9026 /* if bit then unpack */
9027 if (IS_BITVAR(retype))
9028 genPackBits(retype,right,"dptr",GPOINTER);
9030 size = AOP_SIZE(right);
9033 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9037 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9038 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9040 if (AOP_TYPE(right) == AOP_LIT)
9041 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9043 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9045 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9052 pic16_freeAsmop(right,NULL,ic,TRUE);
9053 pic16_freeAsmop(result,NULL,ic,TRUE);
9056 /*-----------------------------------------------------------------*/
9057 /* genPointerSet - stores the value into a pointer location */
9058 /*-----------------------------------------------------------------*/
9059 static void genPointerSet (iCode *ic)
9061 operand *right, *result ;
9062 sym_link *type, *etype;
9065 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9067 right = IC_RIGHT(ic);
9068 result = IC_RESULT(ic) ;
9070 /* depending on the type of pointer we need to
9071 move it to the correct pointer register */
9072 type = operandType(result);
9073 etype = getSpec(type);
9074 /* if left is of type of pointer then it is simple */
9075 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9076 p_type = DCL_TYPE(type);
9079 /* we have to go by the storage class */
9080 p_type = PTR_TYPE(SPEC_OCLS(etype));
9082 /* if (SPEC_OCLS(etype)->codesp ) { */
9083 /* p_type = CPOINTER ; */
9086 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9087 /* p_type = FPOINTER ; */
9089 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9090 /* p_type = PPOINTER ; */
9092 /* if (SPEC_OCLS(etype) == idata ) */
9093 /* p_type = IPOINTER ; */
9095 /* p_type = POINTER ; */
9098 /* now that we have the pointer type we assign
9099 the pointer values */
9104 genNearPointerSet (right,result,ic);
9108 genPagedPointerSet (right,result,ic);
9112 genFarPointerSet (right,result,ic);
9116 genGenPointerSet (right,result,ic);
9120 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9121 "genPointerSet: illegal pointer type");
9125 /*-----------------------------------------------------------------*/
9126 /* genIfx - generate code for Ifx statement */
9127 /*-----------------------------------------------------------------*/
9128 static void genIfx (iCode *ic, iCode *popIc)
9130 operand *cond = IC_COND(ic);
9133 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9135 pic16_aopOp(cond,ic,FALSE);
9137 /* get the value into acc */
9138 if (AOP_TYPE(cond) != AOP_CRY)
9139 pic16_toBoolean(cond);
9142 /* the result is now in the accumulator */
9143 pic16_freeAsmop(cond,NULL,ic,TRUE);
9145 /* if there was something to be popped then do it */
9149 /* if the condition is a bit variable */
9150 if (isbit && IS_ITEMP(cond) &&
9152 genIfxJump(ic,SPIL_LOC(cond)->rname);
9153 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9156 if (isbit && !IS_ITEMP(cond))
9157 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9165 /*-----------------------------------------------------------------*/
9166 /* genAddrOf - generates code for address of */
9167 /*-----------------------------------------------------------------*/
9168 static void genAddrOf (iCode *ic)
9170 operand *right, *result, *left;
9173 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9176 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9178 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9179 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9180 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9182 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9184 size = AOP_SIZE(IC_RESULT(ic));
9189 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9190 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9195 pic16_freeAsmop(left,NULL,ic,FALSE);
9196 pic16_freeAsmop(result,NULL,ic,TRUE);
9201 /*-----------------------------------------------------------------*/
9202 /* genFarFarAssign - assignment when both are in far space */
9203 /*-----------------------------------------------------------------*/
9204 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9206 int size = AOP_SIZE(right);
9209 /* first push the right side on to the stack */
9211 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9213 pic16_emitcode ("push","acc");
9216 pic16_freeAsmop(right,NULL,ic,FALSE);
9217 /* now assign DPTR to result */
9218 pic16_aopOp(result,ic,FALSE);
9219 size = AOP_SIZE(result);
9221 pic16_emitcode ("pop","acc");
9222 pic16_aopPut(AOP(result),"a",--offset);
9224 pic16_freeAsmop(result,NULL,ic,FALSE);
9229 /*-----------------------------------------------------------------*/
9230 /* genAssign - generate code for assignment */
9231 /*-----------------------------------------------------------------*/
9232 static void genAssign (iCode *ic)
9234 operand *result, *right;
9235 int size, offset,know_W;
9236 unsigned long lit = 0L;
9238 result = IC_RESULT(ic);
9239 right = IC_RIGHT(ic) ;
9241 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9243 /* if they are the same */
9244 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9247 pic16_aopOp(right,ic,FALSE);
9248 pic16_aopOp(result,ic,TRUE);
9250 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9252 /* if they are the same registers */
9253 if (pic16_sameRegs(AOP(right),AOP(result)))
9256 /* if the result is a bit */
9257 if (AOP_TYPE(result) == AOP_CRY) {
9258 /* if the right size is a literal then
9259 we know what the value is */
9260 if (AOP_TYPE(right) == AOP_LIT) {
9262 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9263 pic16_popGet(AOP(result),0));
9265 if (((int) operandLitValue(right)))
9266 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9267 AOP(result)->aopu.aop_dir,
9268 AOP(result)->aopu.aop_dir);
9270 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9271 AOP(result)->aopu.aop_dir,
9272 AOP(result)->aopu.aop_dir);
9276 /* the right is also a bit variable */
9277 if (AOP_TYPE(right) == AOP_CRY) {
9278 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9279 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9280 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9282 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9283 AOP(result)->aopu.aop_dir,
9284 AOP(result)->aopu.aop_dir);
9285 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9286 AOP(right)->aopu.aop_dir,
9287 AOP(right)->aopu.aop_dir);
9288 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9289 AOP(result)->aopu.aop_dir,
9290 AOP(result)->aopu.aop_dir);
9295 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9296 pic16_toBoolean(right);
9298 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9299 //pic16_aopPut(AOP(result),"a",0);
9303 /* bit variables done */
9305 size = AOP_SIZE(result);
9307 if(AOP_TYPE(right) == AOP_LIT)
9308 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9310 /* VR - What is this?! */
9311 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9312 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9313 if(aopIdx(AOP(result),0) == 4) {
9314 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9315 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9316 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9319 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9324 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9325 if(AOP_TYPE(right) == AOP_LIT) {
9327 if(know_W != (lit&0xff))
9328 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9330 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9332 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9336 } else if (AOP_TYPE(right) == AOP_CRY) {
9337 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9339 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9340 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9343 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9346 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9347 normally should work, but mind that thw W register live range
9348 is not checked, so if the code generator assumes that the W
9349 is already loaded after such a pair, wrong code will be generated.
9351 Checking the live range is the next step.
9352 This is experimental code yet and has not been fully tested yet.
9353 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9354 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9357 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9359 /* This is the old code, which is assumed(?!) that works fine(!?) */
9361 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9362 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9371 pic16_freeAsmop (right,NULL,ic,FALSE);
9372 pic16_freeAsmop (result,NULL,ic,TRUE);
9375 /*-----------------------------------------------------------------*/
9376 /* genJumpTab - generates code for jump table */
9377 /*-----------------------------------------------------------------*/
9378 static void genJumpTab (iCode *ic)
9383 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9385 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9386 /* get the condition into accumulator */
9387 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9389 /* multiply by three */
9390 pic16_emitcode("add","a,acc");
9391 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9393 jtab = newiTempLabel(NULL);
9394 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9395 pic16_emitcode("jmp","@a+dptr");
9396 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9398 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9399 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9401 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9402 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9403 pic16_emitpLabel(jtab->key);
9405 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9407 /* now generate the jump labels */
9408 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9409 jtab = setNextItem(IC_JTLABELS(ic))) {
9410 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9411 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9417 /*-----------------------------------------------------------------*/
9418 /* genMixedOperation - gen code for operators between mixed types */
9419 /*-----------------------------------------------------------------*/
9421 TSD - Written for the PIC port - but this unfortunately is buggy.
9422 This routine is good in that it is able to efficiently promote
9423 types to different (larger) sizes. Unfortunately, the temporary
9424 variables that are optimized out by this routine are sometimes
9425 used in other places. So until I know how to really parse the
9426 iCode tree, I'm going to not be using this routine :(.
9428 static int genMixedOperation (iCode *ic)
9431 operand *result = IC_RESULT(ic);
9432 sym_link *ctype = operandType(IC_LEFT(ic));
9433 operand *right = IC_RIGHT(ic);
9439 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9441 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9447 nextright = IC_RIGHT(nextic);
9448 nextleft = IC_LEFT(nextic);
9449 nextresult = IC_RESULT(nextic);
9451 pic16_aopOp(right,ic,FALSE);
9452 pic16_aopOp(result,ic,FALSE);
9453 pic16_aopOp(nextright, nextic, FALSE);
9454 pic16_aopOp(nextleft, nextic, FALSE);
9455 pic16_aopOp(nextresult, nextic, FALSE);
9457 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9463 pic16_emitcode(";remove right +","");
9465 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9471 pic16_emitcode(";remove left +","");
9475 big = AOP_SIZE(nextleft);
9476 small = AOP_SIZE(nextright);
9478 switch(nextic->op) {
9481 pic16_emitcode(";optimize a +","");
9482 /* if unsigned or not an integral type */
9483 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9484 pic16_emitcode(";add a bit to something","");
9487 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9489 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9490 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9491 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9493 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9501 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9502 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9503 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9506 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9508 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9509 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9510 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9511 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9512 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9515 pic16_emitcode("rlf","known_zero,w");
9522 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9523 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9524 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9526 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9536 pic16_freeAsmop(right,NULL,ic,TRUE);
9537 pic16_freeAsmop(result,NULL,ic,TRUE);
9538 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9539 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9541 nextic->generated = 1;
9548 /*-----------------------------------------------------------------*/
9549 /* genCast - gen code for casting */
9550 /*-----------------------------------------------------------------*/
9551 static void genCast (iCode *ic)
9553 operand *result = IC_RESULT(ic);
9554 sym_link *ctype = operandType(IC_LEFT(ic));
9555 sym_link *rtype = operandType(IC_RIGHT(ic));
9556 operand *right = IC_RIGHT(ic);
9559 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9560 /* if they are equivalent then do nothing */
9561 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9564 pic16_aopOp(right,ic,FALSE) ;
9565 pic16_aopOp(result,ic,FALSE);
9567 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9569 /* if the result is a bit */
9570 if (AOP_TYPE(result) == AOP_CRY) {
9571 /* if the right size is a literal then
9572 we know what the value is */
9573 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9574 if (AOP_TYPE(right) == AOP_LIT) {
9576 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9577 pic16_popGet(AOP(result),0));
9579 if (((int) operandLitValue(right)))
9580 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9581 AOP(result)->aopu.aop_dir,
9582 AOP(result)->aopu.aop_dir);
9584 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9585 AOP(result)->aopu.aop_dir,
9586 AOP(result)->aopu.aop_dir);
9591 /* the right is also a bit variable */
9592 if (AOP_TYPE(right) == AOP_CRY) {
9595 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9597 pic16_emitcode("clrc","");
9598 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9599 AOP(right)->aopu.aop_dir,
9600 AOP(right)->aopu.aop_dir);
9601 pic16_aopPut(AOP(result),"c",0);
9606 if (AOP_TYPE(right) == AOP_REG) {
9607 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9608 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9609 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9611 pic16_toBoolean(right);
9612 pic16_aopPut(AOP(result),"a",0);
9616 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9618 size = AOP_SIZE(result);
9620 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9622 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9623 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9624 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9627 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9632 /* if they are the same size : or less */
9633 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9635 /* if they are in the same place */
9636 if (pic16_sameRegs(AOP(right),AOP(result)))
9639 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9640 if (IS_PTR_CONST(rtype))
9641 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9642 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9643 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9645 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9646 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9647 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9648 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9649 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9650 if(AOP_SIZE(result) <2)
9651 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9655 /* if they in different places then copy */
9656 size = AOP_SIZE(result);
9659 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9660 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9662 //pic16_aopPut(AOP(result),
9663 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9673 /* if the result is of type pointer */
9674 if (IS_PTR(ctype)) {
9677 sym_link *type = operandType(right);
9678 sym_link *etype = getSpec(type);
9679 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9681 /* pointer to generic pointer */
9682 if (IS_GENPTR(ctype)) {
9686 p_type = DCL_TYPE(type);
9688 /* we have to go by the storage class */
9689 p_type = PTR_TYPE(SPEC_OCLS(etype));
9691 /* if (SPEC_OCLS(etype)->codesp ) */
9692 /* p_type = CPOINTER ; */
9694 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9695 /* p_type = FPOINTER ; */
9697 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9698 /* p_type = PPOINTER; */
9700 /* if (SPEC_OCLS(etype) == idata ) */
9701 /* p_type = IPOINTER ; */
9703 /* p_type = POINTER ; */
9706 /* the first two bytes are known */
9707 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9708 size = GPTRSIZE - 1;
9711 if(offset < AOP_SIZE(right)) {
9712 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9713 if ((AOP_TYPE(right) == AOP_PCODE) &&
9714 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9715 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9716 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9718 pic16_aopPut(AOP(result),
9719 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9723 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9726 /* the last byte depending on type */
9730 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9733 pic16_emitcode(";BUG!? ","%d",__LINE__);
9737 pic16_emitcode(";BUG!? ","%d",__LINE__);
9741 pic16_emitcode(";BUG!? ","%d",__LINE__);
9746 /* this should never happen */
9747 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9748 "got unknown pointer type");
9751 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9755 /* just copy the pointers */
9756 size = AOP_SIZE(result);
9759 pic16_aopPut(AOP(result),
9760 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9769 /* so we now know that the size of destination is greater
9770 than the size of the source.
9771 Now, if the next iCode is an operator then we might be
9772 able to optimize the operation without performing a cast.
9774 if(genMixedOperation(ic))
9777 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9779 /* we move to result for the size of source */
9780 size = AOP_SIZE(right);
9783 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9784 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9788 /* now depending on the sign of the destination */
9789 size = AOP_SIZE(result) - AOP_SIZE(right);
9790 /* if unsigned or not an integral type */
9791 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9793 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9795 /* we need to extend the sign :{ */
9798 /* Save one instruction of casting char to int */
9799 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9800 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9801 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
9803 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9806 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9808 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9810 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9813 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
9818 pic16_freeAsmop(right,NULL,ic,TRUE);
9819 pic16_freeAsmop(result,NULL,ic,TRUE);
9823 /*-----------------------------------------------------------------*/
9824 /* genDjnz - generate decrement & jump if not zero instrucion */
9825 /*-----------------------------------------------------------------*/
9826 static int genDjnz (iCode *ic, iCode *ifx)
9829 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9834 /* if the if condition has a false label
9835 then we cannot save */
9839 /* if the minus is not of the form
9841 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9842 !IS_OP_LITERAL(IC_RIGHT(ic)))
9845 if (operandLitValue(IC_RIGHT(ic)) != 1)
9848 /* if the size of this greater than one then no
9850 if (getSize(operandType(IC_RESULT(ic))) > 1)
9853 /* otherwise we can save BIG */
9854 lbl = newiTempLabel(NULL);
9855 lbl1= newiTempLabel(NULL);
9857 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9859 if (IS_AOP_PREG(IC_RESULT(ic))) {
9860 pic16_emitcode("dec","%s",
9861 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9862 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9863 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9867 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9868 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9870 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9871 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9874 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9875 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9876 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9877 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9880 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9885 /*-----------------------------------------------------------------*/
9886 /* genReceive - generate code for a receive iCode */
9887 /*-----------------------------------------------------------------*/
9888 static void genReceive (iCode *ic)
9890 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9892 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9893 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9894 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9896 int size = getSize(operandType(IC_RESULT(ic)));
9897 int offset = pic16_fReturnSizePic - size;
9899 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9900 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9903 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9904 size = AOP_SIZE(IC_RESULT(ic));
9907 pic16_emitcode ("pop","acc");
9908 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9913 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9915 assignResultValue(IC_RESULT(ic));
9918 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9921 /*-----------------------------------------------------------------*/
9922 /* genDummyRead - generate code for dummy read of volatiles */
9923 /*-----------------------------------------------------------------*/
9925 genDummyRead (iCode * ic)
9927 pic16_emitcode ("; genDummyRead","");
9928 pic16_emitcode ("; not implemented","");
9933 /*-----------------------------------------------------------------*/
9934 /* genpic16Code - generate code for pic16 based controllers */
9935 /*-----------------------------------------------------------------*/
9937 * At this point, ralloc.c has gone through the iCode and attempted
9938 * to optimize in a way suitable for a PIC. Now we've got to generate
9939 * PIC instructions that correspond to the iCode.
9941 * Once the instructions are generated, we'll pass through both the
9942 * peep hole optimizer and the pCode optimizer.
9943 *-----------------------------------------------------------------*/
9945 void genpic16Code (iCode *lic)
9950 lineHead = lineCurr = NULL;
9952 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9953 pic16_addpBlock(pb);
9956 /* if debug information required */
9957 if (options.debug && currFunc) {
9959 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9961 if (IS_STATIC(currFunc->etype)) {
9962 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9963 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9965 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9966 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
9975 for (ic = lic ; ic ; ic = ic->next ) {
9977 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
9978 // DEBUGpic16_emitcode("; VR", "");
9979 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
9980 if ( cln != ic->lineno ) {
9981 if ( options.debug ) {
9983 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
9984 FileBaseName(ic->filename),ic->lineno,
9985 ic->level,ic->block);
9989 pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9990 pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9991 printCLine(ic->filename, ic->lineno));
9993 pic16_addpCode2pBlock(pb,
9994 pic16_newpCodeCSource(ic->lineno,
9996 printCLine(ic->filename, ic->lineno)));
10000 /* if the result is marked as
10001 spilt and rematerializable or code for
10002 this has already been generated then
10004 if (resultRemat(ic) || ic->generated )
10007 /* depending on the operation */
10026 /* IPOP happens only when trying to restore a
10027 spilt live range, if there is an ifx statement
10028 following this pop then the if statement might
10029 be using some of the registers being popped which
10030 would destroy the contents of the register so
10031 we need to check for this condition and handle it */
10033 ic->next->op == IFX &&
10034 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10035 genIfx (ic->next,ic);
10053 genEndFunction (ic);
10069 pic16_genPlus (ic) ;
10073 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10074 pic16_genMinus (ic);
10090 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10094 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10101 /* note these two are xlated by algebraic equivalence
10102 during parsing SDCC.y */
10103 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10104 "got '>=' or '<=' shouldn't have come here");
10108 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10120 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10124 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10128 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10152 genRightShift (ic);
10155 case GET_VALUE_AT_ADDRESS:
10160 if (POINTER_SET(ic))
10187 addSet(&_G.sendSet,ic);
10190 case DUMMY_READ_VOLATILE:
10200 /* now we are ready to call the
10201 peep hole optimizer */
10202 if (!options.nopeep) {
10203 peepHole (&lineHead);
10205 /* now do the actual printing */
10206 printLine (lineHead,codeOutFile);
10209 DFPRINTF((stderr,"printing pBlock\n\n"));
10210 pic16_printpBlock(stdout,pb);