1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
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;
61 /* max_key keeps track of the largest label number used in
62 a function. This is then used to adjust the label offset
63 for the next function.
66 static int GpsuedoStkPtr=0;
68 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
69 unsigned int pic16aopLiteral (value *val, int offset);
70 const char *pic16_AopType(short type);
71 static iCode *ifxForOp ( operand *op, iCode *ic );
73 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
75 /* this is the down and dirty file with all kinds of
76 kludgy & hacky stuff. This is what it is all about
77 CODE GENERATION for a specific MCU . some of the
78 routines may be reusable, will have to see */
80 static char *zero = "#0x00";
81 static char *one = "#0x01";
82 static char *spname = "sp";
84 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
85 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
86 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
87 static char **fReturn = fReturnpic16;
89 static char *accUse[] = {"a","b"};
91 //static short rbank = -1;
103 /* Resolved ifx structure. This structure stores information
104 about an iCode ifx that makes it easier to generate code.
106 typedef struct resolvedIfx {
107 symbol *lbl; /* pointer to a label */
108 int condition; /* true or false ifx */
109 int generated; /* set true when the code associated with the ifx
113 extern int pic16_ptrRegReq ;
114 extern int pic16_nRegs;
115 extern FILE *codeOutFile;
116 static void saverbank (int, iCode *,bool);
118 static lineNode *lineHead = NULL;
119 static lineNode *lineCurr = NULL;
121 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
122 0xE0, 0xC0, 0x80, 0x00};
123 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
124 0x07, 0x03, 0x01, 0x00};
128 /*-----------------------------------------------------------------*/
129 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
130 /* exponent of 2 is returned, otherwise -1 is */
132 /* note that this is similar to the function `powof2' in SDCCsymt */
136 /*-----------------------------------------------------------------*/
137 static int my_powof2 (unsigned long num)
140 if( (num & (num-1)) == 0) {
153 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
156 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
158 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
159 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
160 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
161 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
162 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
163 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
164 ((result) ? AOP_SIZE(result) : 0));
168 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
171 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
173 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
174 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
175 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
176 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
177 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
178 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
182 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
185 char lb[INITIAL_INLINEASM];
188 if(!pic16_debug_verbose)
195 sprintf(lb,"%s\t",inst);
197 sprintf(lb,"%s",inst);
198 vsprintf(lb+(strlen(lb)),fmt,ap);
202 while (isspace(*lbp)) lbp++;
205 lineCurr = (lineCurr ?
206 connectLine(lineCurr,newLineNode(lb)) :
207 (lineHead = newLineNode(lb)));
208 lineCurr->isInline = _G.inLine;
209 lineCurr->isDebug = _G.debugLine;
211 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
217 void pic16_emitpLabel(int key)
219 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
222 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
226 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
228 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
231 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
234 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
238 /*-----------------------------------------------------------------*/
239 /* pic16_emitcode - writes the code into a file : for now it is simple */
240 /*-----------------------------------------------------------------*/
241 void pic16_emitcode (char *inst,char *fmt, ...)
244 char lb[INITIAL_INLINEASM];
251 sprintf(lb,"%s\t",inst);
253 sprintf(lb,"%s",inst);
254 vsprintf(lb+(strlen(lb)),fmt,ap);
258 while (isspace(*lbp)) lbp++;
261 lineCurr = (lineCurr ?
262 connectLine(lineCurr,newLineNode(lb)) :
263 (lineHead = newLineNode(lb)));
264 lineCurr->isInline = _G.inLine;
265 lineCurr->isDebug = _G.debugLine;
267 // VR fprintf(stderr, "lb = <%s>\n", lbp);
269 if(pic16_debug_verbose)
270 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
276 /*-----------------------------------------------------------------*/
277 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
278 /*-----------------------------------------------------------------*/
279 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
281 bool r0iu = FALSE , r1iu = FALSE;
282 bool r0ou = FALSE , r1ou = FALSE;
284 /* the logic: if r0 & r1 used in the instruction
285 then we are in trouble otherwise */
287 /* first check if r0 & r1 are used by this
288 instruction, in which case we are in trouble */
289 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
290 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
295 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
296 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
298 /* if no usage of r0 then return it */
299 if (!r0iu && !r0ou) {
300 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
301 (*aopp)->type = AOP_R0;
303 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
306 /* if no usage of r1 then return it */
307 if (!r1iu && !r1ou) {
308 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
309 (*aopp)->type = AOP_R1;
311 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
314 /* now we know they both have usage */
315 /* if r0 not used in this instruction */
317 /* push it if not already pushed */
319 //pic16_emitcode ("push","%s",
320 // pic16_regWithIdx(R0_IDX)->dname);
324 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
325 (*aopp)->type = AOP_R0;
327 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
330 /* if r1 not used then */
333 /* push it if not already pushed */
335 //pic16_emitcode ("push","%s",
336 // pic16_regWithIdx(R1_IDX)->dname);
340 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
341 (*aopp)->type = AOP_R1;
342 return pic16_regWithIdx(R1_IDX);
346 /* I said end of world but not quite end of world yet */
347 /* if this is a result then we can push it on the stack*/
349 (*aopp)->type = AOP_STK;
353 /* other wise this is true end of the world */
354 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
355 "getFreePtr should never reach here");
359 /*-----------------------------------------------------------------*/
360 /* newAsmop - creates a new asmOp */
361 /*-----------------------------------------------------------------*/
362 static asmop *newAsmop (short type)
366 aop = Safe_calloc(1,sizeof(asmop));
371 static void genSetDPTR(int n)
375 pic16_emitcode(";", "Select standard DPTR");
376 pic16_emitcode("mov", "dps, #0x00");
380 pic16_emitcode(";", "Select alternate DPTR");
381 pic16_emitcode("mov", "dps, #0x01");
385 /*-----------------------------------------------------------------*/
386 /* resolveIfx - converts an iCode ifx into a form more useful for */
387 /* generating code */
388 /*-----------------------------------------------------------------*/
389 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
394 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
396 resIfx->condition = 1; /* assume that the ifx is true */
397 resIfx->generated = 0; /* indicate that the ifx has not been used */
400 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
402 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
403 __FUNCTION__,__LINE__,resIfx->lbl->key);
407 resIfx->lbl = IC_TRUE(ifx);
409 resIfx->lbl = IC_FALSE(ifx);
410 resIfx->condition = 0;
414 DEBUGpic16_emitcode("; ***","ifx true is non-null");
416 DEBUGpic16_emitcode("; ***","ifx false is non-null");
420 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
423 /*-----------------------------------------------------------------*/
424 /* pointerCode - returns the code for a pointer type */
425 /*-----------------------------------------------------------------*/
426 static int pointerCode (sym_link *etype)
429 return PTR_TYPE(SPEC_OCLS(etype));
433 /*-----------------------------------------------------------------*/
434 /* aopForSym - for a true symbol */
435 /*-----------------------------------------------------------------*/
436 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
439 memmap *space= SPEC_OCLS(sym->etype);
441 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
442 /* if already has one */
446 /* assign depending on the storage class */
447 /* if it is on the stack or indirectly addressable */
448 /* space we need to assign either r0 or r1 to it */
449 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
450 sym->aop = aop = newAsmop(0);
451 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
452 aop->size = getSize(sym->type);
454 /* now assign the address of the variable to
455 the pointer register */
456 if (aop->type != AOP_STK) {
460 pic16_emitcode("push","acc");
462 pic16_emitcode("mov","a,_bp");
463 pic16_emitcode("add","a,#0x%02x",
465 ((char)(sym->stack - _G.nRegsSaved )) :
466 ((char)sym->stack)) & 0xff);
467 pic16_emitcode("mov","%s,a",
468 aop->aopu.aop_ptr->name);
471 pic16_emitcode("pop","acc");
473 pic16_emitcode("mov","%s,#%s",
474 aop->aopu.aop_ptr->name,
476 aop->paged = space->paged;
478 aop->aopu.aop_stk = sym->stack;
482 if (sym->onStack && options.stack10bit)
484 /* It's on the 10 bit stack, which is located in
488 //DEBUGpic16_emitcode(";","%d",__LINE__);
491 pic16_emitcode("push","acc");
493 pic16_emitcode("mov","a,_bp");
494 pic16_emitcode("add","a,#0x%02x",
496 ((char)(sym->stack - _G.nRegsSaved )) :
497 ((char)sym->stack)) & 0xff);
500 pic16_emitcode ("mov","dpx1,#0x40");
501 pic16_emitcode ("mov","dph1,#0x00");
502 pic16_emitcode ("mov","dpl1, a");
506 pic16_emitcode("pop","acc");
508 sym->aop = aop = newAsmop(AOP_DPTR2);
509 aop->size = getSize(sym->type);
513 //DEBUGpic16_emitcode(";","%d",__LINE__);
514 /* if in bit space */
515 if (IN_BITSPACE(space)) {
516 sym->aop = aop = newAsmop (AOP_CRY);
517 aop->aopu.aop_dir = sym->rname ;
518 aop->size = getSize(sym->type);
519 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
522 /* if it is in direct space */
523 if (IN_DIRSPACE(space)) {
524 sym->aop = aop = newAsmop (AOP_DIR);
525 aop->aopu.aop_dir = sym->rname ;
526 aop->size = getSize(sym->type);
527 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
531 /* special case for a function */
532 if (IS_FUNC(sym->type)) {
533 sym->aop = aop = newAsmop(AOP_IMMD);
534 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
535 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
536 strcpy(aop->aopu.aop_immd,sym->rname);
537 aop->size = FPTRSIZE;
538 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
543 /* only remaining is far space */
544 /* in which case DPTR gets the address */
545 sym->aop = aop = newAsmop(AOP_PCODE);
547 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
548 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
549 PCOI(aop->aopu.pcop)->index = 0;
551 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
552 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
554 pic16_allocDirReg (IC_LEFT(ic));
556 aop->size = FPTRSIZE;
558 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
559 sym->aop = aop = newAsmop(AOP_DPTR);
560 pic16_emitcode ("mov","dptr,#%s", sym->rname);
561 aop->size = getSize(sym->type);
563 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
566 /* if it is in code space */
567 if (IN_CODESPACE(space))
573 /*-----------------------------------------------------------------*/
574 /* aopForRemat - rematerialzes an object */
575 /*-----------------------------------------------------------------*/
576 static asmop *aopForRemat (operand *op) // x symbol *sym)
578 symbol *sym = OP_SYMBOL(op);
580 asmop *aop = newAsmop(AOP_PCODE);
584 ic = sym->rematiCode;
586 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
587 if(IS_OP_POINTER(op)) {
588 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
592 val += (int) operandLitValue(IC_RIGHT(ic));
593 } else if (ic->op == '-') {
594 val -= (int) operandLitValue(IC_RIGHT(ic));
598 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
601 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
602 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
603 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
604 PCOI(aop->aopu.pcop)->index = val;
606 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
607 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
608 val, IS_PTR_CONST(operandType(op)));
610 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
612 pic16_allocDirReg (IC_LEFT(ic));
617 static int aopIdx (asmop *aop, int offset)
622 if(aop->type != AOP_REG)
625 return aop->aopu.aop_reg[offset]->rIdx;
628 /*-----------------------------------------------------------------*/
629 /* regsInCommon - two operands have some registers in common */
630 /*-----------------------------------------------------------------*/
631 static bool regsInCommon (operand *op1, operand *op2)
636 /* if they have registers in common */
637 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
640 sym1 = OP_SYMBOL(op1);
641 sym2 = OP_SYMBOL(op2);
643 if (sym1->nRegs == 0 || sym2->nRegs == 0)
646 for (i = 0 ; i < sym1->nRegs ; i++) {
651 for (j = 0 ; j < sym2->nRegs ;j++ ) {
655 if (sym2->regs[j] == sym1->regs[i])
663 /*-----------------------------------------------------------------*/
664 /* operandsEqu - equivalent */
665 /*-----------------------------------------------------------------*/
666 static bool operandsEqu ( operand *op1, operand *op2)
670 /* if they not symbols */
671 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
674 sym1 = OP_SYMBOL(op1);
675 sym2 = OP_SYMBOL(op2);
677 /* if both are itemps & one is spilt
678 and the other is not then false */
679 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
680 sym1->isspilt != sym2->isspilt )
683 /* if they are the same */
687 if (strcmp(sym1->rname,sym2->rname) == 0)
691 /* if left is a tmp & right is not */
695 (sym1->usl.spillLoc == sym2))
702 (sym2->usl.spillLoc == sym1))
708 /*-----------------------------------------------------------------*/
709 /* pic16_sameRegs - two asmops have the same registers */
710 /*-----------------------------------------------------------------*/
711 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
718 if (aop1->type != AOP_REG ||
719 aop2->type != AOP_REG )
722 if (aop1->size != aop2->size )
725 for (i = 0 ; i < aop1->size ; i++ )
726 if (aop1->aopu.aop_reg[i] !=
727 aop2->aopu.aop_reg[i] )
733 /*-----------------------------------------------------------------*/
734 /* pic16_aopOp - allocates an asmop for an operand : */
735 /*-----------------------------------------------------------------*/
736 void pic16_aopOp (operand *op, iCode *ic, bool result)
745 // DEBUGpic16_emitcode(";","%d",__LINE__);
746 /* if this a literal */
747 if (IS_OP_LITERAL(op)) {
748 op->aop = aop = newAsmop(AOP_LIT);
749 aop->aopu.aop_lit = op->operand.valOperand;
750 aop->size = getSize(operandType(op));
755 sym_link *type = operandType(op);
756 if(IS_PTR_CONST(type))
757 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
760 /* if already has a asmop then continue */
764 /* if the underlying symbol has a aop */
765 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
766 DEBUGpic16_emitcode(";","%d",__LINE__);
767 op->aop = OP_SYMBOL(op)->aop;
771 /* if this is a true symbol */
772 if (IS_TRUE_SYMOP(op)) {
773 //DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
774 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
778 /* this is a temporary : this has
784 e) can be a return use only */
789 /* if the type is a conditional */
790 if (sym->regType == REG_CND) {
791 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
796 /* if it is spilt then two situations
798 b) has a spill location */
799 if (sym->isspilt || sym->nRegs == 0) {
801 DEBUGpic16_emitcode(";","%d",__LINE__);
802 /* rematerialize it NOW */
805 sym->aop = op->aop = aop =
807 aop->size = getSize(sym->type);
808 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
814 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
815 aop->size = getSize(sym->type);
816 for ( i = 0 ; i < 2 ; i++ )
817 aop->aopu.aop_str[i] = accUse[i];
818 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
824 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
825 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
826 //pic16_allocDirReg (IC_LEFT(ic));
827 aop->size = getSize(sym->type);
832 aop = op->aop = sym->aop = newAsmop(AOP_STR);
833 aop->size = getSize(sym->type);
834 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
835 aop->aopu.aop_str[i] = fReturn[i];
837 DEBUGpic16_emitcode(";","%d",__LINE__);
841 /* else spill location */
842 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
843 /* force a new aop if sizes differ */
844 sym->usl.spillLoc->aop = NULL;
846 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
847 __FUNCTION__,__LINE__,
848 sym->usl.spillLoc->rname,
849 sym->rname, sym->usl.spillLoc->offset);
851 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
852 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
853 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
855 sym->usl.spillLoc->offset);
856 aop->size = getSize(sym->type);
862 sym_link *type = operandType(op);
863 if(IS_PTR_CONST(type))
864 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
867 /* must be in a register */
868 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
869 sym->aop = op->aop = aop = newAsmop(AOP_REG);
870 aop->size = sym->nRegs;
871 for ( i = 0 ; i < sym->nRegs ;i++)
872 aop->aopu.aop_reg[i] = sym->regs[i];
875 /*-----------------------------------------------------------------*/
876 /* pic16_freeAsmop - free up the asmop given to an operand */
877 /*----------------------------------------------------------------*/
878 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
895 /* depending on the asmop type only three cases need work AOP_RO
896 , AOP_R1 && AOP_STK */
902 pic16_emitcode ("pop","ar0");
906 bitVectUnSetBit(ic->rUsed,R0_IDX);
912 pic16_emitcode ("pop","ar1");
916 bitVectUnSetBit(ic->rUsed,R1_IDX);
922 int stk = aop->aopu.aop_stk + aop->size;
923 bitVectUnSetBit(ic->rUsed,R0_IDX);
924 bitVectUnSetBit(ic->rUsed,R1_IDX);
926 getFreePtr(ic,&aop,FALSE);
928 if (options.stack10bit)
930 /* I'm not sure what to do here yet... */
933 "*** Warning: probably generating bad code for "
934 "10 bit stack mode.\n");
938 pic16_emitcode ("mov","a,_bp");
939 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
940 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
942 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
946 pic16_emitcode("pop","acc");
947 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
949 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
952 pic16_freeAsmop(op,NULL,ic,TRUE);
954 pic16_emitcode("pop","ar0");
959 pic16_emitcode("pop","ar1");
967 /* all other cases just dealloc */
971 OP_SYMBOL(op)->aop = NULL;
972 /* if the symbol has a spill */
974 SPIL_LOC(op)->aop = NULL;
979 /*-----------------------------------------------------------------*/
980 /* pic16_aopGet - for fetching value of the aop */
981 /*-----------------------------------------------------------------*/
982 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
987 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
988 /* offset is greater than
990 if (offset > (aop->size - 1) &&
991 aop->type != AOP_LIT)
994 /* depending on type */
999 DEBUGpic16_emitcode(";","%d",__LINE__);
1000 /* if we need to increment it */
1001 while (offset > aop->coff) {
1002 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1006 while (offset < aop->coff) {
1007 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1011 aop->coff = offset ;
1013 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1014 return (dname ? "acc" : "a");
1016 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1017 rs = Safe_calloc(1,strlen(s)+1);
1023 DEBUGpic16_emitcode(";","%d",__LINE__);
1024 if (aop->type == AOP_DPTR2)
1029 while (offset > aop->coff) {
1030 pic16_emitcode ("inc","dptr");
1034 while (offset < aop->coff) {
1035 pic16_emitcode("lcall","__decdptr");
1041 pic16_emitcode("clr","a");
1042 pic16_emitcode("movc","a,@a+dptr");
1045 pic16_emitcode("movx","a,@dptr");
1048 if (aop->type == AOP_DPTR2)
1053 return (dname ? "acc" : "a");
1058 sprintf (s,"%s",aop->aopu.aop_immd);
1061 sprintf(s,"(%s >> %d)",
1066 aop->aopu.aop_immd);
1067 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1068 rs = Safe_calloc(1,strlen(s)+1);
1074 sprintf(s,"(%s + %d)",
1077 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1079 sprintf(s,"%s",aop->aopu.aop_dir);
1080 rs = Safe_calloc(1,strlen(s)+1);
1086 // return aop->aopu.aop_reg[offset]->dname;
1088 return aop->aopu.aop_reg[offset]->name;
1091 //pic16_emitcode(";","%d",__LINE__);
1092 return aop->aopu.aop_dir;
1095 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1096 return "AOP_accumulator_bug";
1099 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1100 rs = Safe_calloc(1,strlen(s)+1);
1105 aop->coff = offset ;
1106 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1109 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1111 return aop->aopu.aop_str[offset];
1115 pCodeOp *pcop = aop->aopu.pcop;
1116 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1118 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1119 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1120 sprintf(s,"%s", pcop->name);
1122 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1125 rs = Safe_calloc(1,strlen(s)+1);
1131 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1132 "aopget got unsupported aop->type");
1137 /*-----------------------------------------------------------------*/
1138 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1139 /*-----------------------------------------------------------------*/
1140 pCodeOp *pic16_popGetTempReg(void)
1145 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1146 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1147 PCOR(pcop)->r->wasUsed=1;
1148 PCOR(pcop)->r->isFree=0;
1154 /*-----------------------------------------------------------------*/
1155 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1156 /*-----------------------------------------------------------------*/
1157 void pic16_popReleaseTempReg(pCodeOp *pcop)
1160 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1161 PCOR(pcop)->r->isFree = 1;
1164 /*-----------------------------------------------------------------*/
1165 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1166 /*-----------------------------------------------------------------*/
1167 pCodeOp *pic16_popGetLabel(unsigned int key)
1170 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1175 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1178 /*-----------------------------------------------------------------*/
1179 /* pic16_popCopyReg - copy a pcode operator */
1180 /*-----------------------------------------------------------------*/
1181 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1185 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1186 pcor->pcop.type = pc->pcop.type;
1188 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1189 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1191 pcor->pcop.name = NULL;
1194 pcor->rIdx = pc->rIdx;
1197 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1201 /*-----------------------------------------------------------------*/
1202 /* pic16_popGet - asm operator to pcode operator conversion */
1203 /*-----------------------------------------------------------------*/
1204 pCodeOp *pic16_popGetLit(unsigned int lit)
1207 return pic16_newpCodeOpLit(lit);
1211 /*-----------------------------------------------------------------*/
1212 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1217 return pic16_newpCodeOpImmd(name, offset,index, 0);
1221 /*-----------------------------------------------------------------*/
1222 /* pic16_popGet - asm operator to pcode operator conversion */
1223 /*-----------------------------------------------------------------*/
1224 pCodeOp *pic16_popGetWithString(char *str)
1230 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1234 pcop = pic16_newpCodeOp(str,PO_STR);
1239 /*-----------------------------------------------------------------*/
1240 /* popRegFromString - */
1241 /*-----------------------------------------------------------------*/
1242 static pCodeOp *popRegFromString(char *str, int size, int offset)
1245 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1246 pcop->type = PO_DIR;
1248 DEBUGpic16_emitcode(";","%d",__LINE__);
1253 pcop->name = Safe_calloc(1,strlen(str)+1);
1254 strcpy(pcop->name,str);
1256 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1258 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1259 if(PCOR(pcop)->r == NULL) {
1260 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1261 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1262 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1264 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1266 PCOR(pcop)->instance = offset;
1271 static pCodeOp *popRegFromIdx(int rIdx)
1275 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1276 __FUNCTION__,__LINE__,rIdx);
1278 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1280 PCOR(pcop)->rIdx = rIdx;
1281 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1282 PCOR(pcop)->r->isFree = 0;
1283 PCOR(pcop)->r->wasUsed = 1;
1285 pcop->type = PCOR(pcop)->r->pc_type;
1290 /*-----------------------------------------------------------------*/
1291 /* pic16_popGet - asm operator to pcode operator conversion */
1292 /*-----------------------------------------------------------------*/
1293 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1295 //char *s = buffer ;
1300 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1301 /* offset is greater than
1304 if (offset > (aop->size - 1) &&
1305 aop->type != AOP_LIT)
1306 return NULL; //zero;
1308 /* depending on type */
1309 switch (aop->type) {
1316 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1320 DEBUGpic16_emitcode(";","%d",__LINE__);
1321 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1324 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1326 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1327 pcop->type = PO_DIR;
1331 sprintf(s,"(%s + %d)",
1335 sprintf(s,"%s",aop->aopu.aop_dir);
1336 pcop->name = Safe_calloc(1,strlen(s)+1);
1337 strcpy(pcop->name,s);
1339 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1340 strcpy(pcop->name,aop->aopu.aop_dir);
1341 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1342 if(PCOR(pcop)->r == NULL) {
1343 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1344 PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1345 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1347 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1349 PCOR(pcop)->instance = offset;
1356 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1358 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1359 PCOR(pcop)->rIdx = rIdx;
1360 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1361 PCOR(pcop)->r->wasUsed=1;
1362 PCOR(pcop)->r->isFree=0;
1364 PCOR(pcop)->instance = offset;
1365 pcop->type = PCOR(pcop)->r->pc_type;
1366 //rs = aop->aopu.aop_reg[offset]->name;
1367 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1372 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1373 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1374 //if(PCOR(pcop)->r == NULL)
1375 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1379 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1382 DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1383 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1385 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1386 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1387 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1388 pcop->type = PCOR(pcop)->r->pc_type;
1389 pcop->name = PCOR(pcop)->r->name;
1395 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1397 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1398 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1399 PCOI(pcop)->offset = offset;
1403 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1404 "pic16_popGet got unsupported aop->type");
1407 /*-----------------------------------------------------------------*/
1408 /* pic16_aopPut - puts a string for a aop */
1409 /*-----------------------------------------------------------------*/
1410 void pic16_aopPut (asmop *aop, char *s, int offset)
1415 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1417 if (aop->size && offset > ( aop->size - 1)) {
1418 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1419 "pic16_aopPut got offset > aop->size");
1423 /* will assign value to value */
1424 /* depending on where it is ofcourse */
1425 switch (aop->type) {
1428 sprintf(d,"(%s + %d)",
1429 aop->aopu.aop_dir,offset);
1430 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1433 sprintf(d,"%s",aop->aopu.aop_dir);
1436 DEBUGpic16_emitcode(";","%d",__LINE__);
1438 pic16_emitcode("movf","%s,w",s);
1439 pic16_emitcode("movwf","%s",d);
1442 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1443 if(offset >= aop->size) {
1444 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1447 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1450 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1457 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1458 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1461 strcmp(s,"r0") == 0 ||
1462 strcmp(s,"r1") == 0 ||
1463 strcmp(s,"r2") == 0 ||
1464 strcmp(s,"r3") == 0 ||
1465 strcmp(s,"r4") == 0 ||
1466 strcmp(s,"r5") == 0 ||
1467 strcmp(s,"r6") == 0 ||
1468 strcmp(s,"r7") == 0 )
1469 pic16_emitcode("mov","%s,%s ; %d",
1470 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1474 if(strcmp(s,"W")==0 )
1475 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1477 pic16_emitcode("movwf","%s",
1478 aop->aopu.aop_reg[offset]->name);
1480 if(strcmp(s,zero)==0) {
1481 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1483 } else if(strcmp(s,"W")==0) {
1484 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1485 pcop->type = PO_GPR_REGISTER;
1487 PCOR(pcop)->rIdx = -1;
1488 PCOR(pcop)->r = NULL;
1490 DEBUGpic16_emitcode(";","%d",__LINE__);
1491 pcop->name = Safe_strdup(s);
1492 pic16_emitpcode(POC_MOVFW,pcop);
1493 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1494 } else if(strcmp(s,one)==0) {
1495 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1496 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1498 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1506 if (aop->type == AOP_DPTR2)
1512 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1513 "pic16_aopPut writting to code space");
1517 while (offset > aop->coff) {
1519 pic16_emitcode ("inc","dptr");
1522 while (offset < aop->coff) {
1524 pic16_emitcode("lcall","__decdptr");
1529 /* if not in accumulater */
1532 pic16_emitcode ("movx","@dptr,a");
1534 if (aop->type == AOP_DPTR2)
1542 while (offset > aop->coff) {
1544 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1546 while (offset < aop->coff) {
1548 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1554 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1559 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1561 if (strcmp(s,"r0") == 0 ||
1562 strcmp(s,"r1") == 0 ||
1563 strcmp(s,"r2") == 0 ||
1564 strcmp(s,"r3") == 0 ||
1565 strcmp(s,"r4") == 0 ||
1566 strcmp(s,"r5") == 0 ||
1567 strcmp(s,"r6") == 0 ||
1568 strcmp(s,"r7") == 0 ) {
1570 sprintf(buffer,"a%s",s);
1571 pic16_emitcode("mov","@%s,%s",
1572 aop->aopu.aop_ptr->name,buffer);
1574 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1579 if (strcmp(s,"a") == 0)
1580 pic16_emitcode("push","acc");
1582 pic16_emitcode("push","%s",s);
1587 /* if bit variable */
1588 if (!aop->aopu.aop_dir) {
1589 pic16_emitcode("clr","a");
1590 pic16_emitcode("rlc","a");
1593 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1596 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1599 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1601 lbl = newiTempLabel(NULL);
1603 if (strcmp(s,"a")) {
1606 pic16_emitcode("clr","c");
1607 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1608 pic16_emitcode("cpl","c");
1609 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1610 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1617 if (strcmp(aop->aopu.aop_str[offset],s))
1618 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1623 if (!offset && (strcmp(s,"acc") == 0))
1626 if (strcmp(aop->aopu.aop_str[offset],s))
1627 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1631 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1632 "pic16_aopPut got unsupported aop->type");
1638 /*-----------------------------------------------------------------*/
1639 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1640 /*-----------------------------------------------------------------*/
1641 static void mov2w (asmop *aop, int offset)
1647 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1649 if ( aop->type == AOP_PCODE ||
1650 aop->type == AOP_LIT )
1651 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1653 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1657 /*-----------------------------------------------------------------*/
1658 /* reAdjustPreg - points a register back to where it should */
1659 /*-----------------------------------------------------------------*/
1660 static void reAdjustPreg (asmop *aop)
1664 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1666 if ((size = aop->size) <= 1)
1669 switch (aop->type) {
1673 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1677 if (aop->type == AOP_DPTR2)
1683 pic16_emitcode("lcall","__decdptr");
1686 if (aop->type == AOP_DPTR2)
1696 /*-----------------------------------------------------------------*/
1697 /* genNotFloat - generates not for float operations */
1698 /*-----------------------------------------------------------------*/
1699 static void genNotFloat (operand *op, operand *res)
1705 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1706 /* we will put 127 in the first byte of
1708 pic16_aopPut(AOP(res),"#127",0);
1709 size = AOP_SIZE(op) - 1;
1712 l = pic16_aopGet(op->aop,offset++,FALSE,FALSE);
1716 pic16_emitcode("orl","a,%s",
1717 pic16_aopGet(op->aop,
1718 offset++,FALSE,FALSE));
1720 tlbl = newiTempLabel(NULL);
1722 tlbl = newiTempLabel(NULL);
1723 pic16_aopPut(res->aop,one,1);
1724 pic16_emitcode("jz","%05d_DS_",(tlbl->key+100));
1725 pic16_aopPut(res->aop,zero,1);
1726 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
1728 size = res->aop->size - 2;
1730 /* put zeros in the rest */
1732 pic16_aopPut(res->aop,zero,offset++);
1736 /*-----------------------------------------------------------------*/
1737 /* opIsGptr: returns non-zero if the passed operand is */
1738 /* a generic pointer type. */
1739 /*-----------------------------------------------------------------*/
1740 static int opIsGptr(operand *op)
1742 sym_link *type = operandType(op);
1744 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1745 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1753 /*-----------------------------------------------------------------*/
1754 /* pic16_getDataSize - get the operand data size */
1755 /*-----------------------------------------------------------------*/
1756 int pic16_getDataSize(operand *op)
1758 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1761 return AOP_SIZE(op);
1763 // tsd- in the pic port, the genptr size is 1, so this code here
1764 // fails. ( in the 8051 port, the size was 4).
1767 size = AOP_SIZE(op);
1768 if (size == GPTRSIZE)
1770 sym_link *type = operandType(op);
1771 if (IS_GENPTR(type))
1773 /* generic pointer; arithmetic operations
1774 * should ignore the high byte (pointer type).
1777 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1784 /*-----------------------------------------------------------------*/
1785 /* pic16_outAcc - output Acc */
1786 /*-----------------------------------------------------------------*/
1787 void pic16_outAcc(operand *result)
1790 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1791 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1794 size = pic16_getDataSize(result);
1796 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1799 /* unsigned or positive */
1801 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1806 /*-----------------------------------------------------------------*/
1807 /* pic16_outBitC - output a bit C */
1808 /*-----------------------------------------------------------------*/
1809 void pic16_outBitC(operand *result)
1812 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1813 /* if the result is bit */
1814 if (AOP_TYPE(result) == AOP_CRY)
1815 pic16_aopPut(AOP(result),"c",0);
1817 pic16_emitcode("clr","a ; %d", __LINE__);
1818 pic16_emitcode("rlc","a");
1819 pic16_outAcc(result);
1823 /*-----------------------------------------------------------------*/
1824 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1825 /*-----------------------------------------------------------------*/
1826 void pic16_toBoolean(operand *oper)
1828 int size = AOP_SIZE(oper) - 1;
1831 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1833 if ( AOP_TYPE(oper) != AOP_ACC) {
1834 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1837 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1842 /*-----------------------------------------------------------------*/
1843 /* genNot - generate code for ! operation */
1844 /*-----------------------------------------------------------------*/
1845 static void genNot (iCode *ic)
1848 sym_link *optype = operandType(IC_LEFT(ic));
1851 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1852 /* assign asmOps to operand & result */
1853 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1854 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1856 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1857 /* if in bit space then a special case */
1858 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1859 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1860 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1861 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1863 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1864 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1865 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1870 /* if type float then do float */
1871 if (IS_FLOAT(optype)) {
1872 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1876 size = AOP_SIZE(IC_RESULT(ic));
1878 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1879 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1880 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1883 pic16_toBoolean(IC_LEFT(ic));
1885 tlbl = newiTempLabel(NULL);
1886 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1887 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1888 pic16_outBitC(IC_RESULT(ic));
1891 /* release the aops */
1892 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1893 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1897 /*-----------------------------------------------------------------*/
1898 /* genCpl - generate code for complement */
1899 /*-----------------------------------------------------------------*/
1900 static void genCpl (iCode *ic)
1906 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1907 /* assign asmOps to operand & result */
1908 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1909 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1911 /* if both are in bit space then
1913 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1914 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1916 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1917 pic16_emitcode("cpl","c");
1918 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1922 size = AOP_SIZE(IC_RESULT(ic));
1925 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1927 pic16_emitcode("cpl","a");
1928 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1930 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1931 DEBUGpic16_emitcode("; ", "same registers");
1932 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
1934 DEBUGpic16_emitcode(";", "not sames registers!");
1935 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1936 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1944 /* release the aops */
1945 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1946 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1949 /*-----------------------------------------------------------------*/
1950 /* genUminusFloat - unary minus for floating points */
1951 /*-----------------------------------------------------------------*/
1952 static void genUminusFloat(operand *op,operand *result)
1954 int size ,offset =0 ;
1957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1958 /* for this we just need to flip the
1959 first it then copy the rest in place */
1960 size = AOP_SIZE(op) - 1;
1961 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1965 pic16_emitcode("cpl","acc.7");
1966 pic16_aopPut(AOP(result),"a",3);
1969 pic16_aopPut(AOP(result),
1970 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1976 /*-----------------------------------------------------------------*/
1977 /* genUminus - unary minus code generation */
1978 /*-----------------------------------------------------------------*/
1979 static void genUminus (iCode *ic)
1982 sym_link *optype, *rtype;
1985 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1987 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1988 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1990 /* if both in bit space then special
1992 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1993 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1995 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1996 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
1997 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2002 optype = operandType(IC_LEFT(ic));
2003 rtype = operandType(IC_RESULT(ic));
2005 /* if float then do float stuff */
2006 if (IS_FLOAT(optype)) {
2007 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2011 /* otherwise subtract from zero by taking the 2's complement */
2012 size = AOP_SIZE(IC_LEFT(ic));
2014 for(i=0; i<size; i++) {
2015 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2016 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2018 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2019 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2023 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2024 for(i=1; i<size; i++) {
2026 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2030 /* release the aops */
2031 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2032 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2035 /*-----------------------------------------------------------------*/
2036 /* saveRegisters - will look for a call and save the registers */
2037 /*-----------------------------------------------------------------*/
2038 static void saveRegisters(iCode *lic)
2045 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2047 for (ic = lic ; ic ; ic = ic->next)
2048 if (ic->op == CALL || ic->op == PCALL)
2052 fprintf(stderr,"found parameter push with no function call\n");
2056 /* if the registers have been saved already then
2058 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2061 /* find the registers in use at this time
2062 and push them away to safety */
2063 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2067 if (options.useXstack) {
2068 if (bitVectBitValue(rsave,R0_IDX))
2069 pic16_emitcode("mov","b,r0");
2070 pic16_emitcode("mov","r0,%s",spname);
2071 for (i = 0 ; i < pic16_nRegs ; i++) {
2072 if (bitVectBitValue(rsave,i)) {
2074 pic16_emitcode("mov","a,b");
2076 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2077 pic16_emitcode("movx","@r0,a");
2078 pic16_emitcode("inc","r0");
2081 pic16_emitcode("mov","%s,r0",spname);
2082 if (bitVectBitValue(rsave,R0_IDX))
2083 pic16_emitcode("mov","r0,b");
2085 //for (i = 0 ; i < pic16_nRegs ; i++) {
2086 // if (bitVectBitValue(rsave,i))
2087 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2090 dtype = operandType(IC_LEFT(ic));
2091 if (currFunc && dtype &&
2092 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2093 IFFUNC_ISISR(currFunc->type) &&
2096 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2099 /*-----------------------------------------------------------------*/
2100 /* unsaveRegisters - pop the pushed registers */
2101 /*-----------------------------------------------------------------*/
2102 static void unsaveRegisters (iCode *ic)
2107 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2108 /* find the registers in use at this time
2109 and push them away to safety */
2110 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2113 if (options.useXstack) {
2114 pic16_emitcode("mov","r0,%s",spname);
2115 for (i = pic16_nRegs ; i >= 0 ; i--) {
2116 if (bitVectBitValue(rsave,i)) {
2117 pic16_emitcode("dec","r0");
2118 pic16_emitcode("movx","a,@r0");
2120 pic16_emitcode("mov","b,a");
2122 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2126 pic16_emitcode("mov","%s,r0",spname);
2127 if (bitVectBitValue(rsave,R0_IDX))
2128 pic16_emitcode("mov","r0,b");
2130 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2131 // if (bitVectBitValue(rsave,i))
2132 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2138 /*-----------------------------------------------------------------*/
2140 /*-----------------------------------------------------------------*/
2141 static void pushSide(operand * oper, int size)
2145 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2147 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2148 if (AOP_TYPE(oper) != AOP_REG &&
2149 AOP_TYPE(oper) != AOP_DIR &&
2151 pic16_emitcode("mov","a,%s",l);
2152 pic16_emitcode("push","acc");
2154 pic16_emitcode("push","%s",l);
2159 /*-----------------------------------------------------------------*/
2160 /* assignResultValue - */
2161 /*-----------------------------------------------------------------*/
2162 static void assignResultValue(operand * oper)
2164 int size = AOP_SIZE(oper);
2166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2168 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2170 if(!GpsuedoStkPtr) {
2171 /* The last byte in the assignment is in W */
2173 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2178 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2180 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2185 /*-----------------------------------------------------------------*/
2186 /* genIpush - genrate code for pushing this gets a little complex */
2187 /*-----------------------------------------------------------------*/
2188 static void genIpush (iCode *ic)
2191 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2193 int size, offset = 0 ;
2197 /* if this is not a parm push : ie. it is spill push
2198 and spill push is always done on the local stack */
2199 if (!ic->parmPush) {
2201 /* and the item is spilt then do nothing */
2202 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2205 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2206 size = AOP_SIZE(IC_LEFT(ic));
2207 /* push it on the stack */
2209 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2214 pic16_emitcode("push","%s",l);
2219 /* this is a paramter push: in this case we call
2220 the routine to find the call and save those
2221 registers that need to be saved */
2224 /* then do the push */
2225 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2228 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2229 size = AOP_SIZE(IC_LEFT(ic));
2232 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2233 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2234 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2236 pic16_emitcode("mov","a,%s",l);
2237 pic16_emitcode("push","acc");
2239 pic16_emitcode("push","%s",l);
2242 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2246 /*-----------------------------------------------------------------*/
2247 /* genIpop - recover the registers: can happen only for spilling */
2248 /*-----------------------------------------------------------------*/
2249 static void genIpop (iCode *ic)
2251 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2256 /* if the temp was not pushed then */
2257 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2260 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2261 size = AOP_SIZE(IC_LEFT(ic));
2264 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2267 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2271 /*-----------------------------------------------------------------*/
2272 /* unsaverbank - restores the resgister bank from stack */
2273 /*-----------------------------------------------------------------*/
2274 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2276 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2282 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2284 if (options.useXstack) {
2286 r = getFreePtr(ic,&aop,FALSE);
2289 pic16_emitcode("mov","%s,_spx",r->name);
2290 pic16_emitcode("movx","a,@%s",r->name);
2291 pic16_emitcode("mov","psw,a");
2292 pic16_emitcode("dec","%s",r->name);
2295 pic16_emitcode ("pop","psw");
2298 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2299 if (options.useXstack) {
2300 pic16_emitcode("movx","a,@%s",r->name);
2301 //pic16_emitcode("mov","(%s+%d),a",
2302 // regspic16[i].base,8*bank+regspic16[i].offset);
2303 pic16_emitcode("dec","%s",r->name);
2306 pic16_emitcode("pop",""); //"(%s+%d)",
2307 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2310 if (options.useXstack) {
2312 pic16_emitcode("mov","_spx,%s",r->name);
2313 pic16_freeAsmop(NULL,aop,ic,TRUE);
2319 /*-----------------------------------------------------------------*/
2320 /* saverbank - saves an entire register bank on the stack */
2321 /*-----------------------------------------------------------------*/
2322 static void saverbank (int bank, iCode *ic, bool pushPsw)
2324 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2330 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2331 if (options.useXstack) {
2334 r = getFreePtr(ic,&aop,FALSE);
2335 pic16_emitcode("mov","%s,_spx",r->name);
2339 for (i = 0 ; i < pic16_nRegs ;i++) {
2340 if (options.useXstack) {
2341 pic16_emitcode("inc","%s",r->name);
2342 //pic16_emitcode("mov","a,(%s+%d)",
2343 // regspic16[i].base,8*bank+regspic16[i].offset);
2344 pic16_emitcode("movx","@%s,a",r->name);
2346 pic16_emitcode("push","");// "(%s+%d)",
2347 //regspic16[i].base,8*bank+regspic16[i].offset);
2351 if (options.useXstack) {
2352 pic16_emitcode("mov","a,psw");
2353 pic16_emitcode("movx","@%s,a",r->name);
2354 pic16_emitcode("inc","%s",r->name);
2355 pic16_emitcode("mov","_spx,%s",r->name);
2356 pic16_freeAsmop (NULL,aop,ic,TRUE);
2359 pic16_emitcode("push","psw");
2361 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2367 /*-----------------------------------------------------------------*/
2368 /* genCall - generates a call statement */
2369 /*-----------------------------------------------------------------*/
2370 static void genCall (iCode *ic)
2374 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2376 /* if caller saves & we have not saved then */
2380 /* if we are calling a function that is not using
2381 the same register bank then we need to save the
2382 destination registers on the stack */
2383 dtype = operandType(IC_LEFT(ic));
2384 if (currFunc && dtype &&
2385 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2386 IFFUNC_ISISR(currFunc->type) &&
2389 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2391 /* if send set is not empty the assign */
2394 /* For the Pic port, there is no data stack.
2395 * So parameters passed to functions are stored
2396 * in registers. (The pCode optimizer will get
2397 * rid of most of these :).
2399 int psuedoStkPtr=-1;
2400 int firstTimeThruLoop = 1;
2402 _G.sendSet = reverseSet(_G.sendSet);
2404 /* First figure how many parameters are getting passed */
2405 for (sic = setFirstItem(_G.sendSet) ; sic ;
2406 sic = setNextItem(_G.sendSet)) {
2408 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2409 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2410 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2413 for (sic = setFirstItem(_G.sendSet) ; sic ;
2414 sic = setNextItem(_G.sendSet)) {
2415 int size, offset = 0;
2417 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2418 size = AOP_SIZE(IC_LEFT(sic));
2421 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2422 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2424 if(!firstTimeThruLoop) {
2425 /* If this is not the first time we've been through the loop
2426 * then we need to save the parameter in a temporary
2427 * register. The last byte of the last parameter is
2429 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2432 firstTimeThruLoop=0;
2434 //if (strcmp(l,fReturn[offset])) {
2435 mov2w (AOP(IC_LEFT(sic)), offset);
2437 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2438 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2439 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2441 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2446 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2451 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2452 OP_SYMBOL(IC_LEFT(ic))->rname :
2453 OP_SYMBOL(IC_LEFT(ic))->name));
2456 /* if we need assign a result value */
2457 if ((IS_ITEMP(IC_RESULT(ic)) &&
2458 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2459 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2460 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2463 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2466 assignResultValue(IC_RESULT(ic));
2468 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2469 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2471 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2474 /* adjust the stack for parameters if
2476 if (ic->parmBytes) {
2478 if (ic->parmBytes > 3) {
2479 pic16_emitcode("mov","a,%s",spname);
2480 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2481 pic16_emitcode("mov","%s,a",spname);
2483 for ( i = 0 ; i < ic->parmBytes ;i++)
2484 pic16_emitcode("dec","%s",spname);
2488 /* if register bank was saved then pop them */
2490 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2492 /* if we hade saved some registers then unsave them */
2493 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2494 unsaveRegisters (ic);
2499 /*-----------------------------------------------------------------*/
2500 /* genPcall - generates a call by pointer statement */
2501 /*-----------------------------------------------------------------*/
2502 static void genPcall (iCode *ic)
2505 symbol *rlbl = newiTempLabel(NULL);
2508 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2509 /* if caller saves & we have not saved then */
2513 /* if we are calling a function that is not using
2514 the same register bank then we need to save the
2515 destination registers on the stack */
2516 dtype = operandType(IC_LEFT(ic));
2517 if (currFunc && dtype &&
2518 IFFUNC_ISISR(currFunc->type) &&
2519 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2520 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2523 /* push the return address on to the stack */
2524 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2525 pic16_emitcode("push","acc");
2526 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2527 pic16_emitcode("push","acc");
2529 if (options.model == MODEL_FLAT24)
2531 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2532 pic16_emitcode("push","acc");
2535 /* now push the calling address */
2536 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2538 pushSide(IC_LEFT(ic), FPTRSIZE);
2540 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2542 /* if send set is not empty the assign */
2546 for (sic = setFirstItem(_G.sendSet) ; sic ;
2547 sic = setNextItem(_G.sendSet)) {
2548 int size, offset = 0;
2549 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2550 size = AOP_SIZE(IC_LEFT(sic));
2552 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2554 if (strcmp(l,fReturn[offset]))
2555 pic16_emitcode("mov","%s,%s",
2560 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2565 pic16_emitcode("ret","");
2566 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2569 /* if we need assign a result value */
2570 if ((IS_ITEMP(IC_RESULT(ic)) &&
2571 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2572 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2573 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2576 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2579 assignResultValue(IC_RESULT(ic));
2581 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2584 /* adjust the stack for parameters if
2586 if (ic->parmBytes) {
2588 if (ic->parmBytes > 3) {
2589 pic16_emitcode("mov","a,%s",spname);
2590 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2591 pic16_emitcode("mov","%s,a",spname);
2593 for ( i = 0 ; i < ic->parmBytes ;i++)
2594 pic16_emitcode("dec","%s",spname);
2598 /* if register bank was saved then unsave them */
2599 if (currFunc && dtype &&
2600 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2601 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2603 /* if we hade saved some registers then
2606 unsaveRegisters (ic);
2610 /*-----------------------------------------------------------------*/
2611 /* resultRemat - result is rematerializable */
2612 /*-----------------------------------------------------------------*/
2613 static int resultRemat (iCode *ic)
2615 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2616 if (SKIP_IC(ic) || ic->op == IFX)
2619 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2620 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2621 if (sym->remat && !POINTER_SET(ic))
2628 #if defined(__BORLANDC__) || defined(_MSC_VER)
2629 #define STRCASECMP stricmp
2631 #define STRCASECMP strcasecmp
2635 /*-----------------------------------------------------------------*/
2636 /* inExcludeList - return 1 if the string is in exclude Reg list */
2637 /*-----------------------------------------------------------------*/
2638 static bool inExcludeList(char *s)
2640 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2643 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2644 if (options.excludeRegs[i] &&
2645 STRCASECMP(options.excludeRegs[i],"none") == 0)
2648 for ( i = 0 ; options.excludeRegs[i]; i++) {
2649 if (options.excludeRegs[i] &&
2650 STRCASECMP(s,options.excludeRegs[i]) == 0)
2657 /*-----------------------------------------------------------------*/
2658 /* genFunction - generated code for function entry */
2659 /*-----------------------------------------------------------------*/
2660 static void genFunction (iCode *ic)
2665 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2667 labelOffset += (max_key+4);
2671 /* create the function header */
2672 pic16_emitcode(";","-----------------------------------------");
2673 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2674 pic16_emitcode(";","-----------------------------------------");
2676 pic16_emitcode("","%s:",sym->rname);
2677 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2679 ftype = operandType(IC_LEFT(ic));
2681 /* if critical function then turn interrupts off */
2682 if (IFFUNC_ISCRITICAL(ftype))
2683 pic16_emitcode("clr","ea");
2685 /* here we need to generate the equates for the
2686 register bank if required */
2688 if (FUNC_REGBANK(ftype) != rbank) {
2691 rbank = FUNC_REGBANK(ftype);
2692 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2693 if (strcmp(regspic16[i].base,"0") == 0)
2694 pic16_emitcode("","%s = 0x%02x",
2696 8*rbank+regspic16[i].offset);
2698 pic16_emitcode ("","%s = %s + 0x%02x",
2701 8*rbank+regspic16[i].offset);
2706 /* if this is an interrupt service routine then
2707 save acc, b, dpl, dph */
2708 if (IFFUNC_ISISR(sym->type)) {
2709 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2710 pic16_emitpcodeNULLop(POC_NOP);
2711 pic16_emitpcodeNULLop(POC_NOP);
2712 pic16_emitpcodeNULLop(POC_NOP);
2713 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2714 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2715 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2716 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2718 pic16_pBlockConvert2ISR(pb);
2720 if (!inExcludeList("acc"))
2721 pic16_emitcode ("push","acc");
2722 if (!inExcludeList("b"))
2723 pic16_emitcode ("push","b");
2724 if (!inExcludeList("dpl"))
2725 pic16_emitcode ("push","dpl");
2726 if (!inExcludeList("dph"))
2727 pic16_emitcode ("push","dph");
2728 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2730 pic16_emitcode ("push", "dpx");
2731 /* Make sure we're using standard DPTR */
2732 pic16_emitcode ("push", "dps");
2733 pic16_emitcode ("mov", "dps, #0x00");
2734 if (options.stack10bit)
2736 /* This ISR could conceivably use DPTR2. Better save it. */
2737 pic16_emitcode ("push", "dpl1");
2738 pic16_emitcode ("push", "dph1");
2739 pic16_emitcode ("push", "dpx1");
2742 /* if this isr has no bank i.e. is going to
2743 run with bank 0 , then we need to save more
2745 if (!FUNC_REGBANK(sym->type)) {
2747 /* if this function does not call any other
2748 function then we can be economical and
2749 save only those registers that are used */
2750 if (! IFFUNC_HASFCALL(sym->type)) {
2753 /* if any registers used */
2754 if (sym->regsUsed) {
2755 /* save the registers used */
2756 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2757 if (bitVectBitValue(sym->regsUsed,i) ||
2758 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2759 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2764 /* this function has a function call cannot
2765 determines register usage so we will have the
2767 saverbank(0,ic,FALSE);
2772 /* if callee-save to be used for this function
2773 then save the registers being used in this function */
2774 if (IFFUNC_CALLEESAVES(sym->type)) {
2777 /* if any registers used */
2778 if (sym->regsUsed) {
2779 /* save the registers used */
2780 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2781 if (bitVectBitValue(sym->regsUsed,i) ||
2782 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2783 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2791 /* set the register bank to the desired value */
2792 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2793 pic16_emitcode("push","psw");
2794 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2797 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2799 if (options.useXstack) {
2800 pic16_emitcode("mov","r0,%s",spname);
2801 pic16_emitcode("mov","a,_bp");
2802 pic16_emitcode("movx","@r0,a");
2803 pic16_emitcode("inc","%s",spname);
2807 /* set up the stack */
2808 pic16_emitcode ("push","_bp"); /* save the callers stack */
2810 pic16_emitcode ("mov","_bp,%s",spname);
2813 /* adjust the stack for the function */
2818 werror(W_STACK_OVERFLOW,sym->name);
2820 if (i > 3 && sym->recvSize < 4) {
2822 pic16_emitcode ("mov","a,sp");
2823 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2824 pic16_emitcode ("mov","sp,a");
2829 pic16_emitcode("inc","sp");
2834 pic16_emitcode ("mov","a,_spx");
2835 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2836 pic16_emitcode ("mov","_spx,a");
2841 /*-----------------------------------------------------------------*/
2842 /* genEndFunction - generates epilogue for functions */
2843 /*-----------------------------------------------------------------*/
2844 static void genEndFunction (iCode *ic)
2846 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2848 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2850 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2852 pic16_emitcode ("mov","%s,_bp",spname);
2855 /* if use external stack but some variables were
2856 added to the local stack then decrement the
2858 if (options.useXstack && sym->stack) {
2859 pic16_emitcode("mov","a,sp");
2860 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2861 pic16_emitcode("mov","sp,a");
2865 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2866 if (options.useXstack) {
2867 pic16_emitcode("mov","r0,%s",spname);
2868 pic16_emitcode("movx","a,@r0");
2869 pic16_emitcode("mov","_bp,a");
2870 pic16_emitcode("dec","%s",spname);
2874 pic16_emitcode ("pop","_bp");
2878 /* restore the register bank */
2879 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2880 pic16_emitcode ("pop","psw");
2882 if (IFFUNC_ISISR(sym->type)) {
2884 /* now we need to restore the registers */
2885 /* if this isr has no bank i.e. is going to
2886 run with bank 0 , then we need to save more
2888 if (!FUNC_REGBANK(sym->type)) {
2890 /* if this function does not call any other
2891 function then we can be economical and
2892 save only those registers that are used */
2893 if (! IFFUNC_HASFCALL(sym->type)) {
2896 /* if any registers used */
2897 if (sym->regsUsed) {
2898 /* save the registers used */
2899 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2900 if (bitVectBitValue(sym->regsUsed,i) ||
2901 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2902 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2907 /* this function has a function call cannot
2908 determines register usage so we will have the
2910 unsaverbank(0,ic,FALSE);
2914 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2916 if (options.stack10bit)
2918 pic16_emitcode ("pop", "dpx1");
2919 pic16_emitcode ("pop", "dph1");
2920 pic16_emitcode ("pop", "dpl1");
2922 pic16_emitcode ("pop", "dps");
2923 pic16_emitcode ("pop", "dpx");
2925 if (!inExcludeList("dph"))
2926 pic16_emitcode ("pop","dph");
2927 if (!inExcludeList("dpl"))
2928 pic16_emitcode ("pop","dpl");
2929 if (!inExcludeList("b"))
2930 pic16_emitcode ("pop","b");
2931 if (!inExcludeList("acc"))
2932 pic16_emitcode ("pop","acc");
2934 if (IFFUNC_ISCRITICAL(sym->type))
2935 pic16_emitcode("setb","ea");
2938 /* if debug then send end of function */
2939 /* if (options.debug && currFunc) { */
2942 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2943 FileBaseName(ic->filename),currFunc->lastLine,
2944 ic->level,ic->block);
2945 if (IS_STATIC(currFunc->etype))
2946 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2948 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2952 pic16_emitcode ("reti","");
2954 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2955 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2956 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
2957 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
2958 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2959 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2961 pic16_emitpcodeNULLop(POC_RETFIE);
2965 if (IFFUNC_ISCRITICAL(sym->type))
2966 pic16_emitcode("setb","ea");
2968 if (IFFUNC_CALLEESAVES(sym->type)) {
2971 /* if any registers used */
2972 if (sym->regsUsed) {
2973 /* save the registers used */
2974 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2975 if (bitVectBitValue(sym->regsUsed,i) ||
2976 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2977 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2983 /* if debug then send end of function */
2986 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2987 FileBaseName(ic->filename),currFunc->lastLine,
2988 ic->level,ic->block);
2989 if (IS_STATIC(currFunc->etype))
2990 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2992 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2996 pic16_emitcode ("return","");
2997 pic16_emitpcodeNULLop(POC_RETURN);
2999 /* Mark the end of a function */
3000 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3005 /*-----------------------------------------------------------------*/
3006 /* genRet - generate code for return statement */
3007 /*-----------------------------------------------------------------*/
3008 static void genRet (iCode *ic)
3010 int size,offset = 0 , pushed = 0;
3012 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3013 /* if we have no return value then
3014 just generate the "ret" */
3018 /* we have something to return then
3019 move the return value into place */
3020 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3021 size = AOP_SIZE(IC_LEFT(ic));
3025 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3027 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3029 pic16_emitcode("push","%s",l);
3032 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3034 if (strcmp(fReturn[offset],l)) {
3035 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3036 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3037 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3039 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3042 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3052 if (strcmp(fReturn[pushed],"a"))
3053 pic16_emitcode("pop",fReturn[pushed]);
3055 pic16_emitcode("pop","acc");
3058 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3061 /* generate a jump to the return label
3062 if the next is not the return statement */
3063 if (!(ic->next && ic->next->op == LABEL &&
3064 IC_LABEL(ic->next) == returnLabel)) {
3066 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3067 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3072 /*-----------------------------------------------------------------*/
3073 /* genLabel - generates a label */
3074 /*-----------------------------------------------------------------*/
3075 static void genLabel (iCode *ic)
3077 /* special case never generate */
3078 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3079 if (IC_LABEL(ic) == entryLabel)
3082 pic16_emitpLabel(IC_LABEL(ic)->key);
3083 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3086 /*-----------------------------------------------------------------*/
3087 /* genGoto - generates a goto */
3088 /*-----------------------------------------------------------------*/
3090 static void genGoto (iCode *ic)
3092 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3093 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3097 /*-----------------------------------------------------------------*/
3098 /* genMultbits :- multiplication of bits */
3099 /*-----------------------------------------------------------------*/
3100 static void genMultbits (operand *left,
3104 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3106 if(!pic16_sameRegs(AOP(result),AOP(right)))
3107 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3109 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3110 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3111 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3116 /*-----------------------------------------------------------------*/
3117 /* genMultOneByte : 8 bit multiplication & division */
3118 /*-----------------------------------------------------------------*/
3119 static void genMultOneByte (operand *left,
3123 sym_link *opetype = operandType(result);
3128 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3129 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3130 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3132 /* (if two literals, the value is computed before) */
3133 /* if one literal, literal on the right */
3134 if (AOP_TYPE(left) == AOP_LIT){
3140 size = AOP_SIZE(result);
3143 if (AOP_TYPE(right) == AOP_LIT){
3144 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3145 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3146 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3147 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3148 pic16_emitcode("call","genMultLit");
3150 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3151 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3152 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3153 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3154 pic16_emitcode("call","pic16_genMult8X8_8");
3157 pic16_genMult8X8_8 (left, right,result);
3160 /* signed or unsigned */
3161 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3162 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3164 //pic16_emitcode("mul","ab");
3165 /* if result size = 1, mul signed = mul unsigned */
3166 //pic16_aopPut(AOP(result),"a",0);
3168 } else { // (size > 1)
3170 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3171 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3172 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3173 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3175 if (SPEC_USIGN(opetype)){
3176 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3177 pic16_genUMult8X8_16 (left, right, result, NULL);
3180 /* for filling the MSBs */
3181 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3182 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3186 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3188 pic16_emitcode("mov","a,b");
3190 /* adjust the MSB if left or right neg */
3192 /* if one literal */
3193 if (AOP_TYPE(right) == AOP_LIT){
3194 pic16_emitcode("multiply ","right is a lit");
3195 /* AND literal negative */
3196 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3197 /* adjust MSB (c==0 after mul) */
3198 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3202 pic16_genSMult8X8_16 (left, right, result, NULL);
3206 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3208 pic16_emitcode("rlc","a");
3209 pic16_emitcode("subb","a,acc");
3217 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3218 //pic16_aopPut(AOP(result),"a",offset++);
3222 /*-----------------------------------------------------------------*/
3223 /* genMult - generates code for multiplication */
3224 /*-----------------------------------------------------------------*/
3225 static void genMult (iCode *ic)
3227 operand *left = IC_LEFT(ic);
3228 operand *right = IC_RIGHT(ic);
3229 operand *result= IC_RESULT(ic);
3231 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3232 /* assign the amsops */
3233 pic16_aopOp (left,ic,FALSE);
3234 pic16_aopOp (right,ic,FALSE);
3235 pic16_aopOp (result,ic,TRUE);
3237 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3239 /* special cases first */
3241 if (AOP_TYPE(left) == AOP_CRY &&
3242 AOP_TYPE(right)== AOP_CRY) {
3243 genMultbits(left,right,result);
3247 /* if both are of size == 1 */
3248 if (AOP_SIZE(left) == 1 &&
3249 AOP_SIZE(right) == 1 ) {
3250 genMultOneByte(left,right,result);
3254 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3256 /* should have been converted to function call */
3260 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3261 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3262 pic16_freeAsmop(result,NULL,ic,TRUE);
3265 /*-----------------------------------------------------------------*/
3266 /* genDivbits :- division of bits */
3267 /*-----------------------------------------------------------------*/
3268 static void genDivbits (operand *left,
3275 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3276 /* the result must be bit */
3277 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3278 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3282 pic16_emitcode("div","ab");
3283 pic16_emitcode("rrc","a");
3284 pic16_aopPut(AOP(result),"c",0);
3287 /*-----------------------------------------------------------------*/
3288 /* genDivOneByte : 8 bit division */
3289 /*-----------------------------------------------------------------*/
3290 static void genDivOneByte (operand *left,
3294 sym_link *opetype = operandType(result);
3299 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3300 size = AOP_SIZE(result) - 1;
3302 /* signed or unsigned */
3303 if (SPEC_USIGN(opetype)) {
3304 /* unsigned is easy */
3305 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3306 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3308 pic16_emitcode("div","ab");
3309 pic16_aopPut(AOP(result),"a",0);
3311 pic16_aopPut(AOP(result),zero,offset++);
3315 /* signed is a little bit more difficult */
3317 /* save the signs of the operands */
3318 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3320 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3321 pic16_emitcode("push","acc"); /* save it on the stack */
3323 /* now sign adjust for both left & right */
3324 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3326 lbl = newiTempLabel(NULL);
3327 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3328 pic16_emitcode("cpl","a");
3329 pic16_emitcode("inc","a");
3330 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3331 pic16_emitcode("mov","b,a");
3333 /* sign adjust left side */
3334 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3337 lbl = newiTempLabel(NULL);
3338 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3339 pic16_emitcode("cpl","a");
3340 pic16_emitcode("inc","a");
3341 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3343 /* now the division */
3344 pic16_emitcode("div","ab");
3345 /* we are interested in the lower order
3347 pic16_emitcode("mov","b,a");
3348 lbl = newiTempLabel(NULL);
3349 pic16_emitcode("pop","acc");
3350 /* if there was an over flow we don't
3351 adjust the sign of the result */
3352 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3353 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3355 pic16_emitcode("clr","a");
3356 pic16_emitcode("subb","a,b");
3357 pic16_emitcode("mov","b,a");
3358 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3360 /* now we are done */
3361 pic16_aopPut(AOP(result),"b",0);
3363 pic16_emitcode("mov","c,b.7");
3364 pic16_emitcode("subb","a,acc");
3367 pic16_aopPut(AOP(result),"a",offset++);
3371 /*-----------------------------------------------------------------*/
3372 /* genDiv - generates code for division */
3373 /*-----------------------------------------------------------------*/
3374 static void genDiv (iCode *ic)
3376 operand *left = IC_LEFT(ic);
3377 operand *right = IC_RIGHT(ic);
3378 operand *result= IC_RESULT(ic);
3380 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3381 /* assign the amsops */
3382 pic16_aopOp (left,ic,FALSE);
3383 pic16_aopOp (right,ic,FALSE);
3384 pic16_aopOp (result,ic,TRUE);
3386 /* special cases first */
3388 if (AOP_TYPE(left) == AOP_CRY &&
3389 AOP_TYPE(right)== AOP_CRY) {
3390 genDivbits(left,right,result);
3394 /* if both are of size == 1 */
3395 if (AOP_SIZE(left) == 1 &&
3396 AOP_SIZE(right) == 1 ) {
3397 genDivOneByte(left,right,result);
3401 /* should have been converted to function call */
3404 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3405 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3406 pic16_freeAsmop(result,NULL,ic,TRUE);
3409 /*-----------------------------------------------------------------*/
3410 /* genModbits :- modulus of bits */
3411 /*-----------------------------------------------------------------*/
3412 static void genModbits (operand *left,
3419 /* the result must be bit */
3420 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3421 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3425 pic16_emitcode("div","ab");
3426 pic16_emitcode("mov","a,b");
3427 pic16_emitcode("rrc","a");
3428 pic16_aopPut(AOP(result),"c",0);
3431 /*-----------------------------------------------------------------*/
3432 /* genModOneByte : 8 bit modulus */
3433 /*-----------------------------------------------------------------*/
3434 static void genModOneByte (operand *left,
3438 sym_link *opetype = operandType(result);
3442 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3443 /* signed or unsigned */
3444 if (SPEC_USIGN(opetype)) {
3445 /* unsigned is easy */
3446 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3447 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3449 pic16_emitcode("div","ab");
3450 pic16_aopPut(AOP(result),"b",0);
3454 /* signed is a little bit more difficult */
3456 /* save the signs of the operands */
3457 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3460 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3461 pic16_emitcode("push","acc"); /* save it on the stack */
3463 /* now sign adjust for both left & right */
3464 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3467 lbl = newiTempLabel(NULL);
3468 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3469 pic16_emitcode("cpl","a");
3470 pic16_emitcode("inc","a");
3471 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3472 pic16_emitcode("mov","b,a");
3474 /* sign adjust left side */
3475 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3478 lbl = newiTempLabel(NULL);
3479 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3480 pic16_emitcode("cpl","a");
3481 pic16_emitcode("inc","a");
3482 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3484 /* now the multiplication */
3485 pic16_emitcode("div","ab");
3486 /* we are interested in the lower order
3488 lbl = newiTempLabel(NULL);
3489 pic16_emitcode("pop","acc");
3490 /* if there was an over flow we don't
3491 adjust the sign of the result */
3492 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3493 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3495 pic16_emitcode("clr","a");
3496 pic16_emitcode("subb","a,b");
3497 pic16_emitcode("mov","b,a");
3498 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3500 /* now we are done */
3501 pic16_aopPut(AOP(result),"b",0);
3505 /*-----------------------------------------------------------------*/
3506 /* genMod - generates code for division */
3507 /*-----------------------------------------------------------------*/
3508 static void genMod (iCode *ic)
3510 operand *left = IC_LEFT(ic);
3511 operand *right = IC_RIGHT(ic);
3512 operand *result= IC_RESULT(ic);
3514 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3515 /* assign the amsops */
3516 pic16_aopOp (left,ic,FALSE);
3517 pic16_aopOp (right,ic,FALSE);
3518 pic16_aopOp (result,ic,TRUE);
3520 /* special cases first */
3522 if (AOP_TYPE(left) == AOP_CRY &&
3523 AOP_TYPE(right)== AOP_CRY) {
3524 genModbits(left,right,result);
3528 /* if both are of size == 1 */
3529 if (AOP_SIZE(left) == 1 &&
3530 AOP_SIZE(right) == 1 ) {
3531 genModOneByte(left,right,result);
3535 /* should have been converted to function call */
3539 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3540 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3541 pic16_freeAsmop(result,NULL,ic,TRUE);
3544 /*-----------------------------------------------------------------*/
3545 /* genIfxJump :- will create a jump depending on the ifx */
3546 /*-----------------------------------------------------------------*/
3548 note: May need to add parameter to indicate when a variable is in bit space.
3550 static void genIfxJump (iCode *ic, char *jval)
3553 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3554 /* if true label then we jump if condition
3556 if ( IC_TRUE(ic) ) {
3558 if(strcmp(jval,"a") == 0)
3560 else if (strcmp(jval,"c") == 0)
3563 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3564 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3567 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3568 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3572 /* false label is present */
3573 if(strcmp(jval,"a") == 0)
3575 else if (strcmp(jval,"c") == 0)
3578 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3579 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3582 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3583 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3588 /* mark the icode as generated */
3592 /*-----------------------------------------------------------------*/
3594 /*-----------------------------------------------------------------*/
3595 static void genSkip(iCode *ifx,int status_bit)
3600 if ( IC_TRUE(ifx) ) {
3601 switch(status_bit) {
3616 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3617 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3621 switch(status_bit) {
3635 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3636 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3642 /*-----------------------------------------------------------------*/
3644 /*-----------------------------------------------------------------*/
3645 static void genSkipc(resolvedIfx *rifx)
3655 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3656 rifx->generated = 1;
3659 /*-----------------------------------------------------------------*/
3661 /*-----------------------------------------------------------------*/
3662 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3667 if( (rifx->condition ^ invert_condition) & 1)
3672 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3673 rifx->generated = 1;
3676 /*-----------------------------------------------------------------*/
3678 /*-----------------------------------------------------------------*/
3679 static void genSkipz(iCode *ifx, int condition)
3690 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3692 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3695 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3697 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3700 /*-----------------------------------------------------------------*/
3702 /*-----------------------------------------------------------------*/
3703 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3709 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3711 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3714 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3715 rifx->generated = 1;
3719 /*-----------------------------------------------------------------*/
3720 /* genChkZeroes :- greater or less than comparison */
3721 /* For each byte in a literal that is zero, inclusive or the */
3722 /* the corresponding byte in the operand with W */
3723 /* returns true if any of the bytes are zero */
3724 /*-----------------------------------------------------------------*/
3725 static int genChkZeroes(operand *op, int lit, int size)
3732 i = (lit >> (size*8)) & 0xff;
3736 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3738 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3747 /*-----------------------------------------------------------------*/
3748 /* genCmp :- greater or less than comparison */
3749 /*-----------------------------------------------------------------*/
3750 static void genCmp (operand *left,operand *right,
3751 operand *result, iCode *ifx, int sign)
3753 int size; //, offset = 0 ;
3754 unsigned long lit = 0L,i = 0;
3755 resolvedIfx rFalseIfx;
3756 // resolvedIfx rTrueIfx;
3758 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3761 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3762 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3766 resolveIfx(&rFalseIfx,ifx);
3767 truelbl = newiTempLabel(NULL);
3768 size = max(AOP_SIZE(left),AOP_SIZE(right));
3770 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3774 /* if literal is on the right then swap with left */
3775 if ((AOP_TYPE(right) == AOP_LIT)) {
3776 operand *tmp = right ;
3777 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3778 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3781 lit = (lit - 1) & mask;
3784 rFalseIfx.condition ^= 1;
3787 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3788 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3792 //if(IC_TRUE(ifx) == NULL)
3793 /* if left & right are bit variables */
3794 if (AOP_TYPE(left) == AOP_CRY &&
3795 AOP_TYPE(right) == AOP_CRY ) {
3796 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3797 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3799 /* subtract right from left if at the
3800 end the carry flag is set then we know that
3801 left is greater than right */
3805 symbol *lbl = newiTempLabel(NULL);
3808 if(AOP_TYPE(right) == AOP_LIT) {
3810 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3812 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3819 genSkipCond(&rFalseIfx,left,size-1,7);
3821 /* no need to compare to 0...*/
3822 /* NOTE: this is a de-generate compare that most certainly
3823 * creates some dead code. */
3824 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3826 if(ifx) ifx->generated = 1;
3833 //i = (lit >> (size*8)) & 0xff;
3834 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3836 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3838 i = ((0-lit) & 0xff);
3841 /* lit is 0x7f, all signed chars are less than
3842 * this except for 0x7f itself */
3843 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3844 genSkipz2(&rFalseIfx,0);
3846 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3847 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3848 genSkipc(&rFalseIfx);
3853 genSkipz2(&rFalseIfx,1);
3855 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3856 genSkipc(&rFalseIfx);
3860 if(ifx) ifx->generated = 1;
3864 /* chars are out of the way. now do ints and longs */
3867 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3874 genSkipCond(&rFalseIfx,left,size,7);
3875 if(ifx) ifx->generated = 1;
3880 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3882 //rFalseIfx.condition ^= 1;
3883 //genSkipCond(&rFalseIfx,left,size,7);
3884 //rFalseIfx.condition ^= 1;
3886 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3887 if(rFalseIfx.condition)
3888 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3890 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3892 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3893 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3894 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3897 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3899 if(rFalseIfx.condition) {
3901 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3907 genSkipc(&rFalseIfx);
3908 pic16_emitpLabel(truelbl->key);
3909 if(ifx) ifx->generated = 1;
3916 if( (lit & 0xff) == 0) {
3917 /* lower byte is zero */
3918 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3919 i = ((lit >> 8) & 0xff) ^0x80;
3920 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3921 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3922 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3923 genSkipc(&rFalseIfx);
3926 if(ifx) ifx->generated = 1;
3931 /* Special cases for signed longs */
3932 if( (lit & 0xffffff) == 0) {
3933 /* lower byte is zero */
3934 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3935 i = ((lit >> 8*3) & 0xff) ^0x80;
3936 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3937 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3938 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3939 genSkipc(&rFalseIfx);
3942 if(ifx) ifx->generated = 1;
3950 if(lit & (0x80 << (size*8))) {
3951 /* lit is negative */
3952 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3954 //genSkipCond(&rFalseIfx,left,size,7);
3956 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3958 if(rFalseIfx.condition)
3959 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3961 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3965 /* lit is positive */
3966 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3967 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3968 if(rFalseIfx.condition)
3969 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3971 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3976 This works, but is only good for ints.
3977 It also requires a "known zero" register.
3978 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3979 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3980 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
3981 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3982 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3983 genSkipc(&rFalseIfx);
3985 pic16_emitpLabel(truelbl->key);
3986 if(ifx) ifx->generated = 1;
3990 /* There are no more special cases, so perform a general compare */
3992 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3993 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3997 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3999 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4001 //rFalseIfx.condition ^= 1;
4002 genSkipc(&rFalseIfx);
4004 pic16_emitpLabel(truelbl->key);
4006 if(ifx) ifx->generated = 1;
4013 /* sign is out of the way. So now do an unsigned compare */
4014 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4017 /* General case - compare to an unsigned literal on the right.*/
4019 i = (lit >> (size*8)) & 0xff;
4020 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4021 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4023 i = (lit >> (size*8)) & 0xff;
4026 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4028 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4030 /* this byte of the lit is zero,
4031 *if it's not the last then OR in the variable */
4033 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4038 pic16_emitpLabel(lbl->key);
4039 //if(emitFinalCheck)
4040 genSkipc(&rFalseIfx);
4042 pic16_emitpLabel(truelbl->key);
4044 if(ifx) ifx->generated = 1;
4051 if(AOP_TYPE(left) == AOP_LIT) {
4052 //symbol *lbl = newiTempLabel(NULL);
4054 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4057 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4060 if((lit == 0) && (sign == 0)){
4063 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4065 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4067 genSkipz2(&rFalseIfx,0);
4068 if(ifx) ifx->generated = 1;
4075 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4076 /* degenerate compare can never be true */
4077 if(rFalseIfx.condition == 0)
4078 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4080 if(ifx) ifx->generated = 1;
4085 /* signed comparisons to a literal byte */
4087 int lp1 = (lit+1) & 0xff;
4089 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4092 rFalseIfx.condition ^= 1;
4093 genSkipCond(&rFalseIfx,right,0,7);
4096 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4097 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4098 genSkipz2(&rFalseIfx,1);
4101 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4102 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4103 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4104 rFalseIfx.condition ^= 1;
4105 genSkipc(&rFalseIfx);
4109 /* unsigned comparisons to a literal byte */
4111 switch(lit & 0xff ) {
4113 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4114 genSkipz2(&rFalseIfx,0);
4117 rFalseIfx.condition ^= 1;
4118 genSkipCond(&rFalseIfx,right,0,7);
4122 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4123 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4124 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4125 rFalseIfx.condition ^= 1;
4126 if (AOP_TYPE(result) == AOP_CRY)
4127 genSkipc(&rFalseIfx);
4129 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4130 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4136 if(ifx) ifx->generated = 1;
4142 /* Size is greater than 1 */
4150 /* this means lit = 0xffffffff, or -1 */
4153 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4154 rFalseIfx.condition ^= 1;
4155 genSkipCond(&rFalseIfx,right,size,7);
4156 if(ifx) ifx->generated = 1;
4163 if(rFalseIfx.condition) {
4164 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4165 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4168 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4170 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4174 if(rFalseIfx.condition) {
4175 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4176 pic16_emitpLabel(truelbl->key);
4178 rFalseIfx.condition ^= 1;
4179 genSkipCond(&rFalseIfx,right,s,7);
4182 if(ifx) ifx->generated = 1;
4186 if((size == 1) && (0 == (lp1&0xff))) {
4187 /* lower byte of signed word is zero */
4188 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4189 i = ((lp1 >> 8) & 0xff) ^0x80;
4190 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4191 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4192 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4193 rFalseIfx.condition ^= 1;
4194 genSkipc(&rFalseIfx);
4197 if(ifx) ifx->generated = 1;
4201 if(lit & (0x80 << (size*8))) {
4202 /* Lit is less than zero */
4203 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4204 //rFalseIfx.condition ^= 1;
4205 //genSkipCond(&rFalseIfx,left,size,7);
4206 //rFalseIfx.condition ^= 1;
4207 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4208 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4210 if(rFalseIfx.condition)
4211 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4213 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4217 /* Lit is greater than or equal to zero */
4218 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4219 //rFalseIfx.condition ^= 1;
4220 //genSkipCond(&rFalseIfx,right,size,7);
4221 //rFalseIfx.condition ^= 1;
4223 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4224 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4226 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4227 if(rFalseIfx.condition)
4228 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4230 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4235 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4236 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4240 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4242 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4244 rFalseIfx.condition ^= 1;
4245 //rFalseIfx.condition = 1;
4246 genSkipc(&rFalseIfx);
4248 pic16_emitpLabel(truelbl->key);
4250 if(ifx) ifx->generated = 1;
4255 /* compare word or long to an unsigned literal on the right.*/
4260 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4263 break; /* handled above */
4266 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4268 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4269 genSkipz2(&rFalseIfx,0);
4273 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4275 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4278 if(rFalseIfx.condition)
4279 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4281 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4284 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4285 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4287 rFalseIfx.condition ^= 1;
4288 genSkipc(&rFalseIfx);
4291 pic16_emitpLabel(truelbl->key);
4293 if(ifx) ifx->generated = 1;
4299 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4300 i = (lit >> (size*8)) & 0xff;
4302 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4303 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4306 i = (lit >> (size*8)) & 0xff;
4309 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4311 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4313 /* this byte of the lit is zero,
4314 *if it's not the last then OR in the variable */
4316 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4321 pic16_emitpLabel(lbl->key);
4323 rFalseIfx.condition ^= 1;
4324 genSkipc(&rFalseIfx);
4328 pic16_emitpLabel(truelbl->key);
4329 if(ifx) ifx->generated = 1;
4333 /* Compare two variables */
4335 DEBUGpic16_emitcode(";sign","%d",sign);
4339 /* Sigh. thus sucks... */
4341 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4342 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4343 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4344 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4345 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4346 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4348 /* Signed char comparison */
4349 /* Special thanks to Nikolai Golovchenko for this snippet */
4350 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4351 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4352 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4353 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4354 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4355 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4357 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4358 genSkipc(&rFalseIfx);
4360 if(ifx) ifx->generated = 1;
4366 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4367 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4371 /* The rest of the bytes of a multi-byte compare */
4375 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4378 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4379 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4384 pic16_emitpLabel(lbl->key);
4386 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4387 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4388 (AOP_TYPE(result) == AOP_REG)) {
4389 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4390 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4392 genSkipc(&rFalseIfx);
4394 //genSkipc(&rFalseIfx);
4395 if(ifx) ifx->generated = 1;
4402 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4403 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4404 pic16_outBitC(result);
4406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4407 /* if the result is used in the next
4408 ifx conditional branch then generate
4409 code a little differently */
4411 genIfxJump (ifx,"c");
4413 pic16_outBitC(result);
4414 /* leave the result in acc */
4419 /*-----------------------------------------------------------------*/
4420 /* genCmpGt :- greater than comparison */
4421 /*-----------------------------------------------------------------*/
4422 static void genCmpGt (iCode *ic, iCode *ifx)
4424 operand *left, *right, *result;
4425 sym_link *letype , *retype;
4428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4430 right= IC_RIGHT(ic);
4431 result = IC_RESULT(ic);
4433 letype = getSpec(operandType(left));
4434 retype =getSpec(operandType(right));
4435 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4436 /* assign the amsops */
4437 pic16_aopOp (left,ic,FALSE);
4438 pic16_aopOp (right,ic,FALSE);
4439 pic16_aopOp (result,ic,TRUE);
4441 genCmp(right, left, result, ifx, sign);
4443 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4444 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4445 pic16_freeAsmop(result,NULL,ic,TRUE);
4448 /*-----------------------------------------------------------------*/
4449 /* genCmpLt - less than comparisons */
4450 /*-----------------------------------------------------------------*/
4451 static void genCmpLt (iCode *ic, iCode *ifx)
4453 operand *left, *right, *result;
4454 sym_link *letype , *retype;
4457 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4459 right= IC_RIGHT(ic);
4460 result = IC_RESULT(ic);
4462 letype = getSpec(operandType(left));
4463 retype =getSpec(operandType(right));
4464 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4466 /* assign the amsops */
4467 pic16_aopOp (left,ic,FALSE);
4468 pic16_aopOp (right,ic,FALSE);
4469 pic16_aopOp (result,ic,TRUE);
4471 genCmp(left, right, result, ifx, sign);
4473 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4474 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4475 pic16_freeAsmop(result,NULL,ic,TRUE);
4478 /*-----------------------------------------------------------------*/
4479 /* genc16bit2lit - compare a 16 bit value to a literal */
4480 /*-----------------------------------------------------------------*/
4481 static void genc16bit2lit(operand *op, int lit, int offset)
4485 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4486 if( (lit&0xff) == 0)
4491 switch( BYTEofLONG(lit,i)) {
4493 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4496 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4499 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4502 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4503 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4508 switch( BYTEofLONG(lit,i)) {
4510 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4514 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4518 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4521 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4523 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4529 /*-----------------------------------------------------------------*/
4530 /* gencjneshort - compare and jump if not equal */
4531 /*-----------------------------------------------------------------*/
4532 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4534 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4536 int res_offset = 0; /* the result may be a different size then left or right */
4537 int res_size = AOP_SIZE(result);
4541 unsigned long lit = 0L;
4542 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4543 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4545 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4546 resolveIfx(&rIfx,ifx);
4547 lbl = newiTempLabel(NULL);
4550 /* if the left side is a literal or
4551 if the right is in a pointer register and left
4553 if ((AOP_TYPE(left) == AOP_LIT) ||
4554 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4559 if(AOP_TYPE(right) == AOP_LIT)
4560 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4562 /* if the right side is a literal then anything goes */
4563 if (AOP_TYPE(right) == AOP_LIT &&
4564 AOP_TYPE(left) != AOP_DIR ) {
4567 genc16bit2lit(left, lit, 0);
4569 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4574 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4575 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4577 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4581 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4583 if(res_offset < res_size-1)
4591 /* if the right side is in a register or in direct space or
4592 if the left is a pointer register & right is not */
4593 else if (AOP_TYPE(right) == AOP_REG ||
4594 AOP_TYPE(right) == AOP_DIR ||
4595 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4596 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4597 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4598 int lbl_key = lbl->key;
4601 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4602 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4604 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4605 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4606 __FUNCTION__,__LINE__);
4610 /* switch(size) { */
4612 /* genc16bit2lit(left, lit, 0); */
4614 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4619 if((AOP_TYPE(left) == AOP_DIR) &&
4620 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4622 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4623 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4625 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4627 switch (lit & 0xff) {
4629 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4632 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4633 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4634 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4638 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4639 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4640 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4641 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4645 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4646 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4651 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4654 if(AOP_TYPE(result) == AOP_CRY) {
4655 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4660 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4662 /* fix me. probably need to check result size too */
4663 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4668 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4669 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4676 if(res_offset < res_size-1)
4681 } else if(AOP_TYPE(right) == AOP_REG &&
4682 AOP_TYPE(left) != AOP_DIR){
4685 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4686 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4687 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4692 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4694 if(res_offset < res_size-1)
4699 /* right is a pointer reg need both a & b */
4701 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4703 pic16_emitcode("mov","b,%s",l);
4704 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4705 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4710 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4712 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4714 pic16_emitpLabel(lbl->key);
4716 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4723 /*-----------------------------------------------------------------*/
4724 /* gencjne - compare and jump if not equal */
4725 /*-----------------------------------------------------------------*/
4726 static void gencjne(operand *left, operand *right, iCode *ifx)
4728 symbol *tlbl = newiTempLabel(NULL);
4730 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4731 gencjneshort(left, right, lbl);
4733 pic16_emitcode("mov","a,%s",one);
4734 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4735 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4736 pic16_emitcode("clr","a");
4737 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4739 pic16_emitpLabel(lbl->key);
4740 pic16_emitpLabel(tlbl->key);
4745 /*-----------------------------------------------------------------*/
4746 /* genCmpEq - generates code for equal to */
4747 /*-----------------------------------------------------------------*/
4748 static void genCmpEq (iCode *ic, iCode *ifx)
4750 operand *left, *right, *result;
4751 unsigned long lit = 0L;
4754 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4757 DEBUGpic16_emitcode ("; ifx is non-null","");
4759 DEBUGpic16_emitcode ("; ifx is null","");
4761 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4762 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4763 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4765 size = max(AOP_SIZE(left),AOP_SIZE(right));
4767 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4769 /* if literal, literal on the right or
4770 if the right is in a pointer register and left
4772 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4773 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4774 operand *tmp = right ;
4780 if(ifx && !AOP_SIZE(result)){
4782 /* if they are both bit variables */
4783 if (AOP_TYPE(left) == AOP_CRY &&
4784 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4785 if(AOP_TYPE(right) == AOP_LIT){
4786 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4788 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4789 pic16_emitcode("cpl","c");
4790 } else if(lit == 1L) {
4791 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4793 pic16_emitcode("clr","c");
4795 /* AOP_TYPE(right) == AOP_CRY */
4797 symbol *lbl = newiTempLabel(NULL);
4798 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4799 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4800 pic16_emitcode("cpl","c");
4801 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4803 /* if true label then we jump if condition
4805 tlbl = newiTempLabel(NULL);
4806 if ( IC_TRUE(ifx) ) {
4807 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4808 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4810 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4811 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4813 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4816 /* left and right are both bit variables, result is carry */
4819 resolveIfx(&rIfx,ifx);
4821 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4822 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4823 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4824 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4829 /* They're not both bit variables. Is the right a literal? */
4830 if(AOP_TYPE(right) == AOP_LIT) {
4831 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4836 switch(lit & 0xff) {
4838 if ( IC_TRUE(ifx) ) {
4839 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4841 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4843 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4844 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4848 if ( IC_TRUE(ifx) ) {
4849 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4851 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4853 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4854 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4858 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4860 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4865 /* end of size == 1 */
4869 genc16bit2lit(left,lit,offset);
4872 /* end of size == 2 */
4877 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4878 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4879 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4880 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4884 /* search for patterns that can be optimized */
4886 genc16bit2lit(left,lit,0);
4889 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4891 genc16bit2lit(left,lit,2);
4893 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4894 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4907 } else if(AOP_TYPE(right) == AOP_CRY ) {
4908 /* we know the left is not a bit, but that the right is */
4909 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4910 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4911 pic16_popGet(AOP(right),offset));
4912 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4914 /* if the two are equal, then W will be 0 and the Z bit is set
4915 * we could test Z now, or go ahead and check the high order bytes if
4916 * the variable we're comparing is larger than a byte. */
4919 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4921 if ( IC_TRUE(ifx) ) {
4923 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4924 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4927 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4928 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4932 /* They're both variables that are larger than bits */
4935 tlbl = newiTempLabel(NULL);
4938 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4939 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4941 if ( IC_TRUE(ifx) ) {
4944 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4945 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4948 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4949 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4953 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4954 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4958 if(s>1 && IC_TRUE(ifx)) {
4959 pic16_emitpLabel(tlbl->key);
4960 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4964 /* mark the icode as generated */
4969 /* if they are both bit variables */
4970 if (AOP_TYPE(left) == AOP_CRY &&
4971 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4972 if(AOP_TYPE(right) == AOP_LIT){
4973 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4975 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4976 pic16_emitcode("cpl","c");
4977 } else if(lit == 1L) {
4978 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4980 pic16_emitcode("clr","c");
4982 /* AOP_TYPE(right) == AOP_CRY */
4984 symbol *lbl = newiTempLabel(NULL);
4985 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4986 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4987 pic16_emitcode("cpl","c");
4988 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4991 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4992 pic16_outBitC(result);
4996 genIfxJump (ifx,"c");
4999 /* if the result is used in an arithmetic operation
5000 then put the result in place */
5001 pic16_outBitC(result);
5004 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5005 gencjne(left,right,result,ifx);
5008 gencjne(left,right,newiTempLabel(NULL));
5010 if(IC_TRUE(ifx)->key)
5011 gencjne(left,right,IC_TRUE(ifx)->key);
5013 gencjne(left,right,IC_FALSE(ifx)->key);
5017 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5018 pic16_aopPut(AOP(result),"a",0);
5023 genIfxJump (ifx,"a");
5027 /* if the result is used in an arithmetic operation
5028 then put the result in place */
5030 if (AOP_TYPE(result) != AOP_CRY)
5031 pic16_outAcc(result);
5033 /* leave the result in acc */
5037 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5038 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5039 pic16_freeAsmop(result,NULL,ic,TRUE);
5042 /*-----------------------------------------------------------------*/
5043 /* ifxForOp - returns the icode containing the ifx for operand */
5044 /*-----------------------------------------------------------------*/
5045 static iCode *ifxForOp ( operand *op, iCode *ic )
5047 /* if true symbol then needs to be assigned */
5048 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5049 if (IS_TRUE_SYMOP(op))
5052 /* if this has register type condition and
5053 the next instruction is ifx with the same operand
5054 and live to of the operand is upto the ifx only then */
5056 ic->next->op == IFX &&
5057 IC_COND(ic->next)->key == op->key &&
5058 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5062 ic->next->op == IFX &&
5063 IC_COND(ic->next)->key == op->key) {
5064 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5068 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5070 ic->next->op == IFX)
5071 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5074 ic->next->op == IFX &&
5075 IC_COND(ic->next)->key == op->key) {
5076 DEBUGpic16_emitcode ("; "," key is okay");
5077 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5078 OP_SYMBOL(op)->liveTo,
5085 /*-----------------------------------------------------------------*/
5086 /* genAndOp - for && operation */
5087 /*-----------------------------------------------------------------*/
5088 static void genAndOp (iCode *ic)
5090 operand *left,*right, *result;
5093 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5094 /* note here that && operations that are in an
5095 if statement are taken away by backPatchLabels
5096 only those used in arthmetic operations remain */
5097 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5098 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5099 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5101 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5103 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5104 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5105 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5107 /* if both are bit variables */
5108 /* if (AOP_TYPE(left) == AOP_CRY && */
5109 /* AOP_TYPE(right) == AOP_CRY ) { */
5110 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5111 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5112 /* pic16_outBitC(result); */
5114 /* tlbl = newiTempLabel(NULL); */
5115 /* pic16_toBoolean(left); */
5116 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5117 /* pic16_toBoolean(right); */
5118 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5119 /* pic16_outBitAcc(result); */
5122 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5123 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5124 pic16_freeAsmop(result,NULL,ic,TRUE);
5128 /*-----------------------------------------------------------------*/
5129 /* genOrOp - for || operation */
5130 /*-----------------------------------------------------------------*/
5133 modified this code, but it doesn't appear to ever get called
5136 static void genOrOp (iCode *ic)
5138 operand *left,*right, *result;
5141 /* note here that || operations that are in an
5142 if statement are taken away by backPatchLabels
5143 only those used in arthmetic operations remain */
5144 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5145 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5146 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5147 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5149 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5151 /* if both are bit variables */
5152 if (AOP_TYPE(left) == AOP_CRY &&
5153 AOP_TYPE(right) == AOP_CRY ) {
5154 pic16_emitcode("clrc","");
5155 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5156 AOP(left)->aopu.aop_dir,
5157 AOP(left)->aopu.aop_dir);
5158 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5159 AOP(right)->aopu.aop_dir,
5160 AOP(right)->aopu.aop_dir);
5161 pic16_emitcode("setc","");
5164 tlbl = newiTempLabel(NULL);
5165 pic16_toBoolean(left);
5167 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5168 pic16_toBoolean(right);
5169 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5171 pic16_outBitAcc(result);
5174 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5175 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5176 pic16_freeAsmop(result,NULL,ic,TRUE);
5179 /*-----------------------------------------------------------------*/
5180 /* isLiteralBit - test if lit == 2^n */
5181 /*-----------------------------------------------------------------*/
5182 static int isLiteralBit(unsigned long lit)
5184 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5185 0x100L,0x200L,0x400L,0x800L,
5186 0x1000L,0x2000L,0x4000L,0x8000L,
5187 0x10000L,0x20000L,0x40000L,0x80000L,
5188 0x100000L,0x200000L,0x400000L,0x800000L,
5189 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5190 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5193 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5194 for(idx = 0; idx < 32; idx++)
5200 /*-----------------------------------------------------------------*/
5201 /* continueIfTrue - */
5202 /*-----------------------------------------------------------------*/
5203 static void continueIfTrue (iCode *ic)
5205 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5207 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5211 /*-----------------------------------------------------------------*/
5213 /*-----------------------------------------------------------------*/
5214 static void jumpIfTrue (iCode *ic)
5216 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5218 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5222 /*-----------------------------------------------------------------*/
5223 /* jmpTrueOrFalse - */
5224 /*-----------------------------------------------------------------*/
5225 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5227 // ugly but optimized by peephole
5228 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5230 symbol *nlbl = newiTempLabel(NULL);
5231 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5232 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5233 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5234 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5237 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5238 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5243 /*-----------------------------------------------------------------*/
5244 /* genAnd - code for and */
5245 /*-----------------------------------------------------------------*/
5246 static void genAnd (iCode *ic, iCode *ifx)
5248 operand *left, *right, *result;
5250 unsigned long lit = 0L;
5255 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5256 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5257 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5258 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5260 resolveIfx(&rIfx,ifx);
5262 /* if left is a literal & right is not then exchange them */
5263 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5264 AOP_NEEDSACC(left)) {
5265 operand *tmp = right ;
5270 /* if result = right then exchange them */
5271 if(pic16_sameRegs(AOP(result),AOP(right))){
5272 operand *tmp = right ;
5277 /* if right is bit then exchange them */
5278 if (AOP_TYPE(right) == AOP_CRY &&
5279 AOP_TYPE(left) != AOP_CRY){
5280 operand *tmp = right ;
5284 if(AOP_TYPE(right) == AOP_LIT)
5285 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5287 size = AOP_SIZE(result);
5289 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5292 // result = bit & yy;
5293 if (AOP_TYPE(left) == AOP_CRY){
5294 // c = bit & literal;
5295 if(AOP_TYPE(right) == AOP_LIT){
5297 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5300 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5303 if(size && (AOP_TYPE(result) == AOP_CRY)){
5304 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5307 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5311 pic16_emitcode("clr","c");
5314 if (AOP_TYPE(right) == AOP_CRY){
5316 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5317 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5320 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5322 pic16_emitcode("rrc","a");
5323 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5329 pic16_outBitC(result);
5331 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5332 genIfxJump(ifx, "c");
5336 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5337 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5338 if((AOP_TYPE(right) == AOP_LIT) &&
5339 (AOP_TYPE(result) == AOP_CRY) &&
5340 (AOP_TYPE(left) != AOP_CRY)){
5341 int posbit = isLiteralBit(lit);
5345 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5348 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5354 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5355 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5357 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5358 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5361 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5362 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5363 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5370 symbol *tlbl = newiTempLabel(NULL);
5371 int sizel = AOP_SIZE(left);
5373 pic16_emitcode("setb","c");
5375 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5376 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5378 if((posbit = isLiteralBit(bytelit)) != 0)
5379 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5381 if(bytelit != 0x0FFL)
5382 pic16_emitcode("anl","a,%s",
5383 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5384 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5389 // bit = left & literal
5391 pic16_emitcode("clr","c");
5392 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5394 // if(left & literal)
5397 jmpTrueOrFalse(ifx, tlbl);
5401 pic16_outBitC(result);
5405 /* if left is same as result */
5406 if(pic16_sameRegs(AOP(result),AOP(left))){
5408 for(;size--; offset++,lit>>=8) {
5409 if(AOP_TYPE(right) == AOP_LIT){
5410 switch(lit & 0xff) {
5412 /* and'ing with 0 has clears the result */
5413 pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5414 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5417 /* and'ing with 0xff is a nop when the result and left are the same */
5422 int p = my_powof2( (~lit) & 0xff );
5424 /* only one bit is set in the literal, so use a bcf instruction */
5425 pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5426 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5429 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5430 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5431 if(know_W != (lit&0xff))
5432 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5434 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5439 if (AOP_TYPE(left) == AOP_ACC) {
5440 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5442 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5443 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5450 // left & result in different registers
5451 if(AOP_TYPE(result) == AOP_CRY){
5453 // if(size), result in bit
5454 // if(!size && ifx), conditional oper: if(left & right)
5455 symbol *tlbl = newiTempLabel(NULL);
5456 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5458 pic16_emitcode("setb","c");
5460 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5461 pic16_emitcode("anl","a,%s",
5462 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5463 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5468 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5469 pic16_outBitC(result);
5471 jmpTrueOrFalse(ifx, tlbl);
5473 for(;(size--);offset++) {
5475 // result = left & right
5476 if(AOP_TYPE(right) == AOP_LIT){
5477 int t = (lit >> (offset*8)) & 0x0FFL;
5480 pic16_emitcode("clrf","%s",
5481 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5482 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5485 pic16_emitcode("movf","%s,w",
5486 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5487 pic16_emitcode("movwf","%s",
5488 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5489 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5490 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5493 pic16_emitcode("movlw","0x%x",t);
5494 pic16_emitcode("andwf","%s,w",
5495 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5496 pic16_emitcode("movwf","%s",
5497 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5499 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5500 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5501 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5506 if (AOP_TYPE(left) == AOP_ACC) {
5507 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5508 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5510 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5511 pic16_emitcode("andwf","%s,w",
5512 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5513 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5514 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5516 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5517 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5523 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5524 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5525 pic16_freeAsmop(result,NULL,ic,TRUE);
5528 /*-----------------------------------------------------------------*/
5529 /* genOr - code for or */
5530 /*-----------------------------------------------------------------*/
5531 static void genOr (iCode *ic, iCode *ifx)
5533 operand *left, *right, *result;
5535 unsigned long lit = 0L;
5537 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5539 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5540 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5541 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5543 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5545 /* if left is a literal & right is not then exchange them */
5546 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5547 AOP_NEEDSACC(left)) {
5548 operand *tmp = right ;
5553 /* if result = right then exchange them */
5554 if(pic16_sameRegs(AOP(result),AOP(right))){
5555 operand *tmp = right ;
5560 /* if right is bit then exchange them */
5561 if (AOP_TYPE(right) == AOP_CRY &&
5562 AOP_TYPE(left) != AOP_CRY){
5563 operand *tmp = right ;
5568 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5570 if(AOP_TYPE(right) == AOP_LIT)
5571 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5573 size = AOP_SIZE(result);
5577 if (AOP_TYPE(left) == AOP_CRY){
5578 if(AOP_TYPE(right) == AOP_LIT){
5579 // c = bit & literal;
5581 // lit != 0 => result = 1
5582 if(AOP_TYPE(result) == AOP_CRY){
5584 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5585 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5586 // AOP(result)->aopu.aop_dir,
5587 // AOP(result)->aopu.aop_dir);
5589 continueIfTrue(ifx);
5593 // lit == 0 => result = left
5594 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5596 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5599 if (AOP_TYPE(right) == AOP_CRY){
5600 if(pic16_sameRegs(AOP(result),AOP(left))){
5602 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5603 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5604 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5606 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5607 AOP(result)->aopu.aop_dir,
5608 AOP(result)->aopu.aop_dir);
5609 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5610 AOP(right)->aopu.aop_dir,
5611 AOP(right)->aopu.aop_dir);
5612 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5613 AOP(result)->aopu.aop_dir,
5614 AOP(result)->aopu.aop_dir);
5616 if( AOP_TYPE(result) == AOP_ACC) {
5617 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5618 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5619 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5620 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5624 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5625 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5626 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5627 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5629 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5630 AOP(result)->aopu.aop_dir,
5631 AOP(result)->aopu.aop_dir);
5632 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5633 AOP(right)->aopu.aop_dir,
5634 AOP(right)->aopu.aop_dir);
5635 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5636 AOP(left)->aopu.aop_dir,
5637 AOP(left)->aopu.aop_dir);
5638 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5639 AOP(result)->aopu.aop_dir,
5640 AOP(result)->aopu.aop_dir);
5645 symbol *tlbl = newiTempLabel(NULL);
5646 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5649 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5650 if( AOP_TYPE(right) == AOP_ACC) {
5651 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5653 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5654 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5659 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5660 pic16_emitcode(";XXX setb","c");
5661 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5662 AOP(left)->aopu.aop_dir,tlbl->key+100);
5663 pic16_toBoolean(right);
5664 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5665 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5666 jmpTrueOrFalse(ifx, tlbl);
5670 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5677 pic16_outBitC(result);
5679 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5680 genIfxJump(ifx, "c");
5684 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5685 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5686 if((AOP_TYPE(right) == AOP_LIT) &&
5687 (AOP_TYPE(result) == AOP_CRY) &&
5688 (AOP_TYPE(left) != AOP_CRY)){
5690 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5693 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5695 continueIfTrue(ifx);
5698 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5699 // lit = 0, result = boolean(left)
5701 pic16_emitcode(";XXX setb","c");
5702 pic16_toBoolean(right);
5704 symbol *tlbl = newiTempLabel(NULL);
5705 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5707 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5709 genIfxJump (ifx,"a");
5713 pic16_outBitC(result);
5717 /* if left is same as result */
5718 if(pic16_sameRegs(AOP(result),AOP(left))){
5720 for(;size--; offset++,lit>>=8) {
5721 if(AOP_TYPE(right) == AOP_LIT){
5722 if((lit & 0xff) == 0)
5723 /* or'ing with 0 has no effect */
5726 int p = my_powof2(lit & 0xff);
5728 /* only one bit is set in the literal, so use a bsf instruction */
5729 pic16_emitpcode(POC_BSF,
5730 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5732 if(know_W != (lit & 0xff))
5733 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5734 know_W = lit & 0xff;
5735 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5740 if (AOP_TYPE(left) == AOP_ACC) {
5741 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5742 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5744 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5745 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5747 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5748 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5754 // left & result in different registers
5755 if(AOP_TYPE(result) == AOP_CRY){
5757 // if(size), result in bit
5758 // if(!size && ifx), conditional oper: if(left | right)
5759 symbol *tlbl = newiTempLabel(NULL);
5760 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5761 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5765 pic16_emitcode(";XXX setb","c");
5767 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5768 pic16_emitcode(";XXX orl","a,%s",
5769 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5770 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5775 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5776 pic16_outBitC(result);
5778 jmpTrueOrFalse(ifx, tlbl);
5779 } else for(;(size--);offset++){
5781 // result = left & right
5782 if(AOP_TYPE(right) == AOP_LIT){
5783 int t = (lit >> (offset*8)) & 0x0FFL;
5786 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5787 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5789 pic16_emitcode("movf","%s,w",
5790 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5791 pic16_emitcode("movwf","%s",
5792 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5795 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5796 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5797 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5799 pic16_emitcode("movlw","0x%x",t);
5800 pic16_emitcode("iorwf","%s,w",
5801 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5802 pic16_emitcode("movwf","%s",
5803 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5809 // faster than result <- left, anl result,right
5810 // and better if result is SFR
5811 if (AOP_TYPE(left) == AOP_ACC) {
5812 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5813 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5815 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5816 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5818 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5819 pic16_emitcode("iorwf","%s,w",
5820 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5822 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5823 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5828 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5829 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5830 pic16_freeAsmop(result,NULL,ic,TRUE);
5833 /*-----------------------------------------------------------------*/
5834 /* genXor - code for xclusive or */
5835 /*-----------------------------------------------------------------*/
5836 static void genXor (iCode *ic, iCode *ifx)
5838 operand *left, *right, *result;
5840 unsigned long lit = 0L;
5842 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5844 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5845 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5846 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5848 /* if left is a literal & right is not ||
5849 if left needs acc & right does not */
5850 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5851 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5852 operand *tmp = right ;
5857 /* if result = right then exchange them */
5858 if(pic16_sameRegs(AOP(result),AOP(right))){
5859 operand *tmp = right ;
5864 /* if right is bit then exchange them */
5865 if (AOP_TYPE(right) == AOP_CRY &&
5866 AOP_TYPE(left) != AOP_CRY){
5867 operand *tmp = right ;
5871 if(AOP_TYPE(right) == AOP_LIT)
5872 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5874 size = AOP_SIZE(result);
5878 if (AOP_TYPE(left) == AOP_CRY){
5879 if(AOP_TYPE(right) == AOP_LIT){
5880 // c = bit & literal;
5882 // lit>>1 != 0 => result = 1
5883 if(AOP_TYPE(result) == AOP_CRY){
5885 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
5886 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5888 continueIfTrue(ifx);
5891 pic16_emitcode("setb","c");
5895 // lit == 0, result = left
5896 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5898 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5900 // lit == 1, result = not(left)
5901 if(size && pic16_sameRegs(AOP(result),AOP(left))){
5902 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
5903 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
5904 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5907 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5908 pic16_emitcode("cpl","c");
5915 symbol *tlbl = newiTempLabel(NULL);
5916 if (AOP_TYPE(right) == AOP_CRY){
5918 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5921 int sizer = AOP_SIZE(right);
5923 // if val>>1 != 0, result = 1
5924 pic16_emitcode("setb","c");
5926 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5928 // test the msb of the lsb
5929 pic16_emitcode("anl","a,#0xfe");
5930 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5934 pic16_emitcode("rrc","a");
5936 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5937 pic16_emitcode("cpl","c");
5938 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5943 pic16_outBitC(result);
5945 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5946 genIfxJump(ifx, "c");
5950 if(pic16_sameRegs(AOP(result),AOP(left))){
5951 /* if left is same as result */
5952 for(;size--; offset++) {
5953 if(AOP_TYPE(right) == AOP_LIT){
5954 int t = (lit >> (offset*8)) & 0x0FFL;
5958 if (IS_AOP_PREG(left)) {
5959 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5960 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5961 pic16_aopPut(AOP(result),"a",offset);
5963 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5964 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5965 pic16_emitcode("xrl","%s,%s",
5966 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5967 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5970 if (AOP_TYPE(left) == AOP_ACC)
5971 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5973 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5974 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5976 if (IS_AOP_PREG(left)) {
5977 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5978 pic16_aopPut(AOP(result),"a",offset);
5980 pic16_emitcode("xrl","%s,a",
5981 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5987 // left & result in different registers
5988 if(AOP_TYPE(result) == AOP_CRY){
5990 // if(size), result in bit
5991 // if(!size && ifx), conditional oper: if(left ^ right)
5992 symbol *tlbl = newiTempLabel(NULL);
5993 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5995 pic16_emitcode("setb","c");
5997 if((AOP_TYPE(right) == AOP_LIT) &&
5998 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5999 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6001 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6002 pic16_emitcode("xrl","a,%s",
6003 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6005 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6010 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6011 pic16_outBitC(result);
6013 jmpTrueOrFalse(ifx, tlbl);
6014 } else for(;(size--);offset++){
6016 // result = left & right
6017 if(AOP_TYPE(right) == AOP_LIT){
6018 int t = (lit >> (offset*8)) & 0x0FFL;
6021 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6022 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6023 pic16_emitcode("movf","%s,w",
6024 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6025 pic16_emitcode("movwf","%s",
6026 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6029 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6030 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6031 pic16_emitcode("comf","%s,w",
6032 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6033 pic16_emitcode("movwf","%s",
6034 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6037 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6038 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6039 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6040 pic16_emitcode("movlw","0x%x",t);
6041 pic16_emitcode("xorwf","%s,w",
6042 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6043 pic16_emitcode("movwf","%s",
6044 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6050 // faster than result <- left, anl result,right
6051 // and better if result is SFR
6052 if (AOP_TYPE(left) == AOP_ACC) {
6053 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6054 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6056 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6057 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6058 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6059 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6061 if ( AOP_TYPE(result) != AOP_ACC){
6062 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6063 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6069 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6070 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6071 pic16_freeAsmop(result,NULL,ic,TRUE);
6074 /*-----------------------------------------------------------------*/
6075 /* genInline - write the inline code out */
6076 /*-----------------------------------------------------------------*/
6077 static void genInline (iCode *ic)
6079 char *buffer, *bp, *bp1;
6081 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6083 _G.inLine += (!options.asmpeep);
6085 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6086 strcpy(buffer,IC_INLINE(ic));
6088 /* emit each line as a code */
6094 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6101 pic16_emitcode(bp1,"");
6107 if ((bp1 != bp) && *bp1)
6108 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6112 _G.inLine -= (!options.asmpeep);
6115 /*-----------------------------------------------------------------*/
6116 /* genRRC - rotate right with carry */
6117 /*-----------------------------------------------------------------*/
6118 static void genRRC (iCode *ic)
6120 operand *left , *result ;
6121 int size, offset = 0, same;
6123 /* rotate right with carry */
6125 result=IC_RESULT(ic);
6126 pic16_aopOp (left,ic,FALSE);
6127 pic16_aopOp (result,ic,FALSE);
6129 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6131 same = pic16_sameRegs(AOP(result),AOP(left));
6133 size = AOP_SIZE(result);
6135 /* get the lsb and put it into the carry */
6136 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6143 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6145 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6146 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6152 pic16_freeAsmop(left,NULL,ic,TRUE);
6153 pic16_freeAsmop(result,NULL,ic,TRUE);
6156 /*-----------------------------------------------------------------*/
6157 /* genRLC - generate code for rotate left with carry */
6158 /*-----------------------------------------------------------------*/
6159 static void genRLC (iCode *ic)
6161 operand *left , *result ;
6162 int size, offset = 0;
6165 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6166 /* rotate right with carry */
6168 result=IC_RESULT(ic);
6169 pic16_aopOp (left,ic,FALSE);
6170 pic16_aopOp (result,ic,FALSE);
6172 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6174 same = pic16_sameRegs(AOP(result),AOP(left));
6176 /* move it to the result */
6177 size = AOP_SIZE(result);
6179 /* get the msb and put it into the carry */
6180 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6187 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6189 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6190 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6197 pic16_freeAsmop(left,NULL,ic,TRUE);
6198 pic16_freeAsmop(result,NULL,ic,TRUE);
6201 /*-----------------------------------------------------------------*/
6202 /* genGetHbit - generates code get highest order bit */
6203 /*-----------------------------------------------------------------*/
6204 static void genGetHbit (iCode *ic)
6206 operand *left, *result;
6208 result=IC_RESULT(ic);
6209 pic16_aopOp (left,ic,FALSE);
6210 pic16_aopOp (result,ic,FALSE);
6212 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6213 /* get the highest order byte into a */
6214 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6215 if(AOP_TYPE(result) == AOP_CRY){
6216 pic16_emitcode("rlc","a");
6217 pic16_outBitC(result);
6220 pic16_emitcode("rl","a");
6221 pic16_emitcode("anl","a,#0x01");
6222 pic16_outAcc(result);
6226 pic16_freeAsmop(left,NULL,ic,TRUE);
6227 pic16_freeAsmop(result,NULL,ic,TRUE);
6230 /*-----------------------------------------------------------------*/
6231 /* AccRol - rotate left accumulator by known count */
6232 /*-----------------------------------------------------------------*/
6233 static void AccRol (int shCount)
6235 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6236 shCount &= 0x0007; // shCount : 0..7
6241 pic16_emitcode("rl","a");
6244 pic16_emitcode("rl","a");
6245 pic16_emitcode("rl","a");
6248 pic16_emitcode("swap","a");
6249 pic16_emitcode("rr","a");
6252 pic16_emitcode("swap","a");
6255 pic16_emitcode("swap","a");
6256 pic16_emitcode("rl","a");
6259 pic16_emitcode("rr","a");
6260 pic16_emitcode("rr","a");
6263 pic16_emitcode("rr","a");
6268 /*-----------------------------------------------------------------*/
6269 /* AccLsh - left shift accumulator by known count */
6270 /*-----------------------------------------------------------------*/
6271 static void AccLsh (int shCount)
6273 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6276 pic16_emitcode("add","a,acc");
6279 pic16_emitcode("add","a,acc");
6280 pic16_emitcode("add","a,acc");
6282 /* rotate left accumulator */
6284 /* and kill the lower order bits */
6285 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6290 /*-----------------------------------------------------------------*/
6291 /* AccRsh - right shift accumulator by known count */
6292 /*-----------------------------------------------------------------*/
6293 static void AccRsh (int shCount)
6295 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6299 pic16_emitcode("rrc","a");
6301 /* rotate right accumulator */
6302 AccRol(8 - shCount);
6303 /* and kill the higher order bits */
6304 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6310 /*-----------------------------------------------------------------*/
6311 /* AccSRsh - signed right shift accumulator by known count */
6312 /*-----------------------------------------------------------------*/
6313 static void AccSRsh (int shCount)
6316 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6319 pic16_emitcode("mov","c,acc.7");
6320 pic16_emitcode("rrc","a");
6321 } else if(shCount == 2){
6322 pic16_emitcode("mov","c,acc.7");
6323 pic16_emitcode("rrc","a");
6324 pic16_emitcode("mov","c,acc.7");
6325 pic16_emitcode("rrc","a");
6327 tlbl = newiTempLabel(NULL);
6328 /* rotate right accumulator */
6329 AccRol(8 - shCount);
6330 /* and kill the higher order bits */
6331 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6332 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6333 pic16_emitcode("orl","a,#0x%02x",
6334 (unsigned char)~SRMask[shCount]);
6335 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6340 /*-----------------------------------------------------------------*/
6341 /* shiftR1Left2Result - shift right one byte from left to result */
6342 /*-----------------------------------------------------------------*/
6343 static void shiftR1Left2ResultSigned (operand *left, int offl,
6344 operand *result, int offr,
6349 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6351 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6355 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6357 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6359 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6360 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6366 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6368 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6370 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6371 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6373 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6374 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6380 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6382 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6383 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6386 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6387 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6388 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6390 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6391 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6393 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6397 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6398 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6399 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6400 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6401 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6405 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6407 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6408 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6410 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6411 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6412 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6413 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6414 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6419 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6420 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6421 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6422 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6423 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6424 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6426 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6427 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6428 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6429 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6430 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6436 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6437 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6438 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6439 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6441 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6442 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6443 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6451 /*-----------------------------------------------------------------*/
6452 /* shiftR1Left2Result - shift right one byte from left to result */
6453 /*-----------------------------------------------------------------*/
6454 static void shiftR1Left2Result (operand *left, int offl,
6455 operand *result, int offr,
6456 int shCount, int sign)
6460 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6462 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6464 /* Copy the msb into the carry if signed. */
6466 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6476 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6478 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6479 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6485 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6487 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6488 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6491 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6496 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6498 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6499 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6502 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6503 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6504 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6505 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6509 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6510 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6511 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6515 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6516 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6517 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6519 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6524 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6525 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6526 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6527 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6528 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6533 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6534 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6535 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6544 /*-----------------------------------------------------------------*/
6545 /* shiftL1Left2Result - shift left one byte from left to result */
6546 /*-----------------------------------------------------------------*/
6547 static void shiftL1Left2Result (operand *left, int offl,
6548 operand *result, int offr, int shCount)
6553 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6555 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6556 DEBUGpic16_emitcode ("; ***","same = %d",same);
6557 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6559 /* shift left accumulator */
6560 //AccLsh(shCount); // don't comment out just yet...
6561 // pic16_aopPut(AOP(result),"a",offr);
6565 /* Shift left 1 bit position */
6566 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6568 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6570 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6571 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6575 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6576 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6577 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6578 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6581 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6582 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6583 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6584 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6585 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6588 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6589 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6590 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6593 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6594 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6595 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6596 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6599 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6600 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6601 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6602 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6603 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6606 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6607 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6608 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6612 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6617 /*-----------------------------------------------------------------*/
6618 /* movLeft2Result - move byte from left to result */
6619 /*-----------------------------------------------------------------*/
6620 static void movLeft2Result (operand *left, int offl,
6621 operand *result, int offr)
6624 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6625 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6626 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6628 if (*l == '@' && (IS_AOP_PREG(result))) {
6629 pic16_emitcode("mov","a,%s",l);
6630 pic16_aopPut(AOP(result),"a",offr);
6632 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6633 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6638 /*-----------------------------------------------------------------*/
6639 /* shiftL2Left2Result - shift left two bytes from left to result */
6640 /*-----------------------------------------------------------------*/
6641 static void shiftL2Left2Result (operand *left, int offl,
6642 operand *result, int offr, int shCount)
6646 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6648 if(pic16_sameRegs(AOP(result), AOP(left))) {
6656 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6657 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6658 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6662 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6663 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6669 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6670 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6671 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6672 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6673 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6674 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6675 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6677 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6678 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6682 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6683 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6684 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6685 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6686 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6687 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6688 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6689 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6690 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6691 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6694 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6695 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6696 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6697 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6698 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6708 /* note, use a mov/add for the shift since the mov has a
6709 chance of getting optimized out */
6710 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6711 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6712 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6713 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6714 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6718 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6719 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6725 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6726 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6727 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6728 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6729 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6730 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6731 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6732 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6736 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6737 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6741 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6742 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6743 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6744 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6746 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6747 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6748 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6749 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6750 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6751 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6752 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6753 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6756 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6757 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6758 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6759 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6760 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6765 /*-----------------------------------------------------------------*/
6766 /* shiftR2Left2Result - shift right two bytes from left to result */
6767 /*-----------------------------------------------------------------*/
6768 static void shiftR2Left2Result (operand *left, int offl,
6769 operand *result, int offr,
6770 int shCount, int sign)
6774 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6775 same = pic16_sameRegs(AOP(result), AOP(left));
6777 if(same && ((offl + MSB16) == offr)){
6779 /* don't crash result[offr] */
6780 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6781 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6784 movLeft2Result(left,offl, result, offr);
6785 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6788 /* a:x >> shCount (x = lsb(result))*/
6791 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6793 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6802 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6807 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6808 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6810 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6811 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6812 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6813 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6818 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6821 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6822 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6829 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6830 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6831 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6833 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6834 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6835 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6836 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6838 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6839 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6840 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6842 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6843 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6844 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6845 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6846 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6850 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6851 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6855 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6856 pic16_emitpcode(POC_BTFSC,
6857 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6858 pic16_emitpcode(POC_ADDWF, 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));
6869 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6870 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6871 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6872 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6874 pic16_emitpcode(POC_BTFSC,
6875 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6876 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6878 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6879 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6880 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6881 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6883 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6884 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6885 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6886 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6887 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6888 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6889 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6890 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6892 pic16_emitpcode(POC_BTFSC,
6893 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6894 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6896 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6897 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6904 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6905 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6906 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6907 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6910 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6912 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6917 /*-----------------------------------------------------------------*/
6918 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6919 /*-----------------------------------------------------------------*/
6920 static void shiftLLeftOrResult (operand *left, int offl,
6921 operand *result, int offr, int shCount)
6923 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6924 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6925 /* shift left accumulator */
6927 /* or with result */
6928 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6929 /* back to result */
6930 pic16_aopPut(AOP(result),"a",offr);
6933 /*-----------------------------------------------------------------*/
6934 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6935 /*-----------------------------------------------------------------*/
6936 static void shiftRLeftOrResult (operand *left, int offl,
6937 operand *result, int offr, int shCount)
6939 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6940 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6941 /* shift right accumulator */
6943 /* or with result */
6944 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6945 /* back to result */
6946 pic16_aopPut(AOP(result),"a",offr);
6949 /*-----------------------------------------------------------------*/
6950 /* genlshOne - left shift a one byte quantity by known count */
6951 /*-----------------------------------------------------------------*/
6952 static void genlshOne (operand *result, operand *left, int shCount)
6954 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6955 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6958 /*-----------------------------------------------------------------*/
6959 /* genlshTwo - left shift two bytes by known amount != 0 */
6960 /*-----------------------------------------------------------------*/
6961 static void genlshTwo (operand *result,operand *left, int shCount)
6965 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6966 size = pic16_getDataSize(result);
6968 /* if shCount >= 8 */
6974 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6976 movLeft2Result(left, LSB, result, MSB16);
6978 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6981 /* 1 <= shCount <= 7 */
6984 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6986 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6990 /*-----------------------------------------------------------------*/
6991 /* shiftLLong - shift left one long from left to result */
6992 /* offl = LSB or MSB16 */
6993 /*-----------------------------------------------------------------*/
6994 static void shiftLLong (operand *left, operand *result, int offr )
6997 int size = AOP_SIZE(result);
6999 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7000 if(size >= LSB+offr){
7001 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7003 pic16_emitcode("add","a,acc");
7004 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7005 size >= MSB16+offr && offr != LSB )
7006 pic16_emitcode("xch","a,%s",
7007 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7009 pic16_aopPut(AOP(result),"a",LSB+offr);
7012 if(size >= MSB16+offr){
7013 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7014 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7017 pic16_emitcode("rlc","a");
7018 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7019 size >= MSB24+offr && offr != LSB)
7020 pic16_emitcode("xch","a,%s",
7021 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7023 pic16_aopPut(AOP(result),"a",MSB16+offr);
7026 if(size >= MSB24+offr){
7027 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7028 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7031 pic16_emitcode("rlc","a");
7032 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7033 size >= MSB32+offr && offr != LSB )
7034 pic16_emitcode("xch","a,%s",
7035 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7037 pic16_aopPut(AOP(result),"a",MSB24+offr);
7040 if(size > MSB32+offr){
7041 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7042 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7045 pic16_emitcode("rlc","a");
7046 pic16_aopPut(AOP(result),"a",MSB32+offr);
7049 pic16_aopPut(AOP(result),zero,LSB);
7052 /*-----------------------------------------------------------------*/
7053 /* genlshFour - shift four byte by a known amount != 0 */
7054 /*-----------------------------------------------------------------*/
7055 static void genlshFour (operand *result, operand *left, int shCount)
7059 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7060 size = AOP_SIZE(result);
7062 /* if shifting more that 3 bytes */
7063 if (shCount >= 24 ) {
7066 /* lowest order of left goes to the highest
7067 order of the destination */
7068 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7070 movLeft2Result(left, LSB, result, MSB32);
7071 pic16_aopPut(AOP(result),zero,LSB);
7072 pic16_aopPut(AOP(result),zero,MSB16);
7073 pic16_aopPut(AOP(result),zero,MSB32);
7077 /* more than two bytes */
7078 else if ( shCount >= 16 ) {
7079 /* lower order two bytes goes to higher order two bytes */
7081 /* if some more remaining */
7083 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7085 movLeft2Result(left, MSB16, result, MSB32);
7086 movLeft2Result(left, LSB, result, MSB24);
7088 pic16_aopPut(AOP(result),zero,MSB16);
7089 pic16_aopPut(AOP(result),zero,LSB);
7093 /* if more than 1 byte */
7094 else if ( shCount >= 8 ) {
7095 /* lower order three bytes goes to higher order three bytes */
7099 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7101 movLeft2Result(left, LSB, result, MSB16);
7103 else{ /* size = 4 */
7105 movLeft2Result(left, MSB24, result, MSB32);
7106 movLeft2Result(left, MSB16, result, MSB24);
7107 movLeft2Result(left, LSB, result, MSB16);
7108 pic16_aopPut(AOP(result),zero,LSB);
7110 else if(shCount == 1)
7111 shiftLLong(left, result, MSB16);
7113 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7114 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7115 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7116 pic16_aopPut(AOP(result),zero,LSB);
7121 /* 1 <= shCount <= 7 */
7122 else if(shCount <= 2){
7123 shiftLLong(left, result, LSB);
7125 shiftLLong(result, result, LSB);
7127 /* 3 <= shCount <= 7, optimize */
7129 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7130 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7131 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7135 /*-----------------------------------------------------------------*/
7136 /* genLeftShiftLiteral - left shifting by known count */
7137 /*-----------------------------------------------------------------*/
7138 static void genLeftShiftLiteral (operand *left,
7143 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7146 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7147 pic16_freeAsmop(right,NULL,ic,TRUE);
7149 pic16_aopOp(left,ic,FALSE);
7150 pic16_aopOp(result,ic,FALSE);
7152 size = getSize(operandType(result));
7155 pic16_emitcode("; shift left ","result %d, left %d",size,
7159 /* I suppose that the left size >= result size */
7162 movLeft2Result(left, size, result, size);
7166 else if(shCount >= (size * 8))
7168 pic16_aopPut(AOP(result),zero,size);
7172 genlshOne (result,left,shCount);
7177 genlshTwo (result,left,shCount);
7181 genlshFour (result,left,shCount);
7185 pic16_freeAsmop(left,NULL,ic,TRUE);
7186 pic16_freeAsmop(result,NULL,ic,TRUE);
7189 /*-----------------------------------------------------------------*
7190 * genMultiAsm - repeat assembly instruction for size of register.
7191 * if endian == 1, then the high byte (i.e base address + size of
7192 * register) is used first else the low byte is used first;
7193 *-----------------------------------------------------------------*/
7194 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7199 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7212 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7217 /*-----------------------------------------------------------------*/
7218 /* genLeftShift - generates code for left shifting */
7219 /*-----------------------------------------------------------------*/
7220 static void genLeftShift (iCode *ic)
7222 operand *left,*right, *result;
7225 symbol *tlbl , *tlbl1;
7228 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7230 right = IC_RIGHT(ic);
7232 result = IC_RESULT(ic);
7234 pic16_aopOp(right,ic,FALSE);
7236 /* if the shift count is known then do it
7237 as efficiently as possible */
7238 if (AOP_TYPE(right) == AOP_LIT) {
7239 genLeftShiftLiteral (left,right,result,ic);
7243 /* shift count is unknown then we have to form
7244 a loop get the loop count in B : Note: we take
7245 only the lower order byte since shifting
7246 more that 32 bits make no sense anyway, ( the
7247 largest size of an object can be only 32 bits ) */
7250 pic16_aopOp(left,ic,FALSE);
7251 pic16_aopOp(result,ic,FALSE);
7253 /* now move the left to the result if they are not the
7255 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7256 AOP_SIZE(result) > 1) {
7258 size = AOP_SIZE(result);
7261 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7262 if (*l == '@' && (IS_AOP_PREG(result))) {
7264 pic16_emitcode("mov","a,%s",l);
7265 pic16_aopPut(AOP(result),"a",offset);
7267 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7268 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7269 //pic16_aopPut(AOP(result),l,offset);
7275 size = AOP_SIZE(result);
7277 /* if it is only one byte then */
7279 if(optimized_for_speed) {
7280 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7281 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7282 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7283 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7284 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7285 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7286 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7287 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7288 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7289 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7290 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7291 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7294 tlbl = newiTempLabel(NULL);
7295 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7296 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7297 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7300 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7301 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7302 pic16_emitpLabel(tlbl->key);
7303 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7304 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7306 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7311 if (pic16_sameRegs(AOP(left),AOP(result))) {
7313 tlbl = newiTempLabel(NULL);
7314 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7315 genMultiAsm(POC_RRCF, result, size,1);
7316 pic16_emitpLabel(tlbl->key);
7317 genMultiAsm(POC_RLCF, result, size,0);
7318 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7320 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7324 //tlbl = newiTempLabel(NULL);
7326 //tlbl1 = newiTempLabel(NULL);
7328 //reAdjustPreg(AOP(result));
7330 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7331 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7332 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7334 //pic16_emitcode("add","a,acc");
7335 //pic16_aopPut(AOP(result),"a",offset++);
7337 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7339 // pic16_emitcode("rlc","a");
7340 // pic16_aopPut(AOP(result),"a",offset++);
7342 //reAdjustPreg(AOP(result));
7344 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7345 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7348 tlbl = newiTempLabel(NULL);
7349 tlbl1= newiTempLabel(NULL);
7351 size = AOP_SIZE(result);
7354 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7356 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7358 /* offset should be 0, 1 or 3 */
7359 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7361 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7363 pic16_emitpcode(POC_MOVWF, pctemp);
7366 pic16_emitpLabel(tlbl->key);
7369 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7371 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7373 pic16_emitpcode(POC_DECFSZ, pctemp);
7374 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7375 pic16_emitpLabel(tlbl1->key);
7377 pic16_popReleaseTempReg(pctemp);
7381 pic16_freeAsmop (right,NULL,ic,TRUE);
7382 pic16_freeAsmop(left,NULL,ic,TRUE);
7383 pic16_freeAsmop(result,NULL,ic,TRUE);
7386 /*-----------------------------------------------------------------*/
7387 /* genrshOne - right shift a one byte quantity by known count */
7388 /*-----------------------------------------------------------------*/
7389 static void genrshOne (operand *result, operand *left,
7390 int shCount, int sign)
7392 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7393 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7396 /*-----------------------------------------------------------------*/
7397 /* genrshTwo - right shift two bytes by known amount != 0 */
7398 /*-----------------------------------------------------------------*/
7399 static void genrshTwo (operand *result,operand *left,
7400 int shCount, int sign)
7402 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7403 /* if shCount >= 8 */
7407 shiftR1Left2Result(left, MSB16, result, LSB,
7410 movLeft2Result(left, MSB16, result, LSB);
7412 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7415 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7416 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7420 /* 1 <= shCount <= 7 */
7422 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7425 /*-----------------------------------------------------------------*/
7426 /* shiftRLong - shift right one long from left to result */
7427 /* offl = LSB or MSB16 */
7428 /*-----------------------------------------------------------------*/
7429 static void shiftRLong (operand *left, int offl,
7430 operand *result, int sign)
7432 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7434 pic16_emitcode("clr","c");
7435 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7437 pic16_emitcode("mov","c,acc.7");
7438 pic16_emitcode("rrc","a");
7439 pic16_aopPut(AOP(result),"a",MSB32-offl);
7441 /* add sign of "a" */
7442 pic16_addSign(result, MSB32, sign);
7444 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7445 pic16_emitcode("rrc","a");
7446 pic16_aopPut(AOP(result),"a",MSB24-offl);
7448 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7449 pic16_emitcode("rrc","a");
7450 pic16_aopPut(AOP(result),"a",MSB16-offl);
7453 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7454 pic16_emitcode("rrc","a");
7455 pic16_aopPut(AOP(result),"a",LSB);
7459 /*-----------------------------------------------------------------*/
7460 /* genrshFour - shift four byte by a known amount != 0 */
7461 /*-----------------------------------------------------------------*/
7462 static void genrshFour (operand *result, operand *left,
7463 int shCount, int sign)
7465 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7466 /* if shifting more that 3 bytes */
7467 if(shCount >= 24 ) {
7470 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7472 movLeft2Result(left, MSB32, result, LSB);
7474 pic16_addSign(result, MSB16, sign);
7476 else if(shCount >= 16){
7479 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7481 movLeft2Result(left, MSB24, result, LSB);
7482 movLeft2Result(left, MSB32, result, MSB16);
7484 pic16_addSign(result, MSB24, sign);
7486 else if(shCount >= 8){
7489 shiftRLong(left, MSB16, result, sign);
7490 else if(shCount == 0){
7491 movLeft2Result(left, MSB16, result, LSB);
7492 movLeft2Result(left, MSB24, result, MSB16);
7493 movLeft2Result(left, MSB32, result, MSB24);
7494 pic16_addSign(result, MSB32, sign);
7497 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7498 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7499 /* the last shift is signed */
7500 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7501 pic16_addSign(result, MSB32, sign);
7504 else{ /* 1 <= shCount <= 7 */
7506 shiftRLong(left, LSB, result, sign);
7508 shiftRLong(result, LSB, result, sign);
7511 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7512 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7513 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7518 /*-----------------------------------------------------------------*/
7519 /* genRightShiftLiteral - right shifting by known count */
7520 /*-----------------------------------------------------------------*/
7521 static void genRightShiftLiteral (operand *left,
7527 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7530 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7531 pic16_freeAsmop(right,NULL,ic,TRUE);
7533 pic16_aopOp(left,ic,FALSE);
7534 pic16_aopOp(result,ic,FALSE);
7537 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7541 lsize = pic16_getDataSize(left);
7542 res_size = pic16_getDataSize(result);
7543 /* test the LEFT size !!! */
7545 /* I suppose that the left size >= result size */
7548 movLeft2Result(left, lsize, result, res_size);
7551 else if(shCount >= (lsize * 8)){
7554 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7556 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7557 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7562 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7563 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7564 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7566 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7571 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7578 genrshOne (result,left,shCount,sign);
7582 genrshTwo (result,left,shCount,sign);
7586 genrshFour (result,left,shCount,sign);
7594 pic16_freeAsmop(left,NULL,ic,TRUE);
7595 pic16_freeAsmop(result,NULL,ic,TRUE);
7598 /*-----------------------------------------------------------------*/
7599 /* genSignedRightShift - right shift of signed number */
7600 /*-----------------------------------------------------------------*/
7601 static void genSignedRightShift (iCode *ic)
7603 operand *right, *left, *result;
7606 symbol *tlbl, *tlbl1 ;
7609 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7611 /* we do it the hard way put the shift count in b
7612 and loop thru preserving the sign */
7613 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7615 right = IC_RIGHT(ic);
7617 result = IC_RESULT(ic);
7619 pic16_aopOp(right,ic,FALSE);
7620 pic16_aopOp(left,ic,FALSE);
7621 pic16_aopOp(result,ic,FALSE);
7624 if ( AOP_TYPE(right) == AOP_LIT) {
7625 genRightShiftLiteral (left,right,result,ic,1);
7628 /* shift count is unknown then we have to form
7629 a loop get the loop count in B : Note: we take
7630 only the lower order byte since shifting
7631 more that 32 bits make no sense anyway, ( the
7632 largest size of an object can be only 32 bits ) */
7634 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7635 //pic16_emitcode("inc","b");
7636 //pic16_freeAsmop (right,NULL,ic,TRUE);
7637 //pic16_aopOp(left,ic,FALSE);
7638 //pic16_aopOp(result,ic,FALSE);
7640 /* now move the left to the result if they are not the
7642 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7643 AOP_SIZE(result) > 1) {
7645 size = AOP_SIZE(result);
7649 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7650 if (*l == '@' && IS_AOP_PREG(result)) {
7652 pic16_emitcode("mov","a,%s",l);
7653 pic16_aopPut(AOP(result),"a",offset);
7655 pic16_aopPut(AOP(result),l,offset);
7657 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7658 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7664 /* mov the highest order bit to OVR */
7665 tlbl = newiTempLabel(NULL);
7666 tlbl1= newiTempLabel(NULL);
7668 size = AOP_SIZE(result);
7671 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7673 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7675 /* offset should be 0, 1 or 3 */
7676 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7678 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7680 pic16_emitpcode(POC_MOVWF, pctemp);
7683 pic16_emitpLabel(tlbl->key);
7685 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7686 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7689 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7692 pic16_emitpcode(POC_DECFSZ, pctemp);
7693 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7694 pic16_emitpLabel(tlbl1->key);
7696 pic16_popReleaseTempReg(pctemp);
7698 size = AOP_SIZE(result);
7700 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7701 pic16_emitcode("rlc","a");
7702 pic16_emitcode("mov","ov,c");
7703 /* if it is only one byte then */
7705 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7707 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7708 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7709 pic16_emitcode("mov","c,ov");
7710 pic16_emitcode("rrc","a");
7711 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7712 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7713 pic16_aopPut(AOP(result),"a",0);
7717 reAdjustPreg(AOP(result));
7718 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7719 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7720 pic16_emitcode("mov","c,ov");
7722 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7724 pic16_emitcode("rrc","a");
7725 pic16_aopPut(AOP(result),"a",offset--);
7727 reAdjustPreg(AOP(result));
7728 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7729 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7734 pic16_freeAsmop(left,NULL,ic,TRUE);
7735 pic16_freeAsmop(result,NULL,ic,TRUE);
7736 pic16_freeAsmop(right,NULL,ic,TRUE);
7739 /*-----------------------------------------------------------------*/
7740 /* genRightShift - generate code for right shifting */
7741 /*-----------------------------------------------------------------*/
7742 static void genRightShift (iCode *ic)
7744 operand *right, *left, *result;
7748 symbol *tlbl, *tlbl1 ;
7750 /* if signed then we do it the hard way preserve the
7751 sign bit moving it inwards */
7752 retype = getSpec(operandType(IC_RESULT(ic)));
7753 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7755 if (!SPEC_USIGN(retype)) {
7756 genSignedRightShift (ic);
7760 /* signed & unsigned types are treated the same : i.e. the
7761 signed is NOT propagated inwards : quoting from the
7762 ANSI - standard : "for E1 >> E2, is equivalent to division
7763 by 2**E2 if unsigned or if it has a non-negative value,
7764 otherwise the result is implementation defined ", MY definition
7765 is that the sign does not get propagated */
7767 right = IC_RIGHT(ic);
7769 result = IC_RESULT(ic);
7771 pic16_aopOp(right,ic,FALSE);
7773 /* if the shift count is known then do it
7774 as efficiently as possible */
7775 if (AOP_TYPE(right) == AOP_LIT) {
7776 genRightShiftLiteral (left,right,result,ic, 0);
7780 /* shift count is unknown then we have to form
7781 a loop get the loop count in B : Note: we take
7782 only the lower order byte since shifting
7783 more that 32 bits make no sense anyway, ( the
7784 largest size of an object can be only 32 bits ) */
7786 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7787 pic16_emitcode("inc","b");
7788 pic16_aopOp(left,ic,FALSE);
7789 pic16_aopOp(result,ic,FALSE);
7791 /* now move the left to the result if they are not the
7793 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7794 AOP_SIZE(result) > 1) {
7796 size = AOP_SIZE(result);
7799 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7800 if (*l == '@' && IS_AOP_PREG(result)) {
7802 pic16_emitcode("mov","a,%s",l);
7803 pic16_aopPut(AOP(result),"a",offset);
7805 pic16_aopPut(AOP(result),l,offset);
7810 tlbl = newiTempLabel(NULL);
7811 tlbl1= newiTempLabel(NULL);
7812 size = AOP_SIZE(result);
7815 /* if it is only one byte then */
7818 tlbl = newiTempLabel(NULL);
7819 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7820 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7821 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7824 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7825 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7826 pic16_emitpLabel(tlbl->key);
7827 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7828 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7830 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7835 reAdjustPreg(AOP(result));
7836 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7837 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7840 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7842 pic16_emitcode("rrc","a");
7843 pic16_aopPut(AOP(result),"a",offset--);
7845 reAdjustPreg(AOP(result));
7847 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7848 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7851 pic16_freeAsmop(left,NULL,ic,TRUE);
7852 pic16_freeAsmop (right,NULL,ic,TRUE);
7853 pic16_freeAsmop(result,NULL,ic,TRUE);
7856 /*-----------------------------------------------------------------*/
7857 /* genUnpackBits - generates code for unpacking bits */
7858 /*-----------------------------------------------------------------*/
7859 static void genUnpackBits (operand *result, char *rname, int ptype)
7866 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7867 etype = getSpec(operandType(result));
7869 /* read the first byte */
7874 pic16_emitcode("mov","a,@%s",rname);
7878 pic16_emitcode("movx","a,@%s",rname);
7882 pic16_emitcode("movx","a,@dptr");
7886 pic16_emitcode("clr","a");
7887 pic16_emitcode("movc","a","@a+dptr");
7891 pic16_emitcode("lcall","__gptrget");
7895 /* if we have bitdisplacement then it fits */
7896 /* into this byte completely or if length is */
7897 /* less than a byte */
7898 if ((shCnt = SPEC_BSTR(etype)) ||
7899 (SPEC_BLEN(etype) <= 8)) {
7901 /* shift right acc */
7904 pic16_emitcode("anl","a,#0x%02x",
7905 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7906 pic16_aopPut(AOP(result),"a",offset);
7910 /* bit field did not fit in a byte */
7911 rlen = SPEC_BLEN(etype) - 8;
7912 pic16_aopPut(AOP(result),"a",offset++);
7919 pic16_emitcode("inc","%s",rname);
7920 pic16_emitcode("mov","a,@%s",rname);
7924 pic16_emitcode("inc","%s",rname);
7925 pic16_emitcode("movx","a,@%s",rname);
7929 pic16_emitcode("inc","dptr");
7930 pic16_emitcode("movx","a,@dptr");
7934 pic16_emitcode("clr","a");
7935 pic16_emitcode("inc","dptr");
7936 pic16_emitcode("movc","a","@a+dptr");
7940 pic16_emitcode("inc","dptr");
7941 pic16_emitcode("lcall","__gptrget");
7946 /* if we are done */
7950 pic16_aopPut(AOP(result),"a",offset++);
7955 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7956 pic16_aopPut(AOP(result),"a",offset);
7963 /*-----------------------------------------------------------------*/
7964 /* genDataPointerGet - generates code when ptr offset is known */
7965 /*-----------------------------------------------------------------*/
7966 static void genDataPointerGet (operand *left,
7970 int size , offset = 0;
7973 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7976 /* optimization - most of the time, left and result are the same
7977 * address, but different types. for the pic code, we could omit
7981 pic16_aopOp(result,ic,TRUE);
7983 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7985 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7987 size = AOP_SIZE(result);
7990 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7994 pic16_freeAsmop(left,NULL,ic,TRUE);
7995 pic16_freeAsmop(result,NULL,ic,TRUE);
7998 /*-----------------------------------------------------------------*/
7999 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8000 /*-----------------------------------------------------------------*/
8001 static void genNearPointerGet (operand *left,
8006 //regs *preg = NULL ;
8008 sym_link *rtype, *retype;
8009 sym_link *ltype = operandType(left);
8012 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8014 rtype = operandType(result);
8015 retype= getSpec(rtype);
8017 pic16_aopOp(left,ic,FALSE);
8019 /* if left is rematerialisable and
8020 result is not bit variable type and
8021 the left is pointer to data space i.e
8022 lower 128 bytes of space */
8023 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8024 !IS_BITVAR(retype) &&
8025 DCL_TYPE(ltype) == POINTER) {
8026 //genDataPointerGet (left,result,ic);
8030 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8032 /* if the value is already in a pointer register
8033 then don't need anything more */
8034 if (!AOP_INPREG(AOP(left))) {
8035 /* otherwise get a free pointer register */
8036 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8039 preg = getFreePtr(ic,&aop,FALSE);
8040 pic16_emitcode("mov","%s,%s",
8042 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8043 rname = preg->name ;
8047 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8049 pic16_aopOp (result,ic,FALSE);
8051 /* if bitfield then unpack the bits */
8052 if (IS_BITVAR(retype))
8053 genUnpackBits (result,rname,POINTER);
8055 /* we have can just get the values */
8056 int size = AOP_SIZE(result);
8059 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8061 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8062 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8064 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8065 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8067 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8071 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8073 pic16_emitcode("mov","a,@%s",rname);
8074 pic16_aopPut(AOP(result),"a",offset);
8076 sprintf(buffer,"@%s",rname);
8077 pic16_aopPut(AOP(result),buffer,offset);
8081 pic16_emitcode("inc","%s",rname);
8086 /* now some housekeeping stuff */
8088 /* we had to allocate for this iCode */
8089 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8090 pic16_freeAsmop(NULL,aop,ic,TRUE);
8092 /* we did not allocate which means left
8093 already in a pointer register, then
8094 if size > 0 && this could be used again
8095 we have to point it back to where it
8097 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8098 if (AOP_SIZE(result) > 1 &&
8099 !OP_SYMBOL(left)->remat &&
8100 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8102 int size = AOP_SIZE(result) - 1;
8104 pic16_emitcode("dec","%s",rname);
8109 pic16_freeAsmop(left,NULL,ic,TRUE);
8110 pic16_freeAsmop(result,NULL,ic,TRUE);
8114 /*-----------------------------------------------------------------*/
8115 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8116 /*-----------------------------------------------------------------*/
8117 static void genPagedPointerGet (operand *left,
8124 sym_link *rtype, *retype;
8126 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8128 rtype = operandType(result);
8129 retype= getSpec(rtype);
8131 pic16_aopOp(left,ic,FALSE);
8133 /* if the value is already in a pointer register
8134 then don't need anything more */
8135 if (!AOP_INPREG(AOP(left))) {
8136 /* otherwise get a free pointer register */
8138 preg = getFreePtr(ic,&aop,FALSE);
8139 pic16_emitcode("mov","%s,%s",
8141 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8142 rname = preg->name ;
8144 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8146 pic16_freeAsmop(left,NULL,ic,TRUE);
8147 pic16_aopOp (result,ic,FALSE);
8149 /* if bitfield then unpack the bits */
8150 if (IS_BITVAR(retype))
8151 genUnpackBits (result,rname,PPOINTER);
8153 /* we have can just get the values */
8154 int size = AOP_SIZE(result);
8159 pic16_emitcode("movx","a,@%s",rname);
8160 pic16_aopPut(AOP(result),"a",offset);
8165 pic16_emitcode("inc","%s",rname);
8169 /* now some housekeeping stuff */
8171 /* we had to allocate for this iCode */
8172 pic16_freeAsmop(NULL,aop,ic,TRUE);
8174 /* we did not allocate which means left
8175 already in a pointer register, then
8176 if size > 0 && this could be used again
8177 we have to point it back to where it
8179 if (AOP_SIZE(result) > 1 &&
8180 !OP_SYMBOL(left)->remat &&
8181 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8183 int size = AOP_SIZE(result) - 1;
8185 pic16_emitcode("dec","%s",rname);
8190 pic16_freeAsmop(result,NULL,ic,TRUE);
8195 /*-----------------------------------------------------------------*/
8196 /* genFarPointerGet - gget value from far space */
8197 /*-----------------------------------------------------------------*/
8198 static void genFarPointerGet (operand *left,
8199 operand *result, iCode *ic)
8202 sym_link *retype = getSpec(operandType(result));
8204 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8206 pic16_aopOp(left,ic,FALSE);
8208 /* if the operand is already in dptr
8209 then we do nothing else we move the value to dptr */
8210 if (AOP_TYPE(left) != AOP_STR) {
8211 /* if this is remateriazable */
8212 if (AOP_TYPE(left) == AOP_IMMD)
8213 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8214 else { /* we need to get it byte by byte */
8215 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8216 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8217 if (options.model == MODEL_FLAT24)
8219 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8223 /* so dptr know contains the address */
8224 pic16_freeAsmop(left,NULL,ic,TRUE);
8225 pic16_aopOp(result,ic,FALSE);
8227 /* if bit then unpack */
8228 if (IS_BITVAR(retype))
8229 genUnpackBits(result,"dptr",FPOINTER);
8231 size = AOP_SIZE(result);
8235 pic16_emitcode("movx","a,@dptr");
8236 pic16_aopPut(AOP(result),"a",offset++);
8238 pic16_emitcode("inc","dptr");
8242 pic16_freeAsmop(result,NULL,ic,TRUE);
8245 /*-----------------------------------------------------------------*/
8246 /* genCodePointerGet - get value from code space */
8247 /*-----------------------------------------------------------------*/
8248 static void genCodePointerGet (operand *left,
8249 operand *result, iCode *ic)
8252 sym_link *retype = getSpec(operandType(result));
8254 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8256 pic16_aopOp(left,ic,FALSE);
8258 /* if the operand is already in dptr
8259 then we do nothing else we move the value to dptr */
8260 if (AOP_TYPE(left) != AOP_STR) {
8261 /* if this is remateriazable */
8262 if (AOP_TYPE(left) == AOP_IMMD)
8263 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8264 else { /* we need to get it byte by byte */
8265 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8266 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8267 if (options.model == MODEL_FLAT24)
8269 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8273 /* so dptr know contains the address */
8274 pic16_freeAsmop(left,NULL,ic,TRUE);
8275 pic16_aopOp(result,ic,FALSE);
8277 /* if bit then unpack */
8278 if (IS_BITVAR(retype))
8279 genUnpackBits(result,"dptr",CPOINTER);
8281 size = AOP_SIZE(result);
8285 pic16_emitcode("clr","a");
8286 pic16_emitcode("movc","a,@a+dptr");
8287 pic16_aopPut(AOP(result),"a",offset++);
8289 pic16_emitcode("inc","dptr");
8293 pic16_freeAsmop(result,NULL,ic,TRUE);
8296 /*-----------------------------------------------------------------*/
8297 /* genGenPointerGet - gget value from generic pointer space */
8298 /*-----------------------------------------------------------------*/
8299 static void genGenPointerGet (operand *left,
8300 operand *result, iCode *ic)
8303 sym_link *retype = getSpec(operandType(result));
8305 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8306 pic16_aopOp(left,ic,FALSE);
8307 pic16_aopOp(result,ic,FALSE);
8310 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8312 /* if the operand is already in dptr
8313 then we do nothing else we move the value to dptr */
8314 // if (AOP_TYPE(left) != AOP_STR) {
8315 /* if this is remateriazable */
8316 if (AOP_TYPE(left) == AOP_IMMD) {
8317 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8318 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8320 else { /* we need to get it byte by byte */
8322 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8323 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8325 size = AOP_SIZE(result);
8329 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8330 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8332 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8337 /* so dptr know contains the address */
8339 /* if bit then unpack */
8340 //if (IS_BITVAR(retype))
8341 // genUnpackBits(result,"dptr",GPOINTER);
8344 pic16_freeAsmop(left,NULL,ic,TRUE);
8345 pic16_freeAsmop(result,NULL,ic,TRUE);
8349 /*-----------------------------------------------------------------*/
8350 /* genConstPointerGet - get value from const generic pointer space */
8351 /*-----------------------------------------------------------------*/
8352 static void genConstPointerGet (operand *left,
8353 operand *result, iCode *ic)
8355 //sym_link *retype = getSpec(operandType(result));
8356 symbol *albl = newiTempLabel(NULL);
8357 symbol *blbl = newiTempLabel(NULL);
8360 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8361 pic16_aopOp(left,ic,FALSE);
8362 pic16_aopOp(result,ic,FALSE);
8365 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8367 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8369 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8370 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8371 pic16_emitpLabel(albl->key);
8373 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8375 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8376 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8377 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8378 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8380 pic16_emitpLabel(blbl->key);
8382 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8385 pic16_freeAsmop(left,NULL,ic,TRUE);
8386 pic16_freeAsmop(result,NULL,ic,TRUE);
8389 /*-----------------------------------------------------------------*/
8390 /* genPointerGet - generate code for pointer get */
8391 /*-----------------------------------------------------------------*/
8392 static void genPointerGet (iCode *ic)
8394 operand *left, *result ;
8395 sym_link *type, *etype;
8398 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8401 result = IC_RESULT(ic) ;
8403 /* depending on the type of pointer we need to
8404 move it to the correct pointer register */
8405 type = operandType(left);
8406 etype = getSpec(type);
8408 if (IS_PTR_CONST(type))
8409 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8411 /* if left is of type of pointer then it is simple */
8412 if (IS_PTR(type) && !IS_FUNC(type->next))
8413 p_type = DCL_TYPE(type);
8415 /* we have to go by the storage class */
8416 p_type = PTR_TYPE(SPEC_OCLS(etype));
8418 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8420 if (SPEC_OCLS(etype)->codesp ) {
8421 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8422 //p_type = CPOINTER ;
8425 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8426 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8427 /*p_type = FPOINTER ;*/
8429 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8430 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8431 /* p_type = PPOINTER; */
8433 if (SPEC_OCLS(etype) == idata )
8434 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8435 /* p_type = IPOINTER; */
8437 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8438 /* p_type = POINTER ; */
8441 /* now that we have the pointer type we assign
8442 the pointer values */
8447 genNearPointerGet (left,result,ic);
8451 genPagedPointerGet(left,result,ic);
8455 genFarPointerGet (left,result,ic);
8459 genConstPointerGet (left,result,ic);
8460 //pic16_emitcodePointerGet (left,result,ic);
8464 if (IS_PTR_CONST(type))
8465 genConstPointerGet (left,result,ic);
8467 genGenPointerGet (left,result,ic);
8473 /*-----------------------------------------------------------------*/
8474 /* genPackBits - generates code for packed bit storage */
8475 /*-----------------------------------------------------------------*/
8476 static void genPackBits (sym_link *etype ,
8478 char *rname, int p_type)
8486 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8487 blen = SPEC_BLEN(etype);
8488 bstr = SPEC_BSTR(etype);
8490 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8493 /* if the bit lenth is less than or */
8494 /* it exactly fits a byte then */
8495 if (SPEC_BLEN(etype) <= 8 ) {
8496 shCount = SPEC_BSTR(etype) ;
8498 /* shift left acc */
8501 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8506 pic16_emitcode ("mov","b,a");
8507 pic16_emitcode("mov","a,@%s",rname);
8511 pic16_emitcode ("mov","b,a");
8512 pic16_emitcode("movx","a,@dptr");
8516 pic16_emitcode ("push","b");
8517 pic16_emitcode ("push","acc");
8518 pic16_emitcode ("lcall","__gptrget");
8519 pic16_emitcode ("pop","b");
8523 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8524 ((unsigned char)(0xFF << (blen+bstr)) |
8525 (unsigned char)(0xFF >> (8-bstr)) ) );
8526 pic16_emitcode ("orl","a,b");
8527 if (p_type == GPOINTER)
8528 pic16_emitcode("pop","b");
8534 pic16_emitcode("mov","@%s,a",rname);
8538 pic16_emitcode("movx","@dptr,a");
8542 DEBUGpic16_emitcode(";lcall","__gptrput");
8547 if ( SPEC_BLEN(etype) <= 8 )
8550 pic16_emitcode("inc","%s",rname);
8551 rLen = SPEC_BLEN(etype) ;
8553 /* now generate for lengths greater than one byte */
8556 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8566 pic16_emitcode("mov","@%s,a",rname);
8568 pic16_emitcode("mov","@%s,%s",rname,l);
8573 pic16_emitcode("movx","@dptr,a");
8578 DEBUGpic16_emitcode(";lcall","__gptrput");
8581 pic16_emitcode ("inc","%s",rname);
8586 /* last last was not complete */
8588 /* save the byte & read byte */
8591 pic16_emitcode ("mov","b,a");
8592 pic16_emitcode("mov","a,@%s",rname);
8596 pic16_emitcode ("mov","b,a");
8597 pic16_emitcode("movx","a,@dptr");
8601 pic16_emitcode ("push","b");
8602 pic16_emitcode ("push","acc");
8603 pic16_emitcode ("lcall","__gptrget");
8604 pic16_emitcode ("pop","b");
8608 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8609 pic16_emitcode ("orl","a,b");
8612 if (p_type == GPOINTER)
8613 pic16_emitcode("pop","b");
8618 pic16_emitcode("mov","@%s,a",rname);
8622 pic16_emitcode("movx","@dptr,a");
8626 DEBUGpic16_emitcode(";lcall","__gptrput");
8630 /*-----------------------------------------------------------------*/
8631 /* genDataPointerSet - remat pointer to data space */
8632 /*-----------------------------------------------------------------*/
8633 static void genDataPointerSet(operand *right,
8637 int size, offset = 0 ;
8638 char *l, buffer[256];
8640 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8641 pic16_aopOp(right,ic,FALSE);
8643 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8644 size = AOP_SIZE(right);
8646 if ( AOP_TYPE(result) == AOP_PCODE) {
8647 fprintf(stderr,"genDataPointerSet %s, %d\n",
8648 AOP(result)->aopu.pcop->name,
8649 PCOI(AOP(result)->aopu.pcop)->offset);
8653 // tsd, was l+1 - the underline `_' prefix was being stripped
8656 sprintf(buffer,"(%s + %d)",l,offset);
8657 fprintf(stderr,"oops %s\n",buffer);
8659 sprintf(buffer,"%s",l);
8661 if (AOP_TYPE(right) == AOP_LIT) {
8662 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8663 lit = lit >> (8*offset);
8665 pic16_emitcode("movlw","%d",lit);
8666 pic16_emitcode("movwf","%s",buffer);
8668 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8669 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8670 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8673 pic16_emitcode("clrf","%s",buffer);
8674 //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8675 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8678 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8679 pic16_emitcode("movwf","%s",buffer);
8681 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8682 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8683 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8690 pic16_freeAsmop(right,NULL,ic,TRUE);
8691 pic16_freeAsmop(result,NULL,ic,TRUE);
8694 /*-----------------------------------------------------------------*/
8695 /* genNearPointerSet - pic16_emitcode for near pointer put */
8696 /*-----------------------------------------------------------------*/
8697 static void genNearPointerSet (operand *right,
8704 sym_link *ptype = operandType(result);
8707 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8708 retype= getSpec(operandType(right));
8710 pic16_aopOp(result,ic,FALSE);
8713 /* if the result is rematerializable &
8714 in data space & not a bit variable */
8715 //if (AOP_TYPE(result) == AOP_IMMD &&
8716 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8717 DCL_TYPE(ptype) == POINTER &&
8718 !IS_BITVAR(retype)) {
8719 genDataPointerSet (right,result,ic);
8720 pic16_freeAsmop(result,NULL,ic,TRUE);
8724 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8725 pic16_aopOp(right,ic,FALSE);
8726 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8728 /* if the value is already in a pointer register
8729 then don't need anything more */
8730 if (!AOP_INPREG(AOP(result))) {
8731 /* otherwise get a free pointer register */
8732 //aop = newAsmop(0);
8733 //preg = getFreePtr(ic,&aop,FALSE);
8734 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8735 //pic16_emitcode("mov","%s,%s",
8737 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8738 //rname = preg->name ;
8739 //pic16_emitcode("movwf","fsr0");
8740 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8741 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8742 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8743 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8747 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8750 /* if bitfield then unpack the bits */
8751 if (IS_BITVAR(retype)) {
8752 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8753 "The programmer is obviously confused");
8754 //genPackBits (retype,right,rname,POINTER);
8758 /* we have can just get the values */
8759 int size = AOP_SIZE(right);
8762 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8764 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8767 //pic16_emitcode("mov","@%s,a",rname);
8768 pic16_emitcode("movf","indf0,w ;1");
8771 if (AOP_TYPE(right) == AOP_LIT) {
8772 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8774 pic16_emitcode("movlw","%s",l);
8775 pic16_emitcode("movwf","indf0 ;2");
8777 pic16_emitcode("clrf","indf0");
8779 pic16_emitcode("movf","%s,w",l);
8780 pic16_emitcode("movwf","indf0 ;2");
8782 //pic16_emitcode("mov","@%s,%s",rname,l);
8785 pic16_emitcode("incf","fsr0,f ;3");
8786 //pic16_emitcode("inc","%s",rname);
8791 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8792 /* now some housekeeping stuff */
8794 /* we had to allocate for this iCode */
8795 pic16_freeAsmop(NULL,aop,ic,TRUE);
8797 /* we did not allocate which means left
8798 already in a pointer register, then
8799 if size > 0 && this could be used again
8800 we have to point it back to where it
8802 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8803 if (AOP_SIZE(right) > 1 &&
8804 !OP_SYMBOL(result)->remat &&
8805 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8807 int size = AOP_SIZE(right) - 1;
8809 pic16_emitcode("decf","fsr0,f");
8810 //pic16_emitcode("dec","%s",rname);
8814 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8817 pic16_freeAsmop(right,NULL,ic,TRUE);
8818 pic16_freeAsmop(result,NULL,ic,TRUE);
8821 /*-----------------------------------------------------------------*/
8822 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8823 /*-----------------------------------------------------------------*/
8824 static void genPagedPointerSet (operand *right,
8833 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8835 retype= getSpec(operandType(right));
8837 pic16_aopOp(result,ic,FALSE);
8839 /* if the value is already in a pointer register
8840 then don't need anything more */
8841 if (!AOP_INPREG(AOP(result))) {
8842 /* otherwise get a free pointer register */
8844 preg = getFreePtr(ic,&aop,FALSE);
8845 pic16_emitcode("mov","%s,%s",
8847 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8848 rname = preg->name ;
8850 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8852 pic16_freeAsmop(result,NULL,ic,TRUE);
8853 pic16_aopOp (right,ic,FALSE);
8855 /* if bitfield then unpack the bits */
8856 if (IS_BITVAR(retype))
8857 genPackBits (retype,right,rname,PPOINTER);
8859 /* we have can just get the values */
8860 int size = AOP_SIZE(right);
8864 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8867 pic16_emitcode("movx","@%s,a",rname);
8870 pic16_emitcode("inc","%s",rname);
8876 /* now some housekeeping stuff */
8878 /* we had to allocate for this iCode */
8879 pic16_freeAsmop(NULL,aop,ic,TRUE);
8881 /* we did not allocate which means left
8882 already in a pointer register, then
8883 if size > 0 && this could be used again
8884 we have to point it back to where it
8886 if (AOP_SIZE(right) > 1 &&
8887 !OP_SYMBOL(result)->remat &&
8888 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8890 int size = AOP_SIZE(right) - 1;
8892 pic16_emitcode("dec","%s",rname);
8897 pic16_freeAsmop(right,NULL,ic,TRUE);
8902 /*-----------------------------------------------------------------*/
8903 /* genFarPointerSet - set value from far space */
8904 /*-----------------------------------------------------------------*/
8905 static void genFarPointerSet (operand *right,
8906 operand *result, iCode *ic)
8909 sym_link *retype = getSpec(operandType(right));
8911 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8912 pic16_aopOp(result,ic,FALSE);
8914 /* if the operand is already in dptr
8915 then we do nothing else we move the value to dptr */
8916 if (AOP_TYPE(result) != AOP_STR) {
8917 /* if this is remateriazable */
8918 if (AOP_TYPE(result) == AOP_IMMD)
8919 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8920 else { /* we need to get it byte by byte */
8921 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8922 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8923 if (options.model == MODEL_FLAT24)
8925 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8929 /* so dptr know contains the address */
8930 pic16_freeAsmop(result,NULL,ic,TRUE);
8931 pic16_aopOp(right,ic,FALSE);
8933 /* if bit then unpack */
8934 if (IS_BITVAR(retype))
8935 genPackBits(retype,right,"dptr",FPOINTER);
8937 size = AOP_SIZE(right);
8941 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8943 pic16_emitcode("movx","@dptr,a");
8945 pic16_emitcode("inc","dptr");
8949 pic16_freeAsmop(right,NULL,ic,TRUE);
8952 /*-----------------------------------------------------------------*/
8953 /* genGenPointerSet - set value from generic pointer space */
8954 /*-----------------------------------------------------------------*/
8955 static void genGenPointerSet (operand *right,
8956 operand *result, iCode *ic)
8959 sym_link *retype = getSpec(operandType(right));
8961 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8963 pic16_aopOp(result,ic,FALSE);
8964 pic16_aopOp(right,ic,FALSE);
8965 size = AOP_SIZE(right);
8967 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8969 /* if the operand is already in dptr
8970 then we do nothing else we move the value to dptr */
8971 if (AOP_TYPE(result) != AOP_STR) {
8972 /* if this is remateriazable */
8973 if (AOP_TYPE(result) == AOP_IMMD) {
8974 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8975 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8977 else { /* we need to get it byte by byte */
8978 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8979 size = AOP_SIZE(right);
8982 /* hack hack! see if this the FSR. If so don't load W */
8983 if(AOP_TYPE(right) != AOP_ACC) {
8986 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
8987 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8989 if(AOP_SIZE(result) > 1) {
8990 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8991 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
8992 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8997 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
8999 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9000 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9004 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9005 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9008 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9015 if(aopIdx(AOP(result),0) != 4) {
9017 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9021 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9026 /* so dptr know contains the address */
9029 /* if bit then unpack */
9030 if (IS_BITVAR(retype))
9031 genPackBits(retype,right,"dptr",GPOINTER);
9033 size = AOP_SIZE(right);
9036 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9040 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9041 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9043 if (AOP_TYPE(right) == AOP_LIT)
9044 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9046 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9048 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9055 pic16_freeAsmop(right,NULL,ic,TRUE);
9056 pic16_freeAsmop(result,NULL,ic,TRUE);
9059 /*-----------------------------------------------------------------*/
9060 /* genPointerSet - stores the value into a pointer location */
9061 /*-----------------------------------------------------------------*/
9062 static void genPointerSet (iCode *ic)
9064 operand *right, *result ;
9065 sym_link *type, *etype;
9068 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9070 right = IC_RIGHT(ic);
9071 result = IC_RESULT(ic) ;
9073 /* depending on the type of pointer we need to
9074 move it to the correct pointer register */
9075 type = operandType(result);
9076 etype = getSpec(type);
9077 /* if left is of type of pointer then it is simple */
9078 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9079 p_type = DCL_TYPE(type);
9082 /* we have to go by the storage class */
9083 p_type = PTR_TYPE(SPEC_OCLS(etype));
9085 /* if (SPEC_OCLS(etype)->codesp ) { */
9086 /* p_type = CPOINTER ; */
9089 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9090 /* p_type = FPOINTER ; */
9092 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9093 /* p_type = PPOINTER ; */
9095 /* if (SPEC_OCLS(etype) == idata ) */
9096 /* p_type = IPOINTER ; */
9098 /* p_type = POINTER ; */
9101 /* now that we have the pointer type we assign
9102 the pointer values */
9107 genNearPointerSet (right,result,ic);
9111 genPagedPointerSet (right,result,ic);
9115 genFarPointerSet (right,result,ic);
9119 genGenPointerSet (right,result,ic);
9123 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9124 "genPointerSet: illegal pointer type");
9128 /*-----------------------------------------------------------------*/
9129 /* genIfx - generate code for Ifx statement */
9130 /*-----------------------------------------------------------------*/
9131 static void genIfx (iCode *ic, iCode *popIc)
9133 operand *cond = IC_COND(ic);
9136 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9138 pic16_aopOp(cond,ic,FALSE);
9140 /* get the value into acc */
9141 if (AOP_TYPE(cond) != AOP_CRY)
9142 pic16_toBoolean(cond);
9145 /* the result is now in the accumulator */
9146 pic16_freeAsmop(cond,NULL,ic,TRUE);
9148 /* if there was something to be popped then do it */
9152 /* if the condition is a bit variable */
9153 if (isbit && IS_ITEMP(cond) &&
9155 genIfxJump(ic,SPIL_LOC(cond)->rname);
9156 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9159 if (isbit && !IS_ITEMP(cond))
9160 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9168 /*-----------------------------------------------------------------*/
9169 /* genAddrOf - generates code for address of */
9170 /*-----------------------------------------------------------------*/
9171 static void genAddrOf (iCode *ic)
9173 operand *right, *result, *left;
9176 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9179 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9181 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9182 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9183 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9185 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9187 size = AOP_SIZE(IC_RESULT(ic));
9191 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9192 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9196 pic16_freeAsmop(left,NULL,ic,FALSE);
9197 pic16_freeAsmop(result,NULL,ic,TRUE);
9202 /*-----------------------------------------------------------------*/
9203 /* genFarFarAssign - assignment when both are in far space */
9204 /*-----------------------------------------------------------------*/
9205 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9207 int size = AOP_SIZE(right);
9210 /* first push the right side on to the stack */
9212 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9214 pic16_emitcode ("push","acc");
9217 pic16_freeAsmop(right,NULL,ic,FALSE);
9218 /* now assign DPTR to result */
9219 pic16_aopOp(result,ic,FALSE);
9220 size = AOP_SIZE(result);
9222 pic16_emitcode ("pop","acc");
9223 pic16_aopPut(AOP(result),"a",--offset);
9225 pic16_freeAsmop(result,NULL,ic,FALSE);
9230 /*-----------------------------------------------------------------*/
9231 /* genAssign - generate code for assignment */
9232 /*-----------------------------------------------------------------*/
9233 static void genAssign (iCode *ic)
9235 operand *result, *right;
9236 int size, offset,know_W;
9237 unsigned long lit = 0L;
9239 result = IC_RESULT(ic);
9240 right = IC_RIGHT(ic) ;
9242 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9244 /* if they are the same */
9245 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9248 pic16_aopOp(right,ic,FALSE);
9249 pic16_aopOp(result,ic,TRUE);
9251 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9253 /* if they are the same registers */
9254 if (pic16_sameRegs(AOP(right),AOP(result)))
9257 /* if the result is a bit */
9258 if (AOP_TYPE(result) == AOP_CRY) {
9260 /* if the right size is a literal then
9261 we know what the value is */
9262 if (AOP_TYPE(right) == AOP_LIT) {
9264 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9265 pic16_popGet(AOP(result),0));
9267 if (((int) operandLitValue(right)))
9268 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9269 AOP(result)->aopu.aop_dir,
9270 AOP(result)->aopu.aop_dir);
9272 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9273 AOP(result)->aopu.aop_dir,
9274 AOP(result)->aopu.aop_dir);
9278 /* the right is also a bit variable */
9279 if (AOP_TYPE(right) == AOP_CRY) {
9280 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9281 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9282 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9284 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9285 AOP(result)->aopu.aop_dir,
9286 AOP(result)->aopu.aop_dir);
9287 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9288 AOP(right)->aopu.aop_dir,
9289 AOP(right)->aopu.aop_dir);
9290 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9291 AOP(result)->aopu.aop_dir,
9292 AOP(result)->aopu.aop_dir);
9297 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9298 pic16_toBoolean(right);
9300 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9301 //pic16_aopPut(AOP(result),"a",0);
9305 /* bit variables done */
9307 size = AOP_SIZE(result);
9309 if(AOP_TYPE(right) == AOP_LIT)
9310 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9312 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9313 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9314 if(aopIdx(AOP(result),0) == 4) {
9315 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9316 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9317 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9320 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9325 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9326 if(AOP_TYPE(right) == AOP_LIT) {
9328 if(know_W != (lit&0xff))
9329 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9331 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9333 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9337 } else if (AOP_TYPE(right) == AOP_CRY) {
9338 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9340 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9341 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9344 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9345 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9346 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9354 pic16_freeAsmop (right,NULL,ic,FALSE);
9355 pic16_freeAsmop (result,NULL,ic,TRUE);
9358 /*-----------------------------------------------------------------*/
9359 /* genJumpTab - genrates code for jump table */
9360 /*-----------------------------------------------------------------*/
9361 static void genJumpTab (iCode *ic)
9366 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9368 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9369 /* get the condition into accumulator */
9370 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9372 /* multiply by three */
9373 pic16_emitcode("add","a,acc");
9374 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9376 jtab = newiTempLabel(NULL);
9377 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9378 pic16_emitcode("jmp","@a+dptr");
9379 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9381 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9382 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9384 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9385 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9386 pic16_emitpLabel(jtab->key);
9388 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9390 /* now generate the jump labels */
9391 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9392 jtab = setNextItem(IC_JTLABELS(ic))) {
9393 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9394 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9400 /*-----------------------------------------------------------------*/
9401 /* genMixedOperation - gen code for operators between mixed types */
9402 /*-----------------------------------------------------------------*/
9404 TSD - Written for the PIC port - but this unfortunately is buggy.
9405 This routine is good in that it is able to efficiently promote
9406 types to different (larger) sizes. Unfortunately, the temporary
9407 variables that are optimized out by this routine are sometimes
9408 used in other places. So until I know how to really parse the
9409 iCode tree, I'm going to not be using this routine :(.
9411 static int genMixedOperation (iCode *ic)
9414 operand *result = IC_RESULT(ic);
9415 sym_link *ctype = operandType(IC_LEFT(ic));
9416 operand *right = IC_RIGHT(ic);
9422 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9424 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9430 nextright = IC_RIGHT(nextic);
9431 nextleft = IC_LEFT(nextic);
9432 nextresult = IC_RESULT(nextic);
9434 pic16_aopOp(right,ic,FALSE);
9435 pic16_aopOp(result,ic,FALSE);
9436 pic16_aopOp(nextright, nextic, FALSE);
9437 pic16_aopOp(nextleft, nextic, FALSE);
9438 pic16_aopOp(nextresult, nextic, FALSE);
9440 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9446 pic16_emitcode(";remove right +","");
9448 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9454 pic16_emitcode(";remove left +","");
9458 big = AOP_SIZE(nextleft);
9459 small = AOP_SIZE(nextright);
9461 switch(nextic->op) {
9464 pic16_emitcode(";optimize a +","");
9465 /* if unsigned or not an integral type */
9466 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9467 pic16_emitcode(";add a bit to something","");
9470 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9472 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9473 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9474 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9476 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9484 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9485 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9486 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9489 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9491 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9492 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9493 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9494 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9495 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9498 pic16_emitcode("rlf","known_zero,w");
9505 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9506 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9507 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9509 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9519 pic16_freeAsmop(right,NULL,ic,TRUE);
9520 pic16_freeAsmop(result,NULL,ic,TRUE);
9521 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9522 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9524 nextic->generated = 1;
9531 /*-----------------------------------------------------------------*/
9532 /* genCast - gen code for casting */
9533 /*-----------------------------------------------------------------*/
9534 static void genCast (iCode *ic)
9536 operand *result = IC_RESULT(ic);
9537 sym_link *ctype = operandType(IC_LEFT(ic));
9538 sym_link *rtype = operandType(IC_RIGHT(ic));
9539 operand *right = IC_RIGHT(ic);
9542 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9543 /* if they are equivalent then do nothing */
9544 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9547 pic16_aopOp(right,ic,FALSE) ;
9548 pic16_aopOp(result,ic,FALSE);
9550 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9552 /* if the result is a bit */
9553 if (AOP_TYPE(result) == AOP_CRY) {
9554 /* if the right size is a literal then
9555 we know what the value is */
9556 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9557 if (AOP_TYPE(right) == AOP_LIT) {
9559 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9560 pic16_popGet(AOP(result),0));
9562 if (((int) operandLitValue(right)))
9563 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9564 AOP(result)->aopu.aop_dir,
9565 AOP(result)->aopu.aop_dir);
9567 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9568 AOP(result)->aopu.aop_dir,
9569 AOP(result)->aopu.aop_dir);
9574 /* the right is also a bit variable */
9575 if (AOP_TYPE(right) == AOP_CRY) {
9578 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9580 pic16_emitcode("clrc","");
9581 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9582 AOP(right)->aopu.aop_dir,
9583 AOP(right)->aopu.aop_dir);
9584 pic16_aopPut(AOP(result),"c",0);
9589 if (AOP_TYPE(right) == AOP_REG) {
9590 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9591 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9592 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9594 pic16_toBoolean(right);
9595 pic16_aopPut(AOP(result),"a",0);
9599 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9601 size = AOP_SIZE(result);
9603 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9605 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9606 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9607 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9610 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9615 /* if they are the same size : or less */
9616 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9618 /* if they are in the same place */
9619 if (pic16_sameRegs(AOP(right),AOP(result)))
9622 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9623 if (IS_PTR_CONST(rtype))
9624 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9625 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9626 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9628 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9629 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9630 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9631 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9632 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9633 if(AOP_SIZE(result) <2)
9634 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9638 /* if they in different places then copy */
9639 size = AOP_SIZE(result);
9642 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9643 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9645 //pic16_aopPut(AOP(result),
9646 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9656 /* if the result is of type pointer */
9657 if (IS_PTR(ctype)) {
9660 sym_link *type = operandType(right);
9661 sym_link *etype = getSpec(type);
9662 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9664 /* pointer to generic pointer */
9665 if (IS_GENPTR(ctype)) {
9669 p_type = DCL_TYPE(type);
9671 /* we have to go by the storage class */
9672 p_type = PTR_TYPE(SPEC_OCLS(etype));
9674 /* if (SPEC_OCLS(etype)->codesp ) */
9675 /* p_type = CPOINTER ; */
9677 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9678 /* p_type = FPOINTER ; */
9680 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9681 /* p_type = PPOINTER; */
9683 /* if (SPEC_OCLS(etype) == idata ) */
9684 /* p_type = IPOINTER ; */
9686 /* p_type = POINTER ; */
9689 /* the first two bytes are known */
9690 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9691 size = GPTRSIZE - 1;
9694 if(offset < AOP_SIZE(right)) {
9695 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9696 if ((AOP_TYPE(right) == AOP_PCODE) &&
9697 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9698 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9699 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9701 pic16_aopPut(AOP(result),
9702 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9706 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9709 /* the last byte depending on type */
9713 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9716 pic16_emitcode(";BUG!? ","%d",__LINE__);
9720 pic16_emitcode(";BUG!? ","%d",__LINE__);
9724 pic16_emitcode(";BUG!? ","%d",__LINE__);
9729 /* this should never happen */
9730 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9731 "got unknown pointer type");
9734 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9738 /* just copy the pointers */
9739 size = AOP_SIZE(result);
9742 pic16_aopPut(AOP(result),
9743 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9752 /* so we now know that the size of destination is greater
9753 than the size of the source.
9754 Now, if the next iCode is an operator then we might be
9755 able to optimize the operation without performing a cast.
9757 if(genMixedOperation(ic))
9760 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9762 /* we move to result for the size of source */
9763 size = AOP_SIZE(right);
9766 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9767 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9771 /* now depending on the sign of the destination */
9772 size = AOP_SIZE(result) - AOP_SIZE(right);
9773 /* if unsigned or not an integral type */
9774 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9776 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9778 /* we need to extend the sign :{ */
9781 /* Save one instruction of casting char to int */
9782 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9783 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9784 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
9786 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9789 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9791 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9793 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9796 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
9801 pic16_freeAsmop(right,NULL,ic,TRUE);
9802 pic16_freeAsmop(result,NULL,ic,TRUE);
9806 /*-----------------------------------------------------------------*/
9807 /* genDjnz - generate decrement & jump if not zero instrucion */
9808 /*-----------------------------------------------------------------*/
9809 static int genDjnz (iCode *ic, iCode *ifx)
9812 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9817 /* if the if condition has a false label
9818 then we cannot save */
9822 /* if the minus is not of the form
9824 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9825 !IS_OP_LITERAL(IC_RIGHT(ic)))
9828 if (operandLitValue(IC_RIGHT(ic)) != 1)
9831 /* if the size of this greater than one then no
9833 if (getSize(operandType(IC_RESULT(ic))) > 1)
9836 /* otherwise we can save BIG */
9837 lbl = newiTempLabel(NULL);
9838 lbl1= newiTempLabel(NULL);
9840 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9842 if (IS_AOP_PREG(IC_RESULT(ic))) {
9843 pic16_emitcode("dec","%s",
9844 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9845 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9846 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9850 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9851 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9853 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9854 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9857 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9858 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9859 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9860 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9863 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9868 /*-----------------------------------------------------------------*/
9869 /* genReceive - generate code for a receive iCode */
9870 /*-----------------------------------------------------------------*/
9871 static void genReceive (iCode *ic)
9873 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9875 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9876 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9877 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9879 int size = getSize(operandType(IC_RESULT(ic)));
9880 int offset = pic16_fReturnSizePic - size;
9882 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9883 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9886 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9887 size = AOP_SIZE(IC_RESULT(ic));
9890 pic16_emitcode ("pop","acc");
9891 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9896 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9898 assignResultValue(IC_RESULT(ic));
9901 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9904 /*-----------------------------------------------------------------*/
9905 /* genpic16Code - generate code for pic16 based controllers */
9906 /*-----------------------------------------------------------------*/
9908 * At this point, ralloc.c has gone through the iCode and attempted
9909 * to optimize in a way suitable for a PIC. Now we've got to generate
9910 * PIC instructions that correspond to the iCode.
9912 * Once the instructions are generated, we'll pass through both the
9913 * peep hole optimizer and the pCode optimizer.
9914 *-----------------------------------------------------------------*/
9916 void genpic16Code (iCode *lic)
9921 lineHead = lineCurr = NULL;
9923 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9924 pic16_addpBlock(pb);
9927 /* if debug information required */
9928 if (options.debug && currFunc) {
9930 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9932 if (IS_STATIC(currFunc->etype)) {
9933 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9934 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9936 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9937 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
9944 for (ic = lic ; ic ; ic = ic->next ) {
9946 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
9947 // DEBUGpic16_emitcode("; VR", "");
9948 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
9949 if ( cln != ic->lineno ) {
9950 if ( options.debug ) {
9952 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
9953 FileBaseName(ic->filename),ic->lineno,
9954 ic->level,ic->block);
9958 pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9959 pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9960 printCLine(ic->filename, ic->lineno));
9962 pic16_addpCode2pBlock(pb,
9963 pic16_newpCodeCSource(ic->lineno,
9965 printCLine(ic->filename, ic->lineno)));
9969 /* if the result is marked as
9970 spilt and rematerializable or code for
9971 this has already been generated then
9973 if (resultRemat(ic) || ic->generated )
9976 /* depending on the operation */
9995 /* IPOP happens only when trying to restore a
9996 spilt live range, if there is an ifx statement
9997 following this pop then the if statement might
9998 be using some of the registers being popped which
9999 would destroy the contents of the register so
10000 we need to check for this condition and handle it */
10002 ic->next->op == IFX &&
10003 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10004 genIfx (ic->next,ic);
10022 genEndFunction (ic);
10038 pic16_genPlus (ic) ;
10042 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10043 pic16_genMinus (ic);
10059 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10063 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10070 /* note these two are xlated by algebraic equivalence
10071 during parsing SDCC.y */
10072 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10073 "got '>=' or '<=' shouldn't have come here");
10077 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10089 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10093 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10097 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10121 genRightShift (ic);
10124 case GET_VALUE_AT_ADDRESS:
10129 if (POINTER_SET(ic))
10156 addSet(&_G.sendSet,ic);
10165 /* now we are ready to call the
10166 peep hole optimizer */
10167 if (!options.nopeep) {
10168 peepHole (&lineHead);
10170 /* now do the actual printing */
10171 printLine (lineHead,codeOutFile);
10174 DFPRINTF((stderr,"printing pBlock\n\n"));
10175 pic16_printpBlock(stdout,pb);