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 if(pic16_debug_verbose)
268 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
274 /*-----------------------------------------------------------------*/
275 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
276 /*-----------------------------------------------------------------*/
277 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
279 bool r0iu = FALSE , r1iu = FALSE;
280 bool r0ou = FALSE , r1ou = FALSE;
282 /* the logic: if r0 & r1 used in the instruction
283 then we are in trouble otherwise */
285 /* first check if r0 & r1 are used by this
286 instruction, in which case we are in trouble */
287 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
288 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
293 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
294 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
296 /* if no usage of r0 then return it */
297 if (!r0iu && !r0ou) {
298 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
299 (*aopp)->type = AOP_R0;
301 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
304 /* if no usage of r1 then return it */
305 if (!r1iu && !r1ou) {
306 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
307 (*aopp)->type = AOP_R1;
309 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
312 /* now we know they both have usage */
313 /* if r0 not used in this instruction */
315 /* push it if not already pushed */
317 //pic16_emitcode ("push","%s",
318 // pic16_regWithIdx(R0_IDX)->dname);
322 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
323 (*aopp)->type = AOP_R0;
325 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
328 /* if r1 not used then */
331 /* push it if not already pushed */
333 //pic16_emitcode ("push","%s",
334 // pic16_regWithIdx(R1_IDX)->dname);
338 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
339 (*aopp)->type = AOP_R1;
340 return pic16_regWithIdx(R1_IDX);
344 /* I said end of world but not quite end of world yet */
345 /* if this is a result then we can push it on the stack*/
347 (*aopp)->type = AOP_STK;
351 /* other wise this is true end of the world */
352 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
353 "getFreePtr should never reach here");
357 /*-----------------------------------------------------------------*/
358 /* newAsmop - creates a new asmOp */
359 /*-----------------------------------------------------------------*/
360 static asmop *newAsmop (short type)
364 aop = Safe_calloc(1,sizeof(asmop));
369 static void genSetDPTR(int n)
373 pic16_emitcode(";", "Select standard DPTR");
374 pic16_emitcode("mov", "dps, #0x00");
378 pic16_emitcode(";", "Select alternate DPTR");
379 pic16_emitcode("mov", "dps, #0x01");
383 /*-----------------------------------------------------------------*/
384 /* resolveIfx - converts an iCode ifx into a form more useful for */
385 /* generating code */
386 /*-----------------------------------------------------------------*/
387 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
392 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
394 resIfx->condition = 1; /* assume that the ifx is true */
395 resIfx->generated = 0; /* indicate that the ifx has not been used */
398 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
400 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
401 __FUNCTION__,__LINE__,resIfx->lbl->key);
405 resIfx->lbl = IC_TRUE(ifx);
407 resIfx->lbl = IC_FALSE(ifx);
408 resIfx->condition = 0;
412 DEBUGpic16_emitcode("; ***","ifx true is non-null");
414 DEBUGpic16_emitcode("; ***","ifx false is non-null");
418 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
421 /*-----------------------------------------------------------------*/
422 /* pointerCode - returns the code for a pointer type */
423 /*-----------------------------------------------------------------*/
424 static int pointerCode (sym_link *etype)
427 return PTR_TYPE(SPEC_OCLS(etype));
431 /*-----------------------------------------------------------------*/
432 /* aopForSym - for a true symbol */
433 /*-----------------------------------------------------------------*/
434 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
437 memmap *space= SPEC_OCLS(sym->etype);
439 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
440 /* if already has one */
444 /* assign depending on the storage class */
445 /* if it is on the stack or indirectly addressable */
446 /* space we need to assign either r0 or r1 to it */
447 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
448 sym->aop = aop = newAsmop(0);
449 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
450 aop->size = getSize(sym->type);
452 /* now assign the address of the variable to
453 the pointer register */
454 if (aop->type != AOP_STK) {
458 pic16_emitcode("push","acc");
460 pic16_emitcode("mov","a,_bp");
461 pic16_emitcode("add","a,#0x%02x",
463 ((char)(sym->stack - _G.nRegsSaved )) :
464 ((char)sym->stack)) & 0xff);
465 pic16_emitcode("mov","%s,a",
466 aop->aopu.aop_ptr->name);
469 pic16_emitcode("pop","acc");
471 pic16_emitcode("mov","%s,#%s",
472 aop->aopu.aop_ptr->name,
474 aop->paged = space->paged;
476 aop->aopu.aop_stk = sym->stack;
480 if (sym->onStack && options.stack10bit)
482 /* It's on the 10 bit stack, which is located in
486 //DEBUGpic16_emitcode(";","%d",__LINE__);
489 pic16_emitcode("push","acc");
491 pic16_emitcode("mov","a,_bp");
492 pic16_emitcode("add","a,#0x%02x",
494 ((char)(sym->stack - _G.nRegsSaved )) :
495 ((char)sym->stack)) & 0xff);
498 pic16_emitcode ("mov","dpx1,#0x40");
499 pic16_emitcode ("mov","dph1,#0x00");
500 pic16_emitcode ("mov","dpl1, a");
504 pic16_emitcode("pop","acc");
506 sym->aop = aop = newAsmop(AOP_DPTR2);
507 aop->size = getSize(sym->type);
511 //DEBUGpic16_emitcode(";","%d",__LINE__);
512 /* if in bit space */
513 if (IN_BITSPACE(space)) {
514 sym->aop = aop = newAsmop (AOP_CRY);
515 aop->aopu.aop_dir = sym->rname ;
516 aop->size = getSize(sym->type);
517 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
520 /* if it is in direct space */
521 if (IN_DIRSPACE(space)) {
522 sym->aop = aop = newAsmop (AOP_DIR);
523 aop->aopu.aop_dir = sym->rname ;
524 aop->size = getSize(sym->type);
525 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
529 /* special case for a function */
530 if (IS_FUNC(sym->type)) {
531 sym->aop = aop = newAsmop(AOP_IMMD);
532 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
533 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
534 strcpy(aop->aopu.aop_immd,sym->rname);
535 aop->size = FPTRSIZE;
536 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
541 /* only remaining is far space */
542 /* in which case DPTR gets the address */
543 sym->aop = aop = newAsmop(AOP_PCODE);
545 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
546 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
547 PCOI(aop->aopu.pcop)->index = 0;
549 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
550 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
552 pic16_allocDirReg (IC_LEFT(ic));
554 aop->size = FPTRSIZE;
556 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
557 sym->aop = aop = newAsmop(AOP_DPTR);
558 pic16_emitcode ("mov","dptr,#%s", sym->rname);
559 aop->size = getSize(sym->type);
561 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
564 /* if it is in code space */
565 if (IN_CODESPACE(space))
571 /*-----------------------------------------------------------------*/
572 /* aopForRemat - rematerialzes an object */
573 /*-----------------------------------------------------------------*/
574 static asmop *aopForRemat (operand *op) // x symbol *sym)
576 symbol *sym = OP_SYMBOL(op);
578 asmop *aop = newAsmop(AOP_PCODE);
582 ic = sym->rematiCode;
584 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
585 if(IS_OP_POINTER(op)) {
586 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
590 val += (int) operandLitValue(IC_RIGHT(ic));
591 } else if (ic->op == '-') {
592 val -= (int) operandLitValue(IC_RIGHT(ic));
596 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
599 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
600 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
601 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
602 PCOI(aop->aopu.pcop)->index = val;
604 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
605 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
606 val, IS_PTR_CONST(operandType(op)));
608 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
610 pic16_allocDirReg (IC_LEFT(ic));
615 static int aopIdx (asmop *aop, int offset)
620 if(aop->type != AOP_REG)
623 return aop->aopu.aop_reg[offset]->rIdx;
626 /*-----------------------------------------------------------------*/
627 /* regsInCommon - two operands have some registers in common */
628 /*-----------------------------------------------------------------*/
629 static bool regsInCommon (operand *op1, operand *op2)
634 /* if they have registers in common */
635 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
638 sym1 = OP_SYMBOL(op1);
639 sym2 = OP_SYMBOL(op2);
641 if (sym1->nRegs == 0 || sym2->nRegs == 0)
644 for (i = 0 ; i < sym1->nRegs ; i++) {
649 for (j = 0 ; j < sym2->nRegs ;j++ ) {
653 if (sym2->regs[j] == sym1->regs[i])
661 /*-----------------------------------------------------------------*/
662 /* operandsEqu - equivalent */
663 /*-----------------------------------------------------------------*/
664 static bool operandsEqu ( operand *op1, operand *op2)
668 /* if they not symbols */
669 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
672 sym1 = OP_SYMBOL(op1);
673 sym2 = OP_SYMBOL(op2);
675 /* if both are itemps & one is spilt
676 and the other is not then false */
677 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
678 sym1->isspilt != sym2->isspilt )
681 /* if they are the same */
685 if (strcmp(sym1->rname,sym2->rname) == 0)
689 /* if left is a tmp & right is not */
693 (sym1->usl.spillLoc == sym2))
700 (sym2->usl.spillLoc == sym1))
706 /*-----------------------------------------------------------------*/
707 /* pic16_sameRegs - two asmops have the same registers */
708 /*-----------------------------------------------------------------*/
709 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
716 if (aop1->type != AOP_REG ||
717 aop2->type != AOP_REG )
720 if (aop1->size != aop2->size )
723 for (i = 0 ; i < aop1->size ; i++ )
724 if (aop1->aopu.aop_reg[i] !=
725 aop2->aopu.aop_reg[i] )
731 /*-----------------------------------------------------------------*/
732 /* pic16_aopOp - allocates an asmop for an operand : */
733 /*-----------------------------------------------------------------*/
734 void pic16_aopOp (operand *op, iCode *ic, bool result)
743 // DEBUGpic16_emitcode(";","%d",__LINE__);
744 /* if this a literal */
745 if (IS_OP_LITERAL(op)) {
746 op->aop = aop = newAsmop(AOP_LIT);
747 aop->aopu.aop_lit = op->operand.valOperand;
748 aop->size = getSize(operandType(op));
753 sym_link *type = operandType(op);
754 if(IS_PTR_CONST(type))
755 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
758 /* if already has a asmop then continue */
762 /* if the underlying symbol has a aop */
763 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
764 DEBUGpic16_emitcode(";","%d",__LINE__);
765 op->aop = OP_SYMBOL(op)->aop;
769 /* if this is a true symbol */
770 if (IS_TRUE_SYMOP(op)) {
771 //DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
772 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
776 /* this is a temporary : this has
782 e) can be a return use only */
787 /* if the type is a conditional */
788 if (sym->regType == REG_CND) {
789 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
794 /* if it is spilt then two situations
796 b) has a spill location */
797 if (sym->isspilt || sym->nRegs == 0) {
799 DEBUGpic16_emitcode(";","%d",__LINE__);
800 /* rematerialize it NOW */
803 sym->aop = op->aop = aop =
805 aop->size = getSize(sym->type);
806 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
812 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
813 aop->size = getSize(sym->type);
814 for ( i = 0 ; i < 2 ; i++ )
815 aop->aopu.aop_str[i] = accUse[i];
816 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
822 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
823 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
824 //pic16_allocDirReg (IC_LEFT(ic));
825 aop->size = getSize(sym->type);
830 aop = op->aop = sym->aop = newAsmop(AOP_STR);
831 aop->size = getSize(sym->type);
832 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
833 aop->aopu.aop_str[i] = fReturn[i];
835 DEBUGpic16_emitcode(";","%d",__LINE__);
839 /* else spill location */
840 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
841 /* force a new aop if sizes differ */
842 sym->usl.spillLoc->aop = NULL;
844 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
845 __FUNCTION__,__LINE__,
846 sym->usl.spillLoc->rname,
847 sym->rname, sym->usl.spillLoc->offset);
849 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
850 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
851 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
853 sym->usl.spillLoc->offset);
854 aop->size = getSize(sym->type);
860 sym_link *type = operandType(op);
861 if(IS_PTR_CONST(type))
862 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
865 /* must be in a register */
866 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
867 sym->aop = op->aop = aop = newAsmop(AOP_REG);
868 aop->size = sym->nRegs;
869 for ( i = 0 ; i < sym->nRegs ;i++)
870 aop->aopu.aop_reg[i] = sym->regs[i];
873 /*-----------------------------------------------------------------*/
874 /* pic16_freeAsmop - free up the asmop given to an operand */
875 /*----------------------------------------------------------------*/
876 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
893 /* depending on the asmop type only three cases need work AOP_RO
894 , AOP_R1 && AOP_STK */
900 pic16_emitcode ("pop","ar0");
904 bitVectUnSetBit(ic->rUsed,R0_IDX);
910 pic16_emitcode ("pop","ar1");
914 bitVectUnSetBit(ic->rUsed,R1_IDX);
920 int stk = aop->aopu.aop_stk + aop->size;
921 bitVectUnSetBit(ic->rUsed,R0_IDX);
922 bitVectUnSetBit(ic->rUsed,R1_IDX);
924 getFreePtr(ic,&aop,FALSE);
926 if (options.stack10bit)
928 /* I'm not sure what to do here yet... */
931 "*** Warning: probably generating bad code for "
932 "10 bit stack mode.\n");
936 pic16_emitcode ("mov","a,_bp");
937 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
938 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
940 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
944 pic16_emitcode("pop","acc");
945 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
947 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
950 pic16_freeAsmop(op,NULL,ic,TRUE);
952 pic16_emitcode("pop","ar0");
957 pic16_emitcode("pop","ar1");
965 /* all other cases just dealloc */
969 OP_SYMBOL(op)->aop = NULL;
970 /* if the symbol has a spill */
972 SPIL_LOC(op)->aop = NULL;
977 /*-----------------------------------------------------------------*/
978 /* pic16_aopGet - for fetching value of the aop */
979 /*-----------------------------------------------------------------*/
980 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
985 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
986 /* offset is greater than
988 if (offset > (aop->size - 1) &&
989 aop->type != AOP_LIT)
992 /* depending on type */
997 DEBUGpic16_emitcode(";","%d",__LINE__);
998 /* if we need to increment it */
999 while (offset > aop->coff) {
1000 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1004 while (offset < aop->coff) {
1005 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1009 aop->coff = offset ;
1011 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1012 return (dname ? "acc" : "a");
1014 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1015 rs = Safe_calloc(1,strlen(s)+1);
1021 DEBUGpic16_emitcode(";","%d",__LINE__);
1022 if (aop->type == AOP_DPTR2)
1027 while (offset > aop->coff) {
1028 pic16_emitcode ("inc","dptr");
1032 while (offset < aop->coff) {
1033 pic16_emitcode("lcall","__decdptr");
1039 pic16_emitcode("clr","a");
1040 pic16_emitcode("movc","a,@a+dptr");
1043 pic16_emitcode("movx","a,@dptr");
1046 if (aop->type == AOP_DPTR2)
1051 return (dname ? "acc" : "a");
1056 sprintf (s,"%s",aop->aopu.aop_immd);
1059 sprintf(s,"(%s >> %d)",
1064 aop->aopu.aop_immd);
1065 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1066 rs = Safe_calloc(1,strlen(s)+1);
1072 sprintf(s,"(%s + %d)",
1075 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1077 sprintf(s,"%s",aop->aopu.aop_dir);
1078 rs = Safe_calloc(1,strlen(s)+1);
1084 // return aop->aopu.aop_reg[offset]->dname;
1086 return aop->aopu.aop_reg[offset]->name;
1089 //pic16_emitcode(";","%d",__LINE__);
1090 return aop->aopu.aop_dir;
1093 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1094 return "AOP_accumulator_bug";
1097 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1098 rs = Safe_calloc(1,strlen(s)+1);
1103 aop->coff = offset ;
1104 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1107 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1109 return aop->aopu.aop_str[offset];
1113 pCodeOp *pcop = aop->aopu.pcop;
1114 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1116 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1117 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1118 sprintf(s,"%s", pcop->name);
1120 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1123 rs = Safe_calloc(1,strlen(s)+1);
1129 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1130 "aopget got unsupported aop->type");
1135 /*-----------------------------------------------------------------*/
1136 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1137 /*-----------------------------------------------------------------*/
1138 pCodeOp *pic16_popGetTempReg(void)
1143 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1144 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1145 PCOR(pcop)->r->wasUsed=1;
1146 PCOR(pcop)->r->isFree=0;
1152 /*-----------------------------------------------------------------*/
1153 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1154 /*-----------------------------------------------------------------*/
1155 void pic16_popReleaseTempReg(pCodeOp *pcop)
1158 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1159 PCOR(pcop)->r->isFree = 1;
1162 /*-----------------------------------------------------------------*/
1163 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *pic16_popGetLabel(unsigned int key)
1168 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1173 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1176 /*-----------------------------------------------------------------*/
1177 /* pic16_popCopyReg - copy a pcode operator */
1178 /*-----------------------------------------------------------------*/
1179 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1183 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1184 pcor->pcop.type = pc->pcop.type;
1186 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1187 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1189 pcor->pcop.name = NULL;
1192 pcor->rIdx = pc->rIdx;
1195 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1199 /*-----------------------------------------------------------------*/
1200 /* pic16_popGet - asm operator to pcode operator conversion */
1201 /*-----------------------------------------------------------------*/
1202 pCodeOp *pic16_popGetLit(unsigned int lit)
1205 return pic16_newpCodeOpLit(lit);
1209 /*-----------------------------------------------------------------*/
1210 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1211 /*-----------------------------------------------------------------*/
1212 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1215 return pic16_newpCodeOpImmd(name, offset,index, 0);
1219 /*-----------------------------------------------------------------*/
1220 /* pic16_popGet - asm operator to pcode operator conversion */
1221 /*-----------------------------------------------------------------*/
1222 pCodeOp *pic16_popGetWithString(char *str)
1228 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1232 pcop = pic16_newpCodeOp(str,PO_STR);
1237 /*-----------------------------------------------------------------*/
1238 /* popRegFromString - */
1239 /*-----------------------------------------------------------------*/
1240 static pCodeOp *popRegFromString(char *str, int size, int offset)
1243 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1244 pcop->type = PO_DIR;
1246 DEBUGpic16_emitcode(";","%d",__LINE__);
1251 pcop->name = Safe_calloc(1,strlen(str)+1);
1252 strcpy(pcop->name,str);
1254 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1256 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1257 if(PCOR(pcop)->r == NULL) {
1258 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1259 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1260 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1262 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1264 PCOR(pcop)->instance = offset;
1269 static pCodeOp *popRegFromIdx(int rIdx)
1273 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1274 __FUNCTION__,__LINE__,rIdx);
1276 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1278 PCOR(pcop)->rIdx = rIdx;
1279 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1280 PCOR(pcop)->r->isFree = 0;
1281 PCOR(pcop)->r->wasUsed = 1;
1283 pcop->type = PCOR(pcop)->r->pc_type;
1288 /*-----------------------------------------------------------------*/
1289 /* pic16_popGet - asm operator to pcode operator conversion */
1290 /*-----------------------------------------------------------------*/
1291 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1293 //char *s = buffer ;
1298 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1299 /* offset is greater than
1302 if (offset > (aop->size - 1) &&
1303 aop->type != AOP_LIT)
1304 return NULL; //zero;
1306 /* depending on type */
1307 switch (aop->type) {
1314 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1318 DEBUGpic16_emitcode(";","%d",__LINE__);
1319 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1322 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1324 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1325 pcop->type = PO_DIR;
1329 sprintf(s,"(%s + %d)",
1333 sprintf(s,"%s",aop->aopu.aop_dir);
1334 pcop->name = Safe_calloc(1,strlen(s)+1);
1335 strcpy(pcop->name,s);
1337 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1338 strcpy(pcop->name,aop->aopu.aop_dir);
1339 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1340 if(PCOR(pcop)->r == NULL) {
1341 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1342 PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1343 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1345 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1347 PCOR(pcop)->instance = offset;
1354 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1356 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1357 PCOR(pcop)->rIdx = rIdx;
1358 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1359 PCOR(pcop)->r->wasUsed=1;
1360 PCOR(pcop)->r->isFree=0;
1362 PCOR(pcop)->instance = offset;
1363 pcop->type = PCOR(pcop)->r->pc_type;
1364 //rs = aop->aopu.aop_reg[offset]->name;
1365 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1370 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1371 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1372 //if(PCOR(pcop)->r == NULL)
1373 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1377 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1380 DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1381 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1383 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1384 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1385 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1386 pcop->type = PCOR(pcop)->r->pc_type;
1387 pcop->name = PCOR(pcop)->r->name;
1393 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1395 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1396 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1397 PCOI(pcop)->offset = offset;
1401 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1402 "pic16_popGet got unsupported aop->type");
1405 /*-----------------------------------------------------------------*/
1406 /* pic16_aopPut - puts a string for a aop */
1407 /*-----------------------------------------------------------------*/
1408 void pic16_aopPut (asmop *aop, char *s, int offset)
1413 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1415 if (aop->size && offset > ( aop->size - 1)) {
1416 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1417 "pic16_aopPut got offset > aop->size");
1421 /* will assign value to value */
1422 /* depending on where it is ofcourse */
1423 switch (aop->type) {
1426 sprintf(d,"(%s + %d)",
1427 aop->aopu.aop_dir,offset);
1428 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1431 sprintf(d,"%s",aop->aopu.aop_dir);
1434 DEBUGpic16_emitcode(";","%d",__LINE__);
1436 pic16_emitcode("movf","%s,w",s);
1437 pic16_emitcode("movwf","%s",d);
1440 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1441 if(offset >= aop->size) {
1442 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1445 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1448 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1455 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1456 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1459 strcmp(s,"r0") == 0 ||
1460 strcmp(s,"r1") == 0 ||
1461 strcmp(s,"r2") == 0 ||
1462 strcmp(s,"r3") == 0 ||
1463 strcmp(s,"r4") == 0 ||
1464 strcmp(s,"r5") == 0 ||
1465 strcmp(s,"r6") == 0 ||
1466 strcmp(s,"r7") == 0 )
1467 pic16_emitcode("mov","%s,%s ; %d",
1468 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1472 if(strcmp(s,"W")==0 )
1473 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1475 pic16_emitcode("movwf","%s",
1476 aop->aopu.aop_reg[offset]->name);
1478 if(strcmp(s,zero)==0) {
1479 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1481 } else if(strcmp(s,"W")==0) {
1482 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1483 pcop->type = PO_GPR_REGISTER;
1485 PCOR(pcop)->rIdx = -1;
1486 PCOR(pcop)->r = NULL;
1488 DEBUGpic16_emitcode(";","%d",__LINE__);
1489 pcop->name = Safe_strdup(s);
1490 pic16_emitpcode(POC_MOVFW,pcop);
1491 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1492 } else if(strcmp(s,one)==0) {
1493 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1494 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1496 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1504 if (aop->type == AOP_DPTR2)
1510 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1511 "pic16_aopPut writting to code space");
1515 while (offset > aop->coff) {
1517 pic16_emitcode ("inc","dptr");
1520 while (offset < aop->coff) {
1522 pic16_emitcode("lcall","__decdptr");
1527 /* if not in accumulater */
1530 pic16_emitcode ("movx","@dptr,a");
1532 if (aop->type == AOP_DPTR2)
1540 while (offset > aop->coff) {
1542 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1544 while (offset < aop->coff) {
1546 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1552 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1557 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1559 if (strcmp(s,"r0") == 0 ||
1560 strcmp(s,"r1") == 0 ||
1561 strcmp(s,"r2") == 0 ||
1562 strcmp(s,"r3") == 0 ||
1563 strcmp(s,"r4") == 0 ||
1564 strcmp(s,"r5") == 0 ||
1565 strcmp(s,"r6") == 0 ||
1566 strcmp(s,"r7") == 0 ) {
1568 sprintf(buffer,"a%s",s);
1569 pic16_emitcode("mov","@%s,%s",
1570 aop->aopu.aop_ptr->name,buffer);
1572 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1577 if (strcmp(s,"a") == 0)
1578 pic16_emitcode("push","acc");
1580 pic16_emitcode("push","%s",s);
1585 /* if bit variable */
1586 if (!aop->aopu.aop_dir) {
1587 pic16_emitcode("clr","a");
1588 pic16_emitcode("rlc","a");
1591 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1594 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1597 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1599 lbl = newiTempLabel(NULL);
1601 if (strcmp(s,"a")) {
1604 pic16_emitcode("clr","c");
1605 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1606 pic16_emitcode("cpl","c");
1607 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1608 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1615 if (strcmp(aop->aopu.aop_str[offset],s))
1616 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1621 if (!offset && (strcmp(s,"acc") == 0))
1624 if (strcmp(aop->aopu.aop_str[offset],s))
1625 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1629 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1630 "pic16_aopPut got unsupported aop->type");
1636 /*-----------------------------------------------------------------*/
1637 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1638 /*-----------------------------------------------------------------*/
1639 static void mov2w (asmop *aop, int offset)
1645 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1647 if ( aop->type == AOP_PCODE ||
1648 aop->type == AOP_LIT )
1649 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1651 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1655 /*-----------------------------------------------------------------*/
1656 /* reAdjustPreg - points a register back to where it should */
1657 /*-----------------------------------------------------------------*/
1658 static void reAdjustPreg (asmop *aop)
1662 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1664 if ((size = aop->size) <= 1)
1667 switch (aop->type) {
1671 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1675 if (aop->type == AOP_DPTR2)
1681 pic16_emitcode("lcall","__decdptr");
1684 if (aop->type == AOP_DPTR2)
1694 /*-----------------------------------------------------------------*/
1695 /* genNotFloat - generates not for float operations */
1696 /*-----------------------------------------------------------------*/
1697 static void genNotFloat (operand *op, operand *res)
1703 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1704 /* we will put 127 in the first byte of
1706 pic16_aopPut(AOP(res),"#127",0);
1707 size = AOP_SIZE(op) - 1;
1710 l = pic16_aopGet(op->aop,offset++,FALSE,FALSE);
1714 pic16_emitcode("orl","a,%s",
1715 pic16_aopGet(op->aop,
1716 offset++,FALSE,FALSE));
1718 tlbl = newiTempLabel(NULL);
1720 tlbl = newiTempLabel(NULL);
1721 pic16_aopPut(res->aop,one,1);
1722 pic16_emitcode("jz","%05d_DS_",(tlbl->key+100));
1723 pic16_aopPut(res->aop,zero,1);
1724 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
1726 size = res->aop->size - 2;
1728 /* put zeros in the rest */
1730 pic16_aopPut(res->aop,zero,offset++);
1734 /*-----------------------------------------------------------------*/
1735 /* opIsGptr: returns non-zero if the passed operand is */
1736 /* a generic pointer type. */
1737 /*-----------------------------------------------------------------*/
1738 static int opIsGptr(operand *op)
1740 sym_link *type = operandType(op);
1742 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1743 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1751 /*-----------------------------------------------------------------*/
1752 /* pic16_getDataSize - get the operand data size */
1753 /*-----------------------------------------------------------------*/
1754 int pic16_getDataSize(operand *op)
1756 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1759 return AOP_SIZE(op);
1761 // tsd- in the pic port, the genptr size is 1, so this code here
1762 // fails. ( in the 8051 port, the size was 4).
1765 size = AOP_SIZE(op);
1766 if (size == GPTRSIZE)
1768 sym_link *type = operandType(op);
1769 if (IS_GENPTR(type))
1771 /* generic pointer; arithmetic operations
1772 * should ignore the high byte (pointer type).
1775 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1782 /*-----------------------------------------------------------------*/
1783 /* pic16_outAcc - output Acc */
1784 /*-----------------------------------------------------------------*/
1785 void pic16_outAcc(operand *result)
1788 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1789 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1792 size = pic16_getDataSize(result);
1794 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1797 /* unsigned or positive */
1799 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1804 /*-----------------------------------------------------------------*/
1805 /* pic16_outBitC - output a bit C */
1806 /*-----------------------------------------------------------------*/
1807 void pic16_outBitC(operand *result)
1810 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1811 /* if the result is bit */
1812 if (AOP_TYPE(result) == AOP_CRY)
1813 pic16_aopPut(AOP(result),"c",0);
1815 pic16_emitcode("clr","a ; %d", __LINE__);
1816 pic16_emitcode("rlc","a");
1817 pic16_outAcc(result);
1821 /*-----------------------------------------------------------------*/
1822 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1823 /*-----------------------------------------------------------------*/
1824 void pic16_toBoolean(operand *oper)
1826 int size = AOP_SIZE(oper) - 1;
1829 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1831 if ( AOP_TYPE(oper) != AOP_ACC) {
1832 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1835 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1840 /*-----------------------------------------------------------------*/
1841 /* genNot - generate code for ! operation */
1842 /*-----------------------------------------------------------------*/
1843 static void genNot (iCode *ic)
1846 sym_link *optype = operandType(IC_LEFT(ic));
1849 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1850 /* assign asmOps to operand & result */
1851 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1852 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1854 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1855 /* if in bit space then a special case */
1856 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1857 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1858 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1859 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1861 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1862 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1863 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1868 /* if type float then do float */
1869 if (IS_FLOAT(optype)) {
1870 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1874 size = AOP_SIZE(IC_RESULT(ic));
1876 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1877 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1878 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1881 pic16_toBoolean(IC_LEFT(ic));
1883 tlbl = newiTempLabel(NULL);
1884 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1885 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1886 pic16_outBitC(IC_RESULT(ic));
1889 /* release the aops */
1890 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1891 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1895 /*-----------------------------------------------------------------*/
1896 /* genCpl - generate code for complement */
1897 /*-----------------------------------------------------------------*/
1898 static void genCpl (iCode *ic)
1904 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1905 /* assign asmOps to operand & result */
1906 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1907 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1909 /* if both are in bit space then
1911 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1912 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1914 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1915 pic16_emitcode("cpl","c");
1916 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1920 size = AOP_SIZE(IC_RESULT(ic));
1922 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1924 pic16_emitcode("cpl","a");
1925 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1930 /* release the aops */
1931 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1932 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1935 /*-----------------------------------------------------------------*/
1936 /* genUminusFloat - unary minus for floating points */
1937 /*-----------------------------------------------------------------*/
1938 static void genUminusFloat(operand *op,operand *result)
1940 int size ,offset =0 ;
1943 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1944 /* for this we just need to flip the
1945 first it then copy the rest in place */
1946 size = AOP_SIZE(op) - 1;
1947 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1951 pic16_emitcode("cpl","acc.7");
1952 pic16_aopPut(AOP(result),"a",3);
1955 pic16_aopPut(AOP(result),
1956 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1962 /*-----------------------------------------------------------------*/
1963 /* genUminus - unary minus code generation */
1964 /*-----------------------------------------------------------------*/
1965 static void genUminus (iCode *ic)
1968 sym_link *optype, *rtype;
1971 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1973 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1974 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1976 /* if both in bit space then special
1978 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1979 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1981 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1982 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
1983 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1988 optype = operandType(IC_LEFT(ic));
1989 rtype = operandType(IC_RESULT(ic));
1991 /* if float then do float stuff */
1992 if (IS_FLOAT(optype)) {
1993 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1997 /* otherwise subtract from zero by taking the 2's complement */
1998 size = AOP_SIZE(IC_LEFT(ic));
2000 for(i=0; i<size; i++) {
2001 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2002 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2004 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2005 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2009 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2010 for(i=1; i<size; i++) {
2012 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2016 /* release the aops */
2017 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2018 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2021 /*-----------------------------------------------------------------*/
2022 /* saveRegisters - will look for a call and save the registers */
2023 /*-----------------------------------------------------------------*/
2024 static void saveRegisters(iCode *lic)
2031 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2033 for (ic = lic ; ic ; ic = ic->next)
2034 if (ic->op == CALL || ic->op == PCALL)
2038 fprintf(stderr,"found parameter push with no function call\n");
2042 /* if the registers have been saved already then
2044 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2047 /* find the registers in use at this time
2048 and push them away to safety */
2049 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2053 if (options.useXstack) {
2054 if (bitVectBitValue(rsave,R0_IDX))
2055 pic16_emitcode("mov","b,r0");
2056 pic16_emitcode("mov","r0,%s",spname);
2057 for (i = 0 ; i < pic16_nRegs ; i++) {
2058 if (bitVectBitValue(rsave,i)) {
2060 pic16_emitcode("mov","a,b");
2062 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2063 pic16_emitcode("movx","@r0,a");
2064 pic16_emitcode("inc","r0");
2067 pic16_emitcode("mov","%s,r0",spname);
2068 if (bitVectBitValue(rsave,R0_IDX))
2069 pic16_emitcode("mov","r0,b");
2071 //for (i = 0 ; i < pic16_nRegs ; i++) {
2072 // if (bitVectBitValue(rsave,i))
2073 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2076 dtype = operandType(IC_LEFT(ic));
2077 if (currFunc && dtype &&
2078 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2079 IFFUNC_ISISR(currFunc->type) &&
2082 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2085 /*-----------------------------------------------------------------*/
2086 /* unsaveRegisters - pop the pushed registers */
2087 /*-----------------------------------------------------------------*/
2088 static void unsaveRegisters (iCode *ic)
2093 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2094 /* find the registers in use at this time
2095 and push them away to safety */
2096 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2099 if (options.useXstack) {
2100 pic16_emitcode("mov","r0,%s",spname);
2101 for (i = pic16_nRegs ; i >= 0 ; i--) {
2102 if (bitVectBitValue(rsave,i)) {
2103 pic16_emitcode("dec","r0");
2104 pic16_emitcode("movx","a,@r0");
2106 pic16_emitcode("mov","b,a");
2108 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2112 pic16_emitcode("mov","%s,r0",spname);
2113 if (bitVectBitValue(rsave,R0_IDX))
2114 pic16_emitcode("mov","r0,b");
2116 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2117 // if (bitVectBitValue(rsave,i))
2118 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2124 /*-----------------------------------------------------------------*/
2126 /*-----------------------------------------------------------------*/
2127 static void pushSide(operand * oper, int size)
2131 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2133 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2134 if (AOP_TYPE(oper) != AOP_REG &&
2135 AOP_TYPE(oper) != AOP_DIR &&
2137 pic16_emitcode("mov","a,%s",l);
2138 pic16_emitcode("push","acc");
2140 pic16_emitcode("push","%s",l);
2145 /*-----------------------------------------------------------------*/
2146 /* assignResultValue - */
2147 /*-----------------------------------------------------------------*/
2148 static void assignResultValue(operand * oper)
2150 int size = AOP_SIZE(oper);
2152 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2154 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2156 if(!GpsuedoStkPtr) {
2157 /* The last byte in the assignment is in W */
2159 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2164 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2166 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2171 /*-----------------------------------------------------------------*/
2172 /* genIpush - genrate code for pushing this gets a little complex */
2173 /*-----------------------------------------------------------------*/
2174 static void genIpush (iCode *ic)
2177 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2179 int size, offset = 0 ;
2183 /* if this is not a parm push : ie. it is spill push
2184 and spill push is always done on the local stack */
2185 if (!ic->parmPush) {
2187 /* and the item is spilt then do nothing */
2188 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2191 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2192 size = AOP_SIZE(IC_LEFT(ic));
2193 /* push it on the stack */
2195 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2200 pic16_emitcode("push","%s",l);
2205 /* this is a paramter push: in this case we call
2206 the routine to find the call and save those
2207 registers that need to be saved */
2210 /* then do the push */
2211 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2214 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2215 size = AOP_SIZE(IC_LEFT(ic));
2218 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2219 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2220 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2222 pic16_emitcode("mov","a,%s",l);
2223 pic16_emitcode("push","acc");
2225 pic16_emitcode("push","%s",l);
2228 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2232 /*-----------------------------------------------------------------*/
2233 /* genIpop - recover the registers: can happen only for spilling */
2234 /*-----------------------------------------------------------------*/
2235 static void genIpop (iCode *ic)
2237 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2242 /* if the temp was not pushed then */
2243 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2246 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2247 size = AOP_SIZE(IC_LEFT(ic));
2250 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2253 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2257 /*-----------------------------------------------------------------*/
2258 /* unsaverbank - restores the resgister bank from stack */
2259 /*-----------------------------------------------------------------*/
2260 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2262 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2268 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2270 if (options.useXstack) {
2272 r = getFreePtr(ic,&aop,FALSE);
2275 pic16_emitcode("mov","%s,_spx",r->name);
2276 pic16_emitcode("movx","a,@%s",r->name);
2277 pic16_emitcode("mov","psw,a");
2278 pic16_emitcode("dec","%s",r->name);
2281 pic16_emitcode ("pop","psw");
2284 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2285 if (options.useXstack) {
2286 pic16_emitcode("movx","a,@%s",r->name);
2287 //pic16_emitcode("mov","(%s+%d),a",
2288 // regspic16[i].base,8*bank+regspic16[i].offset);
2289 pic16_emitcode("dec","%s",r->name);
2292 pic16_emitcode("pop",""); //"(%s+%d)",
2293 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2296 if (options.useXstack) {
2298 pic16_emitcode("mov","_spx,%s",r->name);
2299 pic16_freeAsmop(NULL,aop,ic,TRUE);
2305 /*-----------------------------------------------------------------*/
2306 /* saverbank - saves an entire register bank on the stack */
2307 /*-----------------------------------------------------------------*/
2308 static void saverbank (int bank, iCode *ic, bool pushPsw)
2310 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2316 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2317 if (options.useXstack) {
2320 r = getFreePtr(ic,&aop,FALSE);
2321 pic16_emitcode("mov","%s,_spx",r->name);
2325 for (i = 0 ; i < pic16_nRegs ;i++) {
2326 if (options.useXstack) {
2327 pic16_emitcode("inc","%s",r->name);
2328 //pic16_emitcode("mov","a,(%s+%d)",
2329 // regspic16[i].base,8*bank+regspic16[i].offset);
2330 pic16_emitcode("movx","@%s,a",r->name);
2332 pic16_emitcode("push","");// "(%s+%d)",
2333 //regspic16[i].base,8*bank+regspic16[i].offset);
2337 if (options.useXstack) {
2338 pic16_emitcode("mov","a,psw");
2339 pic16_emitcode("movx","@%s,a",r->name);
2340 pic16_emitcode("inc","%s",r->name);
2341 pic16_emitcode("mov","_spx,%s",r->name);
2342 pic16_freeAsmop (NULL,aop,ic,TRUE);
2345 pic16_emitcode("push","psw");
2347 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2353 /*-----------------------------------------------------------------*/
2354 /* genCall - generates a call statement */
2355 /*-----------------------------------------------------------------*/
2356 static void genCall (iCode *ic)
2360 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2362 /* if caller saves & we have not saved then */
2366 /* if we are calling a function that is not using
2367 the same register bank then we need to save the
2368 destination registers on the stack */
2369 dtype = operandType(IC_LEFT(ic));
2370 if (currFunc && dtype &&
2371 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2372 IFFUNC_ISISR(currFunc->type) &&
2375 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2377 /* if send set is not empty the assign */
2380 /* For the Pic port, there is no data stack.
2381 * So parameters passed to functions are stored
2382 * in registers. (The pCode optimizer will get
2383 * rid of most of these :).
2385 int psuedoStkPtr=-1;
2386 int firstTimeThruLoop = 1;
2388 _G.sendSet = reverseSet(_G.sendSet);
2390 /* First figure how many parameters are getting passed */
2391 for (sic = setFirstItem(_G.sendSet) ; sic ;
2392 sic = setNextItem(_G.sendSet)) {
2394 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2395 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2396 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2399 for (sic = setFirstItem(_G.sendSet) ; sic ;
2400 sic = setNextItem(_G.sendSet)) {
2401 int size, offset = 0;
2403 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2404 size = AOP_SIZE(IC_LEFT(sic));
2407 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2408 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2410 if(!firstTimeThruLoop) {
2411 /* If this is not the first time we've been through the loop
2412 * then we need to save the parameter in a temporary
2413 * register. The last byte of the last parameter is
2415 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2418 firstTimeThruLoop=0;
2420 //if (strcmp(l,fReturn[offset])) {
2421 mov2w (AOP(IC_LEFT(sic)), offset);
2423 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2424 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2425 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2427 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2432 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2437 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2438 OP_SYMBOL(IC_LEFT(ic))->rname :
2439 OP_SYMBOL(IC_LEFT(ic))->name));
2442 /* if we need assign a result value */
2443 if ((IS_ITEMP(IC_RESULT(ic)) &&
2444 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2445 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2446 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2449 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2452 assignResultValue(IC_RESULT(ic));
2454 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2455 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2457 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2460 /* adjust the stack for parameters if
2462 if (ic->parmBytes) {
2464 if (ic->parmBytes > 3) {
2465 pic16_emitcode("mov","a,%s",spname);
2466 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2467 pic16_emitcode("mov","%s,a",spname);
2469 for ( i = 0 ; i < ic->parmBytes ;i++)
2470 pic16_emitcode("dec","%s",spname);
2474 /* if register bank was saved then pop them */
2476 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2478 /* if we hade saved some registers then unsave them */
2479 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2480 unsaveRegisters (ic);
2485 /*-----------------------------------------------------------------*/
2486 /* genPcall - generates a call by pointer statement */
2487 /*-----------------------------------------------------------------*/
2488 static void genPcall (iCode *ic)
2491 symbol *rlbl = newiTempLabel(NULL);
2494 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2495 /* if caller saves & we have not saved then */
2499 /* if we are calling a function that is not using
2500 the same register bank then we need to save the
2501 destination registers on the stack */
2502 dtype = operandType(IC_LEFT(ic));
2503 if (currFunc && dtype &&
2504 IFFUNC_ISISR(currFunc->type) &&
2505 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2506 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2509 /* push the return address on to the stack */
2510 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2511 pic16_emitcode("push","acc");
2512 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2513 pic16_emitcode("push","acc");
2515 if (options.model == MODEL_FLAT24)
2517 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2518 pic16_emitcode("push","acc");
2521 /* now push the calling address */
2522 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2524 pushSide(IC_LEFT(ic), FPTRSIZE);
2526 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2528 /* if send set is not empty the assign */
2532 for (sic = setFirstItem(_G.sendSet) ; sic ;
2533 sic = setNextItem(_G.sendSet)) {
2534 int size, offset = 0;
2535 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2536 size = AOP_SIZE(IC_LEFT(sic));
2538 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2540 if (strcmp(l,fReturn[offset]))
2541 pic16_emitcode("mov","%s,%s",
2546 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2551 pic16_emitcode("ret","");
2552 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2555 /* if we need assign a result value */
2556 if ((IS_ITEMP(IC_RESULT(ic)) &&
2557 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2558 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2559 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2562 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2565 assignResultValue(IC_RESULT(ic));
2567 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2570 /* adjust the stack for parameters if
2572 if (ic->parmBytes) {
2574 if (ic->parmBytes > 3) {
2575 pic16_emitcode("mov","a,%s",spname);
2576 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2577 pic16_emitcode("mov","%s,a",spname);
2579 for ( i = 0 ; i < ic->parmBytes ;i++)
2580 pic16_emitcode("dec","%s",spname);
2584 /* if register bank was saved then unsave them */
2585 if (currFunc && dtype &&
2586 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2587 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2589 /* if we hade saved some registers then
2592 unsaveRegisters (ic);
2596 /*-----------------------------------------------------------------*/
2597 /* resultRemat - result is rematerializable */
2598 /*-----------------------------------------------------------------*/
2599 static int resultRemat (iCode *ic)
2601 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2602 if (SKIP_IC(ic) || ic->op == IFX)
2605 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2606 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2607 if (sym->remat && !POINTER_SET(ic))
2614 #if defined(__BORLANDC__) || defined(_MSC_VER)
2615 #define STRCASECMP stricmp
2617 #define STRCASECMP strcasecmp
2621 /*-----------------------------------------------------------------*/
2622 /* inExcludeList - return 1 if the string is in exclude Reg list */
2623 /*-----------------------------------------------------------------*/
2624 static bool inExcludeList(char *s)
2626 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2629 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2630 if (options.excludeRegs[i] &&
2631 STRCASECMP(options.excludeRegs[i],"none") == 0)
2634 for ( i = 0 ; options.excludeRegs[i]; i++) {
2635 if (options.excludeRegs[i] &&
2636 STRCASECMP(s,options.excludeRegs[i]) == 0)
2643 /*-----------------------------------------------------------------*/
2644 /* genFunction - generated code for function entry */
2645 /*-----------------------------------------------------------------*/
2646 static void genFunction (iCode *ic)
2651 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2653 labelOffset += (max_key+4);
2657 /* create the function header */
2658 pic16_emitcode(";","-----------------------------------------");
2659 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2660 pic16_emitcode(";","-----------------------------------------");
2662 pic16_emitcode("","%s:",sym->rname);
2663 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2665 ftype = operandType(IC_LEFT(ic));
2667 /* if critical function then turn interrupts off */
2668 if (IFFUNC_ISCRITICAL(ftype))
2669 pic16_emitcode("clr","ea");
2671 /* here we need to generate the equates for the
2672 register bank if required */
2674 if (FUNC_REGBANK(ftype) != rbank) {
2677 rbank = FUNC_REGBANK(ftype);
2678 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2679 if (strcmp(regspic16[i].base,"0") == 0)
2680 pic16_emitcode("","%s = 0x%02x",
2682 8*rbank+regspic16[i].offset);
2684 pic16_emitcode ("","%s = %s + 0x%02x",
2687 8*rbank+regspic16[i].offset);
2692 /* if this is an interrupt service routine then
2693 save acc, b, dpl, dph */
2694 if (IFFUNC_ISISR(sym->type)) {
2695 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2696 pic16_emitpcodeNULLop(POC_NOP);
2697 pic16_emitpcodeNULLop(POC_NOP);
2698 pic16_emitpcodeNULLop(POC_NOP);
2699 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2700 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2701 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2702 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2704 pic16_pBlockConvert2ISR(pb);
2706 if (!inExcludeList("acc"))
2707 pic16_emitcode ("push","acc");
2708 if (!inExcludeList("b"))
2709 pic16_emitcode ("push","b");
2710 if (!inExcludeList("dpl"))
2711 pic16_emitcode ("push","dpl");
2712 if (!inExcludeList("dph"))
2713 pic16_emitcode ("push","dph");
2714 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2716 pic16_emitcode ("push", "dpx");
2717 /* Make sure we're using standard DPTR */
2718 pic16_emitcode ("push", "dps");
2719 pic16_emitcode ("mov", "dps, #0x00");
2720 if (options.stack10bit)
2722 /* This ISR could conceivably use DPTR2. Better save it. */
2723 pic16_emitcode ("push", "dpl1");
2724 pic16_emitcode ("push", "dph1");
2725 pic16_emitcode ("push", "dpx1");
2728 /* if this isr has no bank i.e. is going to
2729 run with bank 0 , then we need to save more
2731 if (!FUNC_REGBANK(sym->type)) {
2733 /* if this function does not call any other
2734 function then we can be economical and
2735 save only those registers that are used */
2736 if (! IFFUNC_HASFCALL(sym->type)) {
2739 /* if any registers used */
2740 if (sym->regsUsed) {
2741 /* save the registers used */
2742 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2743 if (bitVectBitValue(sym->regsUsed,i) ||
2744 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2745 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2750 /* this function has a function call cannot
2751 determines register usage so we will have the
2753 saverbank(0,ic,FALSE);
2758 /* if callee-save to be used for this function
2759 then save the registers being used in this function */
2760 if (IFFUNC_CALLEESAVES(sym->type)) {
2763 /* if any registers used */
2764 if (sym->regsUsed) {
2765 /* save the registers used */
2766 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2767 if (bitVectBitValue(sym->regsUsed,i) ||
2768 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2769 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2777 /* set the register bank to the desired value */
2778 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2779 pic16_emitcode("push","psw");
2780 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2783 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2785 if (options.useXstack) {
2786 pic16_emitcode("mov","r0,%s",spname);
2787 pic16_emitcode("mov","a,_bp");
2788 pic16_emitcode("movx","@r0,a");
2789 pic16_emitcode("inc","%s",spname);
2793 /* set up the stack */
2794 pic16_emitcode ("push","_bp"); /* save the callers stack */
2796 pic16_emitcode ("mov","_bp,%s",spname);
2799 /* adjust the stack for the function */
2804 werror(W_STACK_OVERFLOW,sym->name);
2806 if (i > 3 && sym->recvSize < 4) {
2808 pic16_emitcode ("mov","a,sp");
2809 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2810 pic16_emitcode ("mov","sp,a");
2815 pic16_emitcode("inc","sp");
2820 pic16_emitcode ("mov","a,_spx");
2821 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2822 pic16_emitcode ("mov","_spx,a");
2827 /*-----------------------------------------------------------------*/
2828 /* genEndFunction - generates epilogue for functions */
2829 /*-----------------------------------------------------------------*/
2830 static void genEndFunction (iCode *ic)
2832 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2834 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2836 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2838 pic16_emitcode ("mov","%s,_bp",spname);
2841 /* if use external stack but some variables were
2842 added to the local stack then decrement the
2844 if (options.useXstack && sym->stack) {
2845 pic16_emitcode("mov","a,sp");
2846 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2847 pic16_emitcode("mov","sp,a");
2851 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2852 if (options.useXstack) {
2853 pic16_emitcode("mov","r0,%s",spname);
2854 pic16_emitcode("movx","a,@r0");
2855 pic16_emitcode("mov","_bp,a");
2856 pic16_emitcode("dec","%s",spname);
2860 pic16_emitcode ("pop","_bp");
2864 /* restore the register bank */
2865 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2866 pic16_emitcode ("pop","psw");
2868 if (IFFUNC_ISISR(sym->type)) {
2870 /* now we need to restore the registers */
2871 /* if this isr has no bank i.e. is going to
2872 run with bank 0 , then we need to save more
2874 if (!FUNC_REGBANK(sym->type)) {
2876 /* if this function does not call any other
2877 function then we can be economical and
2878 save only those registers that are used */
2879 if (! IFFUNC_HASFCALL(sym->type)) {
2882 /* if any registers used */
2883 if (sym->regsUsed) {
2884 /* save the registers used */
2885 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2886 if (bitVectBitValue(sym->regsUsed,i) ||
2887 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2888 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2893 /* this function has a function call cannot
2894 determines register usage so we will have the
2896 unsaverbank(0,ic,FALSE);
2900 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2902 if (options.stack10bit)
2904 pic16_emitcode ("pop", "dpx1");
2905 pic16_emitcode ("pop", "dph1");
2906 pic16_emitcode ("pop", "dpl1");
2908 pic16_emitcode ("pop", "dps");
2909 pic16_emitcode ("pop", "dpx");
2911 if (!inExcludeList("dph"))
2912 pic16_emitcode ("pop","dph");
2913 if (!inExcludeList("dpl"))
2914 pic16_emitcode ("pop","dpl");
2915 if (!inExcludeList("b"))
2916 pic16_emitcode ("pop","b");
2917 if (!inExcludeList("acc"))
2918 pic16_emitcode ("pop","acc");
2920 if (IFFUNC_ISCRITICAL(sym->type))
2921 pic16_emitcode("setb","ea");
2924 /* if debug then send end of function */
2925 /* if (options.debug && currFunc) { */
2928 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2929 FileBaseName(ic->filename),currFunc->lastLine,
2930 ic->level,ic->block);
2931 if (IS_STATIC(currFunc->etype))
2932 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2934 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2938 pic16_emitcode ("reti","");
2940 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2941 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2942 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
2943 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
2944 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2945 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2947 pic16_emitpcodeNULLop(POC_RETFIE);
2951 if (IFFUNC_ISCRITICAL(sym->type))
2952 pic16_emitcode("setb","ea");
2954 if (IFFUNC_CALLEESAVES(sym->type)) {
2957 /* if any registers used */
2958 if (sym->regsUsed) {
2959 /* save the registers used */
2960 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2961 if (bitVectBitValue(sym->regsUsed,i) ||
2962 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2963 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2969 /* if debug then send end of function */
2972 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2973 FileBaseName(ic->filename),currFunc->lastLine,
2974 ic->level,ic->block);
2975 if (IS_STATIC(currFunc->etype))
2976 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2978 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2982 pic16_emitcode ("return","");
2983 pic16_emitpcodeNULLop(POC_RETURN);
2985 /* Mark the end of a function */
2986 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
2991 /*-----------------------------------------------------------------*/
2992 /* genRet - generate code for return statement */
2993 /*-----------------------------------------------------------------*/
2994 static void genRet (iCode *ic)
2996 int size,offset = 0 , pushed = 0;
2998 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2999 /* if we have no return value then
3000 just generate the "ret" */
3004 /* we have something to return then
3005 move the return value into place */
3006 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3007 size = AOP_SIZE(IC_LEFT(ic));
3011 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3013 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3015 pic16_emitcode("push","%s",l);
3018 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3020 if (strcmp(fReturn[offset],l)) {
3021 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3022 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3023 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3025 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3028 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3038 if (strcmp(fReturn[pushed],"a"))
3039 pic16_emitcode("pop",fReturn[pushed]);
3041 pic16_emitcode("pop","acc");
3044 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3047 /* generate a jump to the return label
3048 if the next is not the return statement */
3049 if (!(ic->next && ic->next->op == LABEL &&
3050 IC_LABEL(ic->next) == returnLabel)) {
3052 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3053 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3058 /*-----------------------------------------------------------------*/
3059 /* genLabel - generates a label */
3060 /*-----------------------------------------------------------------*/
3061 static void genLabel (iCode *ic)
3063 /* special case never generate */
3064 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3065 if (IC_LABEL(ic) == entryLabel)
3068 pic16_emitpLabel(IC_LABEL(ic)->key);
3069 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3072 /*-----------------------------------------------------------------*/
3073 /* genGoto - generates a goto */
3074 /*-----------------------------------------------------------------*/
3076 static void genGoto (iCode *ic)
3078 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3079 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3083 /*-----------------------------------------------------------------*/
3084 /* genMultbits :- multiplication of bits */
3085 /*-----------------------------------------------------------------*/
3086 static void genMultbits (operand *left,
3090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3092 if(!pic16_sameRegs(AOP(result),AOP(right)))
3093 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3095 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3096 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3097 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3102 /*-----------------------------------------------------------------*/
3103 /* genMultOneByte : 8 bit multiplication & division */
3104 /*-----------------------------------------------------------------*/
3105 static void genMultOneByte (operand *left,
3109 sym_link *opetype = operandType(result);
3114 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3115 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3116 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3118 /* (if two literals, the value is computed before) */
3119 /* if one literal, literal on the right */
3120 if (AOP_TYPE(left) == AOP_LIT){
3126 size = AOP_SIZE(result);
3129 if (AOP_TYPE(right) == AOP_LIT){
3130 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3131 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3132 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3133 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3134 pic16_emitcode("call","genMultLit");
3136 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3137 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3138 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3139 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3140 pic16_emitcode("call","pic16_genMult8X8_8");
3143 pic16_genMult8X8_8 (left, right,result);
3146 /* signed or unsigned */
3147 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3148 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3150 //pic16_emitcode("mul","ab");
3151 /* if result size = 1, mul signed = mul unsigned */
3152 //pic16_aopPut(AOP(result),"a",0);
3154 } else { // (size > 1)
3156 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3157 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3158 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3159 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3161 if (SPEC_USIGN(opetype)){
3162 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3163 pic16_genUMult8X8_16 (left, right, result, NULL);
3166 /* for filling the MSBs */
3167 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3168 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3172 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3174 pic16_emitcode("mov","a,b");
3176 /* adjust the MSB if left or right neg */
3178 /* if one literal */
3179 if (AOP_TYPE(right) == AOP_LIT){
3180 pic16_emitcode("multiply ","right is a lit");
3181 /* AND literal negative */
3182 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3183 /* adjust MSB (c==0 after mul) */
3184 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3188 pic16_genSMult8X8_16 (left, right, result, NULL);
3192 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3194 pic16_emitcode("rlc","a");
3195 pic16_emitcode("subb","a,acc");
3203 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3204 //pic16_aopPut(AOP(result),"a",offset++);
3208 /*-----------------------------------------------------------------*/
3209 /* genMult - generates code for multiplication */
3210 /*-----------------------------------------------------------------*/
3211 static void genMult (iCode *ic)
3213 operand *left = IC_LEFT(ic);
3214 operand *right = IC_RIGHT(ic);
3215 operand *result= IC_RESULT(ic);
3217 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3218 /* assign the amsops */
3219 pic16_aopOp (left,ic,FALSE);
3220 pic16_aopOp (right,ic,FALSE);
3221 pic16_aopOp (result,ic,TRUE);
3223 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3225 /* special cases first */
3227 if (AOP_TYPE(left) == AOP_CRY &&
3228 AOP_TYPE(right)== AOP_CRY) {
3229 genMultbits(left,right,result);
3233 /* if both are of size == 1 */
3234 if (AOP_SIZE(left) == 1 &&
3235 AOP_SIZE(right) == 1 ) {
3236 genMultOneByte(left,right,result);
3240 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3242 /* should have been converted to function call */
3246 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3247 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3248 pic16_freeAsmop(result,NULL,ic,TRUE);
3251 /*-----------------------------------------------------------------*/
3252 /* genDivbits :- division of bits */
3253 /*-----------------------------------------------------------------*/
3254 static void genDivbits (operand *left,
3261 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3262 /* the result must be bit */
3263 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3264 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3268 pic16_emitcode("div","ab");
3269 pic16_emitcode("rrc","a");
3270 pic16_aopPut(AOP(result),"c",0);
3273 /*-----------------------------------------------------------------*/
3274 /* genDivOneByte : 8 bit division */
3275 /*-----------------------------------------------------------------*/
3276 static void genDivOneByte (operand *left,
3280 sym_link *opetype = operandType(result);
3285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3286 size = AOP_SIZE(result) - 1;
3288 /* signed or unsigned */
3289 if (SPEC_USIGN(opetype)) {
3290 /* unsigned is easy */
3291 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3292 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3294 pic16_emitcode("div","ab");
3295 pic16_aopPut(AOP(result),"a",0);
3297 pic16_aopPut(AOP(result),zero,offset++);
3301 /* signed is a little bit more difficult */
3303 /* save the signs of the operands */
3304 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3306 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3307 pic16_emitcode("push","acc"); /* save it on the stack */
3309 /* now sign adjust for both left & right */
3310 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3312 lbl = newiTempLabel(NULL);
3313 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3314 pic16_emitcode("cpl","a");
3315 pic16_emitcode("inc","a");
3316 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3317 pic16_emitcode("mov","b,a");
3319 /* sign adjust left side */
3320 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3323 lbl = newiTempLabel(NULL);
3324 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3325 pic16_emitcode("cpl","a");
3326 pic16_emitcode("inc","a");
3327 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3329 /* now the division */
3330 pic16_emitcode("div","ab");
3331 /* we are interested in the lower order
3333 pic16_emitcode("mov","b,a");
3334 lbl = newiTempLabel(NULL);
3335 pic16_emitcode("pop","acc");
3336 /* if there was an over flow we don't
3337 adjust the sign of the result */
3338 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3339 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3341 pic16_emitcode("clr","a");
3342 pic16_emitcode("subb","a,b");
3343 pic16_emitcode("mov","b,a");
3344 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3346 /* now we are done */
3347 pic16_aopPut(AOP(result),"b",0);
3349 pic16_emitcode("mov","c,b.7");
3350 pic16_emitcode("subb","a,acc");
3353 pic16_aopPut(AOP(result),"a",offset++);
3357 /*-----------------------------------------------------------------*/
3358 /* genDiv - generates code for division */
3359 /*-----------------------------------------------------------------*/
3360 static void genDiv (iCode *ic)
3362 operand *left = IC_LEFT(ic);
3363 operand *right = IC_RIGHT(ic);
3364 operand *result= IC_RESULT(ic);
3366 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3367 /* assign the amsops */
3368 pic16_aopOp (left,ic,FALSE);
3369 pic16_aopOp (right,ic,FALSE);
3370 pic16_aopOp (result,ic,TRUE);
3372 /* special cases first */
3374 if (AOP_TYPE(left) == AOP_CRY &&
3375 AOP_TYPE(right)== AOP_CRY) {
3376 genDivbits(left,right,result);
3380 /* if both are of size == 1 */
3381 if (AOP_SIZE(left) == 1 &&
3382 AOP_SIZE(right) == 1 ) {
3383 genDivOneByte(left,right,result);
3387 /* should have been converted to function call */
3390 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3391 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3392 pic16_freeAsmop(result,NULL,ic,TRUE);
3395 /*-----------------------------------------------------------------*/
3396 /* genModbits :- modulus of bits */
3397 /*-----------------------------------------------------------------*/
3398 static void genModbits (operand *left,
3405 /* the result must be bit */
3406 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3407 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3411 pic16_emitcode("div","ab");
3412 pic16_emitcode("mov","a,b");
3413 pic16_emitcode("rrc","a");
3414 pic16_aopPut(AOP(result),"c",0);
3417 /*-----------------------------------------------------------------*/
3418 /* genModOneByte : 8 bit modulus */
3419 /*-----------------------------------------------------------------*/
3420 static void genModOneByte (operand *left,
3424 sym_link *opetype = operandType(result);
3428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3429 /* signed or unsigned */
3430 if (SPEC_USIGN(opetype)) {
3431 /* unsigned is easy */
3432 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3433 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3435 pic16_emitcode("div","ab");
3436 pic16_aopPut(AOP(result),"b",0);
3440 /* signed is a little bit more difficult */
3442 /* save the signs of the operands */
3443 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3446 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3447 pic16_emitcode("push","acc"); /* save it on the stack */
3449 /* now sign adjust for both left & right */
3450 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3453 lbl = newiTempLabel(NULL);
3454 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3455 pic16_emitcode("cpl","a");
3456 pic16_emitcode("inc","a");
3457 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3458 pic16_emitcode("mov","b,a");
3460 /* sign adjust left side */
3461 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3464 lbl = newiTempLabel(NULL);
3465 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3466 pic16_emitcode("cpl","a");
3467 pic16_emitcode("inc","a");
3468 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3470 /* now the multiplication */
3471 pic16_emitcode("div","ab");
3472 /* we are interested in the lower order
3474 lbl = newiTempLabel(NULL);
3475 pic16_emitcode("pop","acc");
3476 /* if there was an over flow we don't
3477 adjust the sign of the result */
3478 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3479 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3481 pic16_emitcode("clr","a");
3482 pic16_emitcode("subb","a,b");
3483 pic16_emitcode("mov","b,a");
3484 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3486 /* now we are done */
3487 pic16_aopPut(AOP(result),"b",0);
3491 /*-----------------------------------------------------------------*/
3492 /* genMod - generates code for division */
3493 /*-----------------------------------------------------------------*/
3494 static void genMod (iCode *ic)
3496 operand *left = IC_LEFT(ic);
3497 operand *right = IC_RIGHT(ic);
3498 operand *result= IC_RESULT(ic);
3500 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3501 /* assign the amsops */
3502 pic16_aopOp (left,ic,FALSE);
3503 pic16_aopOp (right,ic,FALSE);
3504 pic16_aopOp (result,ic,TRUE);
3506 /* special cases first */
3508 if (AOP_TYPE(left) == AOP_CRY &&
3509 AOP_TYPE(right)== AOP_CRY) {
3510 genModbits(left,right,result);
3514 /* if both are of size == 1 */
3515 if (AOP_SIZE(left) == 1 &&
3516 AOP_SIZE(right) == 1 ) {
3517 genModOneByte(left,right,result);
3521 /* should have been converted to function call */
3525 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3526 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3527 pic16_freeAsmop(result,NULL,ic,TRUE);
3530 /*-----------------------------------------------------------------*/
3531 /* genIfxJump :- will create a jump depending on the ifx */
3532 /*-----------------------------------------------------------------*/
3534 note: May need to add parameter to indicate when a variable is in bit space.
3536 static void genIfxJump (iCode *ic, char *jval)
3539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3540 /* if true label then we jump if condition
3542 if ( IC_TRUE(ic) ) {
3544 if(strcmp(jval,"a") == 0)
3546 else if (strcmp(jval,"c") == 0)
3549 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3550 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3553 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3554 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3558 /* false label is present */
3559 if(strcmp(jval,"a") == 0)
3561 else if (strcmp(jval,"c") == 0)
3564 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3565 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3568 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3569 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3574 /* mark the icode as generated */
3578 /*-----------------------------------------------------------------*/
3580 /*-----------------------------------------------------------------*/
3581 static void genSkip(iCode *ifx,int status_bit)
3586 if ( IC_TRUE(ifx) ) {
3587 switch(status_bit) {
3602 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3603 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3607 switch(status_bit) {
3621 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3622 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3628 /*-----------------------------------------------------------------*/
3630 /*-----------------------------------------------------------------*/
3631 static void genSkipc(resolvedIfx *rifx)
3641 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3642 rifx->generated = 1;
3645 /*-----------------------------------------------------------------*/
3647 /*-----------------------------------------------------------------*/
3648 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3653 if( (rifx->condition ^ invert_condition) & 1)
3658 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3659 rifx->generated = 1;
3662 /*-----------------------------------------------------------------*/
3664 /*-----------------------------------------------------------------*/
3665 static void genSkipz(iCode *ifx, int condition)
3676 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3678 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3681 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3683 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3686 /*-----------------------------------------------------------------*/
3688 /*-----------------------------------------------------------------*/
3689 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3695 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3697 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3700 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3701 rifx->generated = 1;
3705 /*-----------------------------------------------------------------*/
3706 /* genChkZeroes :- greater or less than comparison */
3707 /* For each byte in a literal that is zero, inclusive or the */
3708 /* the corresponding byte in the operand with W */
3709 /* returns true if any of the bytes are zero */
3710 /*-----------------------------------------------------------------*/
3711 static int genChkZeroes(operand *op, int lit, int size)
3718 i = (lit >> (size*8)) & 0xff;
3722 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3724 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3733 /*-----------------------------------------------------------------*/
3734 /* genCmp :- greater or less than comparison */
3735 /*-----------------------------------------------------------------*/
3736 static void genCmp (operand *left,operand *right,
3737 operand *result, iCode *ifx, int sign)
3739 int size; //, offset = 0 ;
3740 unsigned long lit = 0L,i = 0;
3741 resolvedIfx rFalseIfx;
3742 // resolvedIfx rTrueIfx;
3744 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3747 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3748 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3752 resolveIfx(&rFalseIfx,ifx);
3753 truelbl = newiTempLabel(NULL);
3754 size = max(AOP_SIZE(left),AOP_SIZE(right));
3756 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3760 /* if literal is on the right then swap with left */
3761 if ((AOP_TYPE(right) == AOP_LIT)) {
3762 operand *tmp = right ;
3763 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3764 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3767 lit = (lit - 1) & mask;
3770 rFalseIfx.condition ^= 1;
3773 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3774 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3778 //if(IC_TRUE(ifx) == NULL)
3779 /* if left & right are bit variables */
3780 if (AOP_TYPE(left) == AOP_CRY &&
3781 AOP_TYPE(right) == AOP_CRY ) {
3782 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3783 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3785 /* subtract right from left if at the
3786 end the carry flag is set then we know that
3787 left is greater than right */
3791 symbol *lbl = newiTempLabel(NULL);
3794 if(AOP_TYPE(right) == AOP_LIT) {
3796 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3798 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3805 genSkipCond(&rFalseIfx,left,size-1,7);
3807 /* no need to compare to 0...*/
3808 /* NOTE: this is a de-generate compare that most certainly
3809 * creates some dead code. */
3810 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3812 if(ifx) ifx->generated = 1;
3819 //i = (lit >> (size*8)) & 0xff;
3820 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3822 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3824 i = ((0-lit) & 0xff);
3827 /* lit is 0x7f, all signed chars are less than
3828 * this except for 0x7f itself */
3829 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3830 genSkipz2(&rFalseIfx,0);
3832 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3833 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3834 genSkipc(&rFalseIfx);
3839 genSkipz2(&rFalseIfx,1);
3841 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3842 genSkipc(&rFalseIfx);
3846 if(ifx) ifx->generated = 1;
3850 /* chars are out of the way. now do ints and longs */
3853 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3860 genSkipCond(&rFalseIfx,left,size,7);
3861 if(ifx) ifx->generated = 1;
3866 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3868 //rFalseIfx.condition ^= 1;
3869 //genSkipCond(&rFalseIfx,left,size,7);
3870 //rFalseIfx.condition ^= 1;
3872 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3873 if(rFalseIfx.condition)
3874 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3876 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3878 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3879 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3880 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3883 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3885 if(rFalseIfx.condition) {
3887 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3893 genSkipc(&rFalseIfx);
3894 pic16_emitpLabel(truelbl->key);
3895 if(ifx) ifx->generated = 1;
3902 if( (lit & 0xff) == 0) {
3903 /* lower byte is zero */
3904 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3905 i = ((lit >> 8) & 0xff) ^0x80;
3906 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3907 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3908 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3909 genSkipc(&rFalseIfx);
3912 if(ifx) ifx->generated = 1;
3917 /* Special cases for signed longs */
3918 if( (lit & 0xffffff) == 0) {
3919 /* lower byte is zero */
3920 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3921 i = ((lit >> 8*3) & 0xff) ^0x80;
3922 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3923 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3924 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3925 genSkipc(&rFalseIfx);
3928 if(ifx) ifx->generated = 1;
3936 if(lit & (0x80 << (size*8))) {
3937 /* lit is negative */
3938 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3940 //genSkipCond(&rFalseIfx,left,size,7);
3942 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3944 if(rFalseIfx.condition)
3945 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3947 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3951 /* lit is positive */
3952 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3953 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3954 if(rFalseIfx.condition)
3955 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3957 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3962 This works, but is only good for ints.
3963 It also requires a "known zero" register.
3964 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3965 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3966 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
3967 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3968 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3969 genSkipc(&rFalseIfx);
3971 pic16_emitpLabel(truelbl->key);
3972 if(ifx) ifx->generated = 1;
3976 /* There are no more special cases, so perform a general compare */
3978 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3979 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3983 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3985 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
3987 //rFalseIfx.condition ^= 1;
3988 genSkipc(&rFalseIfx);
3990 pic16_emitpLabel(truelbl->key);
3992 if(ifx) ifx->generated = 1;
3999 /* sign is out of the way. So now do an unsigned compare */
4000 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4003 /* General case - compare to an unsigned literal on the right.*/
4005 i = (lit >> (size*8)) & 0xff;
4006 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4007 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4009 i = (lit >> (size*8)) & 0xff;
4012 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4014 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4016 /* this byte of the lit is zero,
4017 *if it's not the last then OR in the variable */
4019 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4024 pic16_emitpLabel(lbl->key);
4025 //if(emitFinalCheck)
4026 genSkipc(&rFalseIfx);
4028 pic16_emitpLabel(truelbl->key);
4030 if(ifx) ifx->generated = 1;
4037 if(AOP_TYPE(left) == AOP_LIT) {
4038 //symbol *lbl = newiTempLabel(NULL);
4040 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4043 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4046 if((lit == 0) && (sign == 0)){
4049 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4051 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4053 genSkipz2(&rFalseIfx,0);
4054 if(ifx) ifx->generated = 1;
4061 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4062 /* degenerate compare can never be true */
4063 if(rFalseIfx.condition == 0)
4064 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4066 if(ifx) ifx->generated = 1;
4071 /* signed comparisons to a literal byte */
4073 int lp1 = (lit+1) & 0xff;
4075 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4078 rFalseIfx.condition ^= 1;
4079 genSkipCond(&rFalseIfx,right,0,7);
4082 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4083 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4084 genSkipz2(&rFalseIfx,1);
4087 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4088 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4089 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4090 rFalseIfx.condition ^= 1;
4091 genSkipc(&rFalseIfx);
4095 /* unsigned comparisons to a literal byte */
4097 switch(lit & 0xff ) {
4099 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4100 genSkipz2(&rFalseIfx,0);
4103 rFalseIfx.condition ^= 1;
4104 genSkipCond(&rFalseIfx,right,0,7);
4108 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4109 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4110 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4111 rFalseIfx.condition ^= 1;
4112 if (AOP_TYPE(result) == AOP_CRY)
4113 genSkipc(&rFalseIfx);
4115 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4116 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4122 if(ifx) ifx->generated = 1;
4128 /* Size is greater than 1 */
4136 /* this means lit = 0xffffffff, or -1 */
4139 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4140 rFalseIfx.condition ^= 1;
4141 genSkipCond(&rFalseIfx,right,size,7);
4142 if(ifx) ifx->generated = 1;
4149 if(rFalseIfx.condition) {
4150 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4151 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4154 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4156 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4160 if(rFalseIfx.condition) {
4161 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4162 pic16_emitpLabel(truelbl->key);
4164 rFalseIfx.condition ^= 1;
4165 genSkipCond(&rFalseIfx,right,s,7);
4168 if(ifx) ifx->generated = 1;
4172 if((size == 1) && (0 == (lp1&0xff))) {
4173 /* lower byte of signed word is zero */
4174 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4175 i = ((lp1 >> 8) & 0xff) ^0x80;
4176 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4177 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4178 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4179 rFalseIfx.condition ^= 1;
4180 genSkipc(&rFalseIfx);
4183 if(ifx) ifx->generated = 1;
4187 if(lit & (0x80 << (size*8))) {
4188 /* Lit is less than zero */
4189 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4190 //rFalseIfx.condition ^= 1;
4191 //genSkipCond(&rFalseIfx,left,size,7);
4192 //rFalseIfx.condition ^= 1;
4193 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4194 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4196 if(rFalseIfx.condition)
4197 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4199 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4203 /* Lit is greater than or equal to zero */
4204 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4205 //rFalseIfx.condition ^= 1;
4206 //genSkipCond(&rFalseIfx,right,size,7);
4207 //rFalseIfx.condition ^= 1;
4209 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4210 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4212 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4213 if(rFalseIfx.condition)
4214 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4216 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4221 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4222 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4226 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4228 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4230 rFalseIfx.condition ^= 1;
4231 //rFalseIfx.condition = 1;
4232 genSkipc(&rFalseIfx);
4234 pic16_emitpLabel(truelbl->key);
4236 if(ifx) ifx->generated = 1;
4241 /* compare word or long to an unsigned literal on the right.*/
4246 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4249 break; /* handled above */
4252 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4254 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4255 genSkipz2(&rFalseIfx,0);
4259 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4261 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4264 if(rFalseIfx.condition)
4265 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4267 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4270 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4271 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4273 rFalseIfx.condition ^= 1;
4274 genSkipc(&rFalseIfx);
4277 pic16_emitpLabel(truelbl->key);
4279 if(ifx) ifx->generated = 1;
4285 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4286 i = (lit >> (size*8)) & 0xff;
4288 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4289 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4292 i = (lit >> (size*8)) & 0xff;
4295 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4297 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4299 /* this byte of the lit is zero,
4300 *if it's not the last then OR in the variable */
4302 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4307 pic16_emitpLabel(lbl->key);
4309 rFalseIfx.condition ^= 1;
4310 genSkipc(&rFalseIfx);
4314 pic16_emitpLabel(truelbl->key);
4315 if(ifx) ifx->generated = 1;
4319 /* Compare two variables */
4321 DEBUGpic16_emitcode(";sign","%d",sign);
4325 /* Sigh. thus sucks... */
4327 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4328 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4329 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4330 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4331 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4332 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4334 /* Signed char comparison */
4335 /* Special thanks to Nikolai Golovchenko for this snippet */
4336 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4337 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4338 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4339 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4340 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4341 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4343 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4344 genSkipc(&rFalseIfx);
4346 if(ifx) ifx->generated = 1;
4352 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4353 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4357 /* The rest of the bytes of a multi-byte compare */
4361 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4364 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4365 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4370 pic16_emitpLabel(lbl->key);
4372 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4373 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4374 (AOP_TYPE(result) == AOP_REG)) {
4375 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4376 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4378 genSkipc(&rFalseIfx);
4380 //genSkipc(&rFalseIfx);
4381 if(ifx) ifx->generated = 1;
4388 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4389 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4390 pic16_outBitC(result);
4392 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4393 /* if the result is used in the next
4394 ifx conditional branch then generate
4395 code a little differently */
4397 genIfxJump (ifx,"c");
4399 pic16_outBitC(result);
4400 /* leave the result in acc */
4405 /*-----------------------------------------------------------------*/
4406 /* genCmpGt :- greater than comparison */
4407 /*-----------------------------------------------------------------*/
4408 static void genCmpGt (iCode *ic, iCode *ifx)
4410 operand *left, *right, *result;
4411 sym_link *letype , *retype;
4414 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4416 right= IC_RIGHT(ic);
4417 result = IC_RESULT(ic);
4419 letype = getSpec(operandType(left));
4420 retype =getSpec(operandType(right));
4421 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4422 /* assign the amsops */
4423 pic16_aopOp (left,ic,FALSE);
4424 pic16_aopOp (right,ic,FALSE);
4425 pic16_aopOp (result,ic,TRUE);
4427 genCmp(right, left, result, ifx, sign);
4429 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4430 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4431 pic16_freeAsmop(result,NULL,ic,TRUE);
4434 /*-----------------------------------------------------------------*/
4435 /* genCmpLt - less than comparisons */
4436 /*-----------------------------------------------------------------*/
4437 static void genCmpLt (iCode *ic, iCode *ifx)
4439 operand *left, *right, *result;
4440 sym_link *letype , *retype;
4443 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4445 right= IC_RIGHT(ic);
4446 result = IC_RESULT(ic);
4448 letype = getSpec(operandType(left));
4449 retype =getSpec(operandType(right));
4450 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4452 /* assign the amsops */
4453 pic16_aopOp (left,ic,FALSE);
4454 pic16_aopOp (right,ic,FALSE);
4455 pic16_aopOp (result,ic,TRUE);
4457 genCmp(left, right, result, ifx, sign);
4459 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4460 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4461 pic16_freeAsmop(result,NULL,ic,TRUE);
4464 /*-----------------------------------------------------------------*/
4465 /* genc16bit2lit - compare a 16 bit value to a literal */
4466 /*-----------------------------------------------------------------*/
4467 static void genc16bit2lit(operand *op, int lit, int offset)
4471 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4472 if( (lit&0xff) == 0)
4477 switch( BYTEofLONG(lit,i)) {
4479 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4482 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4485 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4488 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4489 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4494 switch( BYTEofLONG(lit,i)) {
4496 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4500 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4504 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4507 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4509 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4515 /*-----------------------------------------------------------------*/
4516 /* gencjneshort - compare and jump if not equal */
4517 /*-----------------------------------------------------------------*/
4518 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4520 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4522 int res_offset = 0; /* the result may be a different size then left or right */
4523 int res_size = AOP_SIZE(result);
4527 unsigned long lit = 0L;
4528 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4529 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4531 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4532 resolveIfx(&rIfx,ifx);
4533 lbl = newiTempLabel(NULL);
4536 /* if the left side is a literal or
4537 if the right is in a pointer register and left
4539 if ((AOP_TYPE(left) == AOP_LIT) ||
4540 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4545 if(AOP_TYPE(right) == AOP_LIT)
4546 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4548 /* if the right side is a literal then anything goes */
4549 if (AOP_TYPE(right) == AOP_LIT &&
4550 AOP_TYPE(left) != AOP_DIR ) {
4553 genc16bit2lit(left, lit, 0);
4555 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4560 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4561 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4563 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4567 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4569 if(res_offset < res_size-1)
4577 /* if the right side is in a register or in direct space or
4578 if the left is a pointer register & right is not */
4579 else if (AOP_TYPE(right) == AOP_REG ||
4580 AOP_TYPE(right) == AOP_DIR ||
4581 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4582 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4583 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4584 int lbl_key = lbl->key;
4587 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4588 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4590 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4591 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4592 __FUNCTION__,__LINE__);
4596 /* switch(size) { */
4598 /* genc16bit2lit(left, lit, 0); */
4600 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4605 if((AOP_TYPE(left) == AOP_DIR) &&
4606 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4608 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4609 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4611 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4613 switch (lit & 0xff) {
4615 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4618 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4619 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4620 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4624 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4625 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4626 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4627 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4631 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4632 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4637 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4640 if(AOP_TYPE(result) == AOP_CRY) {
4641 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4646 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4648 /* fix me. probably need to check result size too */
4649 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4654 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4655 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4662 if(res_offset < res_size-1)
4667 } else if(AOP_TYPE(right) == AOP_REG &&
4668 AOP_TYPE(left) != AOP_DIR){
4671 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4672 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4673 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4678 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4680 if(res_offset < res_size-1)
4685 /* right is a pointer reg need both a & b */
4687 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4689 pic16_emitcode("mov","b,%s",l);
4690 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4691 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4696 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4698 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4700 pic16_emitpLabel(lbl->key);
4702 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4709 /*-----------------------------------------------------------------*/
4710 /* gencjne - compare and jump if not equal */
4711 /*-----------------------------------------------------------------*/
4712 static void gencjne(operand *left, operand *right, iCode *ifx)
4714 symbol *tlbl = newiTempLabel(NULL);
4716 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4717 gencjneshort(left, right, lbl);
4719 pic16_emitcode("mov","a,%s",one);
4720 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4721 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4722 pic16_emitcode("clr","a");
4723 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4725 pic16_emitpLabel(lbl->key);
4726 pic16_emitpLabel(tlbl->key);
4731 /*-----------------------------------------------------------------*/
4732 /* genCmpEq - generates code for equal to */
4733 /*-----------------------------------------------------------------*/
4734 static void genCmpEq (iCode *ic, iCode *ifx)
4736 operand *left, *right, *result;
4737 unsigned long lit = 0L;
4740 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4743 DEBUGpic16_emitcode ("; ifx is non-null","");
4745 DEBUGpic16_emitcode ("; ifx is null","");
4747 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4748 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4749 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4751 size = max(AOP_SIZE(left),AOP_SIZE(right));
4753 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4755 /* if literal, literal on the right or
4756 if the right is in a pointer register and left
4758 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4759 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4760 operand *tmp = right ;
4766 if(ifx && !AOP_SIZE(result)){
4768 /* if they are both bit variables */
4769 if (AOP_TYPE(left) == AOP_CRY &&
4770 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4771 if(AOP_TYPE(right) == AOP_LIT){
4772 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4774 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4775 pic16_emitcode("cpl","c");
4776 } else if(lit == 1L) {
4777 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4779 pic16_emitcode("clr","c");
4781 /* AOP_TYPE(right) == AOP_CRY */
4783 symbol *lbl = newiTempLabel(NULL);
4784 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4785 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4786 pic16_emitcode("cpl","c");
4787 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4789 /* if true label then we jump if condition
4791 tlbl = newiTempLabel(NULL);
4792 if ( IC_TRUE(ifx) ) {
4793 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4794 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4796 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4797 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4799 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4802 /* left and right are both bit variables, result is carry */
4805 resolveIfx(&rIfx,ifx);
4807 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4808 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4809 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4810 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4815 /* They're not both bit variables. Is the right a literal? */
4816 if(AOP_TYPE(right) == AOP_LIT) {
4817 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4822 switch(lit & 0xff) {
4824 if ( IC_TRUE(ifx) ) {
4825 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4827 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4829 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4830 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4834 if ( IC_TRUE(ifx) ) {
4835 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4837 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4839 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4840 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4844 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4846 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4851 /* end of size == 1 */
4855 genc16bit2lit(left,lit,offset);
4858 /* end of size == 2 */
4863 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4864 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4865 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4866 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4870 /* search for patterns that can be optimized */
4872 genc16bit2lit(left,lit,0);
4875 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4877 genc16bit2lit(left,lit,2);
4879 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4880 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4893 } else if(AOP_TYPE(right) == AOP_CRY ) {
4894 /* we know the left is not a bit, but that the right is */
4895 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4896 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4897 pic16_popGet(AOP(right),offset));
4898 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4900 /* if the two are equal, then W will be 0 and the Z bit is set
4901 * we could test Z now, or go ahead and check the high order bytes if
4902 * the variable we're comparing is larger than a byte. */
4905 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4907 if ( IC_TRUE(ifx) ) {
4909 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4910 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4913 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4914 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4918 /* They're both variables that are larger than bits */
4921 tlbl = newiTempLabel(NULL);
4924 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4925 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4927 if ( IC_TRUE(ifx) ) {
4930 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4931 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4934 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4935 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4939 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4940 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4944 if(s>1 && IC_TRUE(ifx)) {
4945 pic16_emitpLabel(tlbl->key);
4946 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4950 /* mark the icode as generated */
4955 /* if they are both bit variables */
4956 if (AOP_TYPE(left) == AOP_CRY &&
4957 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4958 if(AOP_TYPE(right) == AOP_LIT){
4959 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4961 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4962 pic16_emitcode("cpl","c");
4963 } else if(lit == 1L) {
4964 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4966 pic16_emitcode("clr","c");
4968 /* AOP_TYPE(right) == AOP_CRY */
4970 symbol *lbl = newiTempLabel(NULL);
4971 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4972 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4973 pic16_emitcode("cpl","c");
4974 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4977 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4978 pic16_outBitC(result);
4982 genIfxJump (ifx,"c");
4985 /* if the result is used in an arithmetic operation
4986 then put the result in place */
4987 pic16_outBitC(result);
4990 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4991 gencjne(left,right,result,ifx);
4994 gencjne(left,right,newiTempLabel(NULL));
4996 if(IC_TRUE(ifx)->key)
4997 gencjne(left,right,IC_TRUE(ifx)->key);
4999 gencjne(left,right,IC_FALSE(ifx)->key);
5003 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5004 pic16_aopPut(AOP(result),"a",0);
5009 genIfxJump (ifx,"a");
5013 /* if the result is used in an arithmetic operation
5014 then put the result in place */
5016 if (AOP_TYPE(result) != AOP_CRY)
5017 pic16_outAcc(result);
5019 /* leave the result in acc */
5023 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5024 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5025 pic16_freeAsmop(result,NULL,ic,TRUE);
5028 /*-----------------------------------------------------------------*/
5029 /* ifxForOp - returns the icode containing the ifx for operand */
5030 /*-----------------------------------------------------------------*/
5031 static iCode *ifxForOp ( operand *op, iCode *ic )
5033 /* if true symbol then needs to be assigned */
5034 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5035 if (IS_TRUE_SYMOP(op))
5038 /* if this has register type condition and
5039 the next instruction is ifx with the same operand
5040 and live to of the operand is upto the ifx only then */
5042 ic->next->op == IFX &&
5043 IC_COND(ic->next)->key == op->key &&
5044 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5048 ic->next->op == IFX &&
5049 IC_COND(ic->next)->key == op->key) {
5050 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5054 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5056 ic->next->op == IFX)
5057 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5060 ic->next->op == IFX &&
5061 IC_COND(ic->next)->key == op->key) {
5062 DEBUGpic16_emitcode ("; "," key is okay");
5063 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5064 OP_SYMBOL(op)->liveTo,
5071 /*-----------------------------------------------------------------*/
5072 /* genAndOp - for && operation */
5073 /*-----------------------------------------------------------------*/
5074 static void genAndOp (iCode *ic)
5076 operand *left,*right, *result;
5079 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5080 /* note here that && operations that are in an
5081 if statement are taken away by backPatchLabels
5082 only those used in arthmetic operations remain */
5083 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5084 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5085 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5087 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5089 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5090 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5091 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5093 /* if both are bit variables */
5094 /* if (AOP_TYPE(left) == AOP_CRY && */
5095 /* AOP_TYPE(right) == AOP_CRY ) { */
5096 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5097 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5098 /* pic16_outBitC(result); */
5100 /* tlbl = newiTempLabel(NULL); */
5101 /* pic16_toBoolean(left); */
5102 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5103 /* pic16_toBoolean(right); */
5104 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5105 /* pic16_outBitAcc(result); */
5108 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5109 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5110 pic16_freeAsmop(result,NULL,ic,TRUE);
5114 /*-----------------------------------------------------------------*/
5115 /* genOrOp - for || operation */
5116 /*-----------------------------------------------------------------*/
5119 modified this code, but it doesn't appear to ever get called
5122 static void genOrOp (iCode *ic)
5124 operand *left,*right, *result;
5127 /* note here that || operations that are in an
5128 if statement are taken away by backPatchLabels
5129 only those used in arthmetic operations remain */
5130 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5131 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5132 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5133 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5135 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5137 /* if both are bit variables */
5138 if (AOP_TYPE(left) == AOP_CRY &&
5139 AOP_TYPE(right) == AOP_CRY ) {
5140 pic16_emitcode("clrc","");
5141 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5142 AOP(left)->aopu.aop_dir,
5143 AOP(left)->aopu.aop_dir);
5144 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5145 AOP(right)->aopu.aop_dir,
5146 AOP(right)->aopu.aop_dir);
5147 pic16_emitcode("setc","");
5150 tlbl = newiTempLabel(NULL);
5151 pic16_toBoolean(left);
5153 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5154 pic16_toBoolean(right);
5155 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5157 pic16_outBitAcc(result);
5160 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5161 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5162 pic16_freeAsmop(result,NULL,ic,TRUE);
5165 /*-----------------------------------------------------------------*/
5166 /* isLiteralBit - test if lit == 2^n */
5167 /*-----------------------------------------------------------------*/
5168 static int isLiteralBit(unsigned long lit)
5170 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5171 0x100L,0x200L,0x400L,0x800L,
5172 0x1000L,0x2000L,0x4000L,0x8000L,
5173 0x10000L,0x20000L,0x40000L,0x80000L,
5174 0x100000L,0x200000L,0x400000L,0x800000L,
5175 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5176 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5179 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5180 for(idx = 0; idx < 32; idx++)
5186 /*-----------------------------------------------------------------*/
5187 /* continueIfTrue - */
5188 /*-----------------------------------------------------------------*/
5189 static void continueIfTrue (iCode *ic)
5191 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5193 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5197 /*-----------------------------------------------------------------*/
5199 /*-----------------------------------------------------------------*/
5200 static void jumpIfTrue (iCode *ic)
5202 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5204 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5208 /*-----------------------------------------------------------------*/
5209 /* jmpTrueOrFalse - */
5210 /*-----------------------------------------------------------------*/
5211 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5213 // ugly but optimized by peephole
5214 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5216 symbol *nlbl = newiTempLabel(NULL);
5217 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5218 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5219 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5220 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5223 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5224 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5229 /*-----------------------------------------------------------------*/
5230 /* genAnd - code for and */
5231 /*-----------------------------------------------------------------*/
5232 static void genAnd (iCode *ic, iCode *ifx)
5234 operand *left, *right, *result;
5236 unsigned long lit = 0L;
5241 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5242 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5243 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5244 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5246 resolveIfx(&rIfx,ifx);
5248 /* if left is a literal & right is not then exchange them */
5249 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5250 AOP_NEEDSACC(left)) {
5251 operand *tmp = right ;
5256 /* if result = right then exchange them */
5257 if(pic16_sameRegs(AOP(result),AOP(right))){
5258 operand *tmp = right ;
5263 /* if right is bit then exchange them */
5264 if (AOP_TYPE(right) == AOP_CRY &&
5265 AOP_TYPE(left) != AOP_CRY){
5266 operand *tmp = right ;
5270 if(AOP_TYPE(right) == AOP_LIT)
5271 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5273 size = AOP_SIZE(result);
5275 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5278 // result = bit & yy;
5279 if (AOP_TYPE(left) == AOP_CRY){
5280 // c = bit & literal;
5281 if(AOP_TYPE(right) == AOP_LIT){
5283 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5286 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5289 if(size && (AOP_TYPE(result) == AOP_CRY)){
5290 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5293 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5297 pic16_emitcode("clr","c");
5300 if (AOP_TYPE(right) == AOP_CRY){
5302 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5303 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5306 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5308 pic16_emitcode("rrc","a");
5309 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5315 pic16_outBitC(result);
5317 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5318 genIfxJump(ifx, "c");
5322 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5323 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5324 if((AOP_TYPE(right) == AOP_LIT) &&
5325 (AOP_TYPE(result) == AOP_CRY) &&
5326 (AOP_TYPE(left) != AOP_CRY)){
5327 int posbit = isLiteralBit(lit);
5331 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5334 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5340 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5341 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5343 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5344 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5347 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5348 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5349 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5356 symbol *tlbl = newiTempLabel(NULL);
5357 int sizel = AOP_SIZE(left);
5359 pic16_emitcode("setb","c");
5361 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5362 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5364 if((posbit = isLiteralBit(bytelit)) != 0)
5365 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5367 if(bytelit != 0x0FFL)
5368 pic16_emitcode("anl","a,%s",
5369 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5370 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5375 // bit = left & literal
5377 pic16_emitcode("clr","c");
5378 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5380 // if(left & literal)
5383 jmpTrueOrFalse(ifx, tlbl);
5387 pic16_outBitC(result);
5391 /* if left is same as result */
5392 if(pic16_sameRegs(AOP(result),AOP(left))){
5394 for(;size--; offset++,lit>>=8) {
5395 if(AOP_TYPE(right) == AOP_LIT){
5396 switch(lit & 0xff) {
5398 /* and'ing with 0 has clears the result */
5399 pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5400 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5403 /* and'ing with 0xff is a nop when the result and left are the same */
5408 int p = my_powof2( (~lit) & 0xff );
5410 /* only one bit is set in the literal, so use a bcf instruction */
5411 pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5412 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5415 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5416 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5417 if(know_W != (lit&0xff))
5418 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5420 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5425 if (AOP_TYPE(left) == AOP_ACC) {
5426 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5428 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5429 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5436 // left & result in different registers
5437 if(AOP_TYPE(result) == AOP_CRY){
5439 // if(size), result in bit
5440 // if(!size && ifx), conditional oper: if(left & right)
5441 symbol *tlbl = newiTempLabel(NULL);
5442 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5444 pic16_emitcode("setb","c");
5446 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5447 pic16_emitcode("anl","a,%s",
5448 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5449 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5454 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5455 pic16_outBitC(result);
5457 jmpTrueOrFalse(ifx, tlbl);
5459 for(;(size--);offset++) {
5461 // result = left & right
5462 if(AOP_TYPE(right) == AOP_LIT){
5463 int t = (lit >> (offset*8)) & 0x0FFL;
5466 pic16_emitcode("clrf","%s",
5467 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5468 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5471 pic16_emitcode("movf","%s,w",
5472 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5473 pic16_emitcode("movwf","%s",
5474 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5475 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5476 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5479 pic16_emitcode("movlw","0x%x",t);
5480 pic16_emitcode("andwf","%s,w",
5481 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5482 pic16_emitcode("movwf","%s",
5483 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5485 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5486 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5487 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5492 if (AOP_TYPE(left) == AOP_ACC) {
5493 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5494 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5496 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5497 pic16_emitcode("andwf","%s,w",
5498 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5499 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5500 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5502 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5503 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5509 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5510 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5511 pic16_freeAsmop(result,NULL,ic,TRUE);
5514 /*-----------------------------------------------------------------*/
5515 /* genOr - code for or */
5516 /*-----------------------------------------------------------------*/
5517 static void genOr (iCode *ic, iCode *ifx)
5519 operand *left, *right, *result;
5521 unsigned long lit = 0L;
5523 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5525 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5526 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5527 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5529 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5531 /* if left is a literal & right is not then exchange them */
5532 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5533 AOP_NEEDSACC(left)) {
5534 operand *tmp = right ;
5539 /* if result = right then exchange them */
5540 if(pic16_sameRegs(AOP(result),AOP(right))){
5541 operand *tmp = right ;
5546 /* if right is bit then exchange them */
5547 if (AOP_TYPE(right) == AOP_CRY &&
5548 AOP_TYPE(left) != AOP_CRY){
5549 operand *tmp = right ;
5554 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5556 if(AOP_TYPE(right) == AOP_LIT)
5557 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5559 size = AOP_SIZE(result);
5563 if (AOP_TYPE(left) == AOP_CRY){
5564 if(AOP_TYPE(right) == AOP_LIT){
5565 // c = bit & literal;
5567 // lit != 0 => result = 1
5568 if(AOP_TYPE(result) == AOP_CRY){
5570 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5571 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5572 // AOP(result)->aopu.aop_dir,
5573 // AOP(result)->aopu.aop_dir);
5575 continueIfTrue(ifx);
5579 // lit == 0 => result = left
5580 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5582 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5585 if (AOP_TYPE(right) == AOP_CRY){
5586 if(pic16_sameRegs(AOP(result),AOP(left))){
5588 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5589 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5590 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5592 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5593 AOP(result)->aopu.aop_dir,
5594 AOP(result)->aopu.aop_dir);
5595 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5596 AOP(right)->aopu.aop_dir,
5597 AOP(right)->aopu.aop_dir);
5598 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5599 AOP(result)->aopu.aop_dir,
5600 AOP(result)->aopu.aop_dir);
5602 if( AOP_TYPE(result) == AOP_ACC) {
5603 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5604 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5605 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5606 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5610 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5611 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5612 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5613 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5615 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5616 AOP(result)->aopu.aop_dir,
5617 AOP(result)->aopu.aop_dir);
5618 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5619 AOP(right)->aopu.aop_dir,
5620 AOP(right)->aopu.aop_dir);
5621 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5622 AOP(left)->aopu.aop_dir,
5623 AOP(left)->aopu.aop_dir);
5624 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5625 AOP(result)->aopu.aop_dir,
5626 AOP(result)->aopu.aop_dir);
5631 symbol *tlbl = newiTempLabel(NULL);
5632 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5635 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5636 if( AOP_TYPE(right) == AOP_ACC) {
5637 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5639 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5640 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5645 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5646 pic16_emitcode(";XXX setb","c");
5647 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5648 AOP(left)->aopu.aop_dir,tlbl->key+100);
5649 pic16_toBoolean(right);
5650 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5651 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5652 jmpTrueOrFalse(ifx, tlbl);
5656 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5663 pic16_outBitC(result);
5665 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5666 genIfxJump(ifx, "c");
5670 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5671 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5672 if((AOP_TYPE(right) == AOP_LIT) &&
5673 (AOP_TYPE(result) == AOP_CRY) &&
5674 (AOP_TYPE(left) != AOP_CRY)){
5676 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5679 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5681 continueIfTrue(ifx);
5684 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5685 // lit = 0, result = boolean(left)
5687 pic16_emitcode(";XXX setb","c");
5688 pic16_toBoolean(right);
5690 symbol *tlbl = newiTempLabel(NULL);
5691 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5693 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5695 genIfxJump (ifx,"a");
5699 pic16_outBitC(result);
5703 /* if left is same as result */
5704 if(pic16_sameRegs(AOP(result),AOP(left))){
5706 for(;size--; offset++,lit>>=8) {
5707 if(AOP_TYPE(right) == AOP_LIT){
5708 if((lit & 0xff) == 0)
5709 /* or'ing with 0 has no effect */
5712 int p = my_powof2(lit & 0xff);
5714 /* only one bit is set in the literal, so use a bsf instruction */
5715 pic16_emitpcode(POC_BSF,
5716 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5718 if(know_W != (lit & 0xff))
5719 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5720 know_W = lit & 0xff;
5721 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5726 if (AOP_TYPE(left) == AOP_ACC) {
5727 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5728 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5730 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5731 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5733 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5734 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5740 // left & result in different registers
5741 if(AOP_TYPE(result) == AOP_CRY){
5743 // if(size), result in bit
5744 // if(!size && ifx), conditional oper: if(left | right)
5745 symbol *tlbl = newiTempLabel(NULL);
5746 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5747 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5751 pic16_emitcode(";XXX setb","c");
5753 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5754 pic16_emitcode(";XXX orl","a,%s",
5755 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5756 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5761 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5762 pic16_outBitC(result);
5764 jmpTrueOrFalse(ifx, tlbl);
5765 } else for(;(size--);offset++){
5767 // result = left & right
5768 if(AOP_TYPE(right) == AOP_LIT){
5769 int t = (lit >> (offset*8)) & 0x0FFL;
5772 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5773 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5775 pic16_emitcode("movf","%s,w",
5776 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5777 pic16_emitcode("movwf","%s",
5778 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5781 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5782 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5783 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5785 pic16_emitcode("movlw","0x%x",t);
5786 pic16_emitcode("iorwf","%s,w",
5787 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5788 pic16_emitcode("movwf","%s",
5789 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5795 // faster than result <- left, anl result,right
5796 // and better if result is SFR
5797 if (AOP_TYPE(left) == AOP_ACC) {
5798 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5799 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5801 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5802 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5804 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5805 pic16_emitcode("iorwf","%s,w",
5806 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5808 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5809 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5814 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5815 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5816 pic16_freeAsmop(result,NULL,ic,TRUE);
5819 /*-----------------------------------------------------------------*/
5820 /* genXor - code for xclusive or */
5821 /*-----------------------------------------------------------------*/
5822 static void genXor (iCode *ic, iCode *ifx)
5824 operand *left, *right, *result;
5826 unsigned long lit = 0L;
5828 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5830 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5831 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5832 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5834 /* if left is a literal & right is not ||
5835 if left needs acc & right does not */
5836 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5837 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5838 operand *tmp = right ;
5843 /* if result = right then exchange them */
5844 if(pic16_sameRegs(AOP(result),AOP(right))){
5845 operand *tmp = right ;
5850 /* if right is bit then exchange them */
5851 if (AOP_TYPE(right) == AOP_CRY &&
5852 AOP_TYPE(left) != AOP_CRY){
5853 operand *tmp = right ;
5857 if(AOP_TYPE(right) == AOP_LIT)
5858 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5860 size = AOP_SIZE(result);
5864 if (AOP_TYPE(left) == AOP_CRY){
5865 if(AOP_TYPE(right) == AOP_LIT){
5866 // c = bit & literal;
5868 // lit>>1 != 0 => result = 1
5869 if(AOP_TYPE(result) == AOP_CRY){
5871 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
5872 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5874 continueIfTrue(ifx);
5877 pic16_emitcode("setb","c");
5881 // lit == 0, result = left
5882 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5884 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5886 // lit == 1, result = not(left)
5887 if(size && pic16_sameRegs(AOP(result),AOP(left))){
5888 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
5889 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
5890 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5893 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5894 pic16_emitcode("cpl","c");
5901 symbol *tlbl = newiTempLabel(NULL);
5902 if (AOP_TYPE(right) == AOP_CRY){
5904 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5907 int sizer = AOP_SIZE(right);
5909 // if val>>1 != 0, result = 1
5910 pic16_emitcode("setb","c");
5912 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5914 // test the msb of the lsb
5915 pic16_emitcode("anl","a,#0xfe");
5916 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5920 pic16_emitcode("rrc","a");
5922 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5923 pic16_emitcode("cpl","c");
5924 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5929 pic16_outBitC(result);
5931 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5932 genIfxJump(ifx, "c");
5936 if(pic16_sameRegs(AOP(result),AOP(left))){
5937 /* if left is same as result */
5938 for(;size--; offset++) {
5939 if(AOP_TYPE(right) == AOP_LIT){
5940 int t = (lit >> (offset*8)) & 0x0FFL;
5944 if (IS_AOP_PREG(left)) {
5945 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5946 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5947 pic16_aopPut(AOP(result),"a",offset);
5949 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5950 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5951 pic16_emitcode("xrl","%s,%s",
5952 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5953 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5956 if (AOP_TYPE(left) == AOP_ACC)
5957 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5959 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5960 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5962 if (IS_AOP_PREG(left)) {
5963 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5964 pic16_aopPut(AOP(result),"a",offset);
5966 pic16_emitcode("xrl","%s,a",
5967 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5973 // left & result in different registers
5974 if(AOP_TYPE(result) == AOP_CRY){
5976 // if(size), result in bit
5977 // if(!size && ifx), conditional oper: if(left ^ right)
5978 symbol *tlbl = newiTempLabel(NULL);
5979 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5981 pic16_emitcode("setb","c");
5983 if((AOP_TYPE(right) == AOP_LIT) &&
5984 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5985 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5987 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5988 pic16_emitcode("xrl","a,%s",
5989 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5991 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5996 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5997 pic16_outBitC(result);
5999 jmpTrueOrFalse(ifx, tlbl);
6000 } else for(;(size--);offset++){
6002 // result = left & right
6003 if(AOP_TYPE(right) == AOP_LIT){
6004 int t = (lit >> (offset*8)) & 0x0FFL;
6007 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6008 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6009 pic16_emitcode("movf","%s,w",
6010 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6011 pic16_emitcode("movwf","%s",
6012 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6015 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6016 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6017 pic16_emitcode("comf","%s,w",
6018 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6019 pic16_emitcode("movwf","%s",
6020 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6023 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6024 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6025 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6026 pic16_emitcode("movlw","0x%x",t);
6027 pic16_emitcode("xorwf","%s,w",
6028 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6029 pic16_emitcode("movwf","%s",
6030 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6036 // faster than result <- left, anl result,right
6037 // and better if result is SFR
6038 if (AOP_TYPE(left) == AOP_ACC) {
6039 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6040 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6042 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6043 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6044 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6045 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6047 if ( AOP_TYPE(result) != AOP_ACC){
6048 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6049 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6055 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6056 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6057 pic16_freeAsmop(result,NULL,ic,TRUE);
6060 /*-----------------------------------------------------------------*/
6061 /* genInline - write the inline code out */
6062 /*-----------------------------------------------------------------*/
6063 static void genInline (iCode *ic)
6065 char *buffer, *bp, *bp1;
6067 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6069 _G.inLine += (!options.asmpeep);
6071 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6072 strcpy(buffer,IC_INLINE(ic));
6074 /* emit each line as a code */
6080 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6087 pic16_emitcode(bp1,"");
6093 if ((bp1 != bp) && *bp1)
6094 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6098 _G.inLine -= (!options.asmpeep);
6101 /*-----------------------------------------------------------------*/
6102 /* genRRC - rotate right with carry */
6103 /*-----------------------------------------------------------------*/
6104 static void genRRC (iCode *ic)
6106 operand *left , *result ;
6107 int size, offset = 0, same;
6109 /* rotate right with carry */
6111 result=IC_RESULT(ic);
6112 pic16_aopOp (left,ic,FALSE);
6113 pic16_aopOp (result,ic,FALSE);
6115 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6117 same = pic16_sameRegs(AOP(result),AOP(left));
6119 size = AOP_SIZE(result);
6121 /* get the lsb and put it into the carry */
6122 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6129 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6131 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6132 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6138 pic16_freeAsmop(left,NULL,ic,TRUE);
6139 pic16_freeAsmop(result,NULL,ic,TRUE);
6142 /*-----------------------------------------------------------------*/
6143 /* genRLC - generate code for rotate left with carry */
6144 /*-----------------------------------------------------------------*/
6145 static void genRLC (iCode *ic)
6147 operand *left , *result ;
6148 int size, offset = 0;
6151 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6152 /* rotate right with carry */
6154 result=IC_RESULT(ic);
6155 pic16_aopOp (left,ic,FALSE);
6156 pic16_aopOp (result,ic,FALSE);
6158 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6160 same = pic16_sameRegs(AOP(result),AOP(left));
6162 /* move it to the result */
6163 size = AOP_SIZE(result);
6165 /* get the msb and put it into the carry */
6166 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6173 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6175 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6176 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6183 pic16_freeAsmop(left,NULL,ic,TRUE);
6184 pic16_freeAsmop(result,NULL,ic,TRUE);
6187 /*-----------------------------------------------------------------*/
6188 /* genGetHbit - generates code get highest order bit */
6189 /*-----------------------------------------------------------------*/
6190 static void genGetHbit (iCode *ic)
6192 operand *left, *result;
6194 result=IC_RESULT(ic);
6195 pic16_aopOp (left,ic,FALSE);
6196 pic16_aopOp (result,ic,FALSE);
6198 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6199 /* get the highest order byte into a */
6200 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6201 if(AOP_TYPE(result) == AOP_CRY){
6202 pic16_emitcode("rlc","a");
6203 pic16_outBitC(result);
6206 pic16_emitcode("rl","a");
6207 pic16_emitcode("anl","a,#0x01");
6208 pic16_outAcc(result);
6212 pic16_freeAsmop(left,NULL,ic,TRUE);
6213 pic16_freeAsmop(result,NULL,ic,TRUE);
6216 /*-----------------------------------------------------------------*/
6217 /* AccRol - rotate left accumulator by known count */
6218 /*-----------------------------------------------------------------*/
6219 static void AccRol (int shCount)
6221 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6222 shCount &= 0x0007; // shCount : 0..7
6227 pic16_emitcode("rl","a");
6230 pic16_emitcode("rl","a");
6231 pic16_emitcode("rl","a");
6234 pic16_emitcode("swap","a");
6235 pic16_emitcode("rr","a");
6238 pic16_emitcode("swap","a");
6241 pic16_emitcode("swap","a");
6242 pic16_emitcode("rl","a");
6245 pic16_emitcode("rr","a");
6246 pic16_emitcode("rr","a");
6249 pic16_emitcode("rr","a");
6254 /*-----------------------------------------------------------------*/
6255 /* AccLsh - left shift accumulator by known count */
6256 /*-----------------------------------------------------------------*/
6257 static void AccLsh (int shCount)
6259 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6262 pic16_emitcode("add","a,acc");
6265 pic16_emitcode("add","a,acc");
6266 pic16_emitcode("add","a,acc");
6268 /* rotate left accumulator */
6270 /* and kill the lower order bits */
6271 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6276 /*-----------------------------------------------------------------*/
6277 /* AccRsh - right shift accumulator by known count */
6278 /*-----------------------------------------------------------------*/
6279 static void AccRsh (int shCount)
6281 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6285 pic16_emitcode("rrc","a");
6287 /* rotate right accumulator */
6288 AccRol(8 - shCount);
6289 /* and kill the higher order bits */
6290 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6296 /*-----------------------------------------------------------------*/
6297 /* AccSRsh - signed right shift accumulator by known count */
6298 /*-----------------------------------------------------------------*/
6299 static void AccSRsh (int shCount)
6302 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6305 pic16_emitcode("mov","c,acc.7");
6306 pic16_emitcode("rrc","a");
6307 } else if(shCount == 2){
6308 pic16_emitcode("mov","c,acc.7");
6309 pic16_emitcode("rrc","a");
6310 pic16_emitcode("mov","c,acc.7");
6311 pic16_emitcode("rrc","a");
6313 tlbl = newiTempLabel(NULL);
6314 /* rotate right accumulator */
6315 AccRol(8 - shCount);
6316 /* and kill the higher order bits */
6317 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6318 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6319 pic16_emitcode("orl","a,#0x%02x",
6320 (unsigned char)~SRMask[shCount]);
6321 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6326 /*-----------------------------------------------------------------*/
6327 /* shiftR1Left2Result - shift right one byte from left to result */
6328 /*-----------------------------------------------------------------*/
6329 static void shiftR1Left2ResultSigned (operand *left, int offl,
6330 operand *result, int offr,
6335 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6337 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6341 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6343 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6345 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6346 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6352 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6354 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6356 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6357 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6359 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6360 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6366 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6368 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6369 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6372 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6373 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6374 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6376 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6377 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6379 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6383 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6384 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6385 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6386 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6387 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6391 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6393 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6394 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6396 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6397 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6398 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6399 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6400 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6405 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6406 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6407 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6408 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6409 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6410 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6412 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6413 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6414 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6415 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6416 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6422 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6423 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6424 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6425 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6427 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6428 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6429 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6437 /*-----------------------------------------------------------------*/
6438 /* shiftR1Left2Result - shift right one byte from left to result */
6439 /*-----------------------------------------------------------------*/
6440 static void shiftR1Left2Result (operand *left, int offl,
6441 operand *result, int offr,
6442 int shCount, int sign)
6446 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6448 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6450 /* Copy the msb into the carry if signed. */
6452 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6462 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6464 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6465 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6471 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6473 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6474 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6477 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6482 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6484 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6485 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6488 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6489 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6490 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6491 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6495 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6496 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6497 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6501 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6502 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6503 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6505 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6510 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6511 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6512 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6513 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6514 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6519 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6520 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6521 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6530 /*-----------------------------------------------------------------*/
6531 /* shiftL1Left2Result - shift left one byte from left to result */
6532 /*-----------------------------------------------------------------*/
6533 static void shiftL1Left2Result (operand *left, int offl,
6534 operand *result, int offr, int shCount)
6539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6541 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6542 DEBUGpic16_emitcode ("; ***","same = %d",same);
6543 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6545 /* shift left accumulator */
6546 //AccLsh(shCount); // don't comment out just yet...
6547 // pic16_aopPut(AOP(result),"a",offr);
6551 /* Shift left 1 bit position */
6552 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6554 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6556 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6557 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6561 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6562 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6563 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6564 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6567 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6568 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6569 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6570 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6571 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6574 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6575 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6576 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6579 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6580 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6581 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6582 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6585 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6586 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6587 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6588 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6589 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6592 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6593 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6594 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6598 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6603 /*-----------------------------------------------------------------*/
6604 /* movLeft2Result - move byte from left to result */
6605 /*-----------------------------------------------------------------*/
6606 static void movLeft2Result (operand *left, int offl,
6607 operand *result, int offr)
6610 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6611 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6612 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6614 if (*l == '@' && (IS_AOP_PREG(result))) {
6615 pic16_emitcode("mov","a,%s",l);
6616 pic16_aopPut(AOP(result),"a",offr);
6618 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6619 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6624 /*-----------------------------------------------------------------*/
6625 /* shiftL2Left2Result - shift left two bytes from left to result */
6626 /*-----------------------------------------------------------------*/
6627 static void shiftL2Left2Result (operand *left, int offl,
6628 operand *result, int offr, int shCount)
6632 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6634 if(pic16_sameRegs(AOP(result), AOP(left))) {
6642 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6643 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6644 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6648 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6649 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6655 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6656 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6657 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6658 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6659 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6660 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6661 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6663 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6664 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6668 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6669 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6670 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6671 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6672 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6673 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6674 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6675 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6676 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6677 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6680 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6681 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6682 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6683 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6684 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6694 /* note, use a mov/add for the shift since the mov has a
6695 chance of getting optimized out */
6696 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6697 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6698 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6699 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6700 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6704 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6705 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6711 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6712 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6713 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6714 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6715 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6716 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6717 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6718 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6722 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6723 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6727 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6728 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6729 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6730 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6732 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6733 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6734 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6735 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6736 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6737 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6738 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6739 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6742 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6743 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6744 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6745 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6746 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6751 /*-----------------------------------------------------------------*/
6752 /* shiftR2Left2Result - shift right two bytes from left to result */
6753 /*-----------------------------------------------------------------*/
6754 static void shiftR2Left2Result (operand *left, int offl,
6755 operand *result, int offr,
6756 int shCount, int sign)
6760 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6761 same = pic16_sameRegs(AOP(result), AOP(left));
6763 if(same && ((offl + MSB16) == offr)){
6765 /* don't crash result[offr] */
6766 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6767 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6770 movLeft2Result(left,offl, result, offr);
6771 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6774 /* a:x >> shCount (x = lsb(result))*/
6777 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6779 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6788 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6793 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6794 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6796 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6797 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6798 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6799 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6804 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));
6815 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6816 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6817 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6819 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6820 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6821 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6822 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6824 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6825 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6826 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6828 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6829 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6830 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6831 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6832 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6836 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6837 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6841 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6842 pic16_emitpcode(POC_BTFSC,
6843 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6844 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6852 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6853 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6855 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6856 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6857 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6858 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6860 pic16_emitpcode(POC_BTFSC,
6861 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6862 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6864 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6865 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6866 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6867 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6869 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6870 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6871 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6872 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6873 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6874 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6875 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6876 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6878 pic16_emitpcode(POC_BTFSC,
6879 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6880 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6882 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6883 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6890 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6891 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6892 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6893 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6896 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6898 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6903 /*-----------------------------------------------------------------*/
6904 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6905 /*-----------------------------------------------------------------*/
6906 static void shiftLLeftOrResult (operand *left, int offl,
6907 operand *result, int offr, int shCount)
6909 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6910 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6911 /* shift left accumulator */
6913 /* or with result */
6914 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6915 /* back to result */
6916 pic16_aopPut(AOP(result),"a",offr);
6919 /*-----------------------------------------------------------------*/
6920 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6921 /*-----------------------------------------------------------------*/
6922 static void shiftRLeftOrResult (operand *left, int offl,
6923 operand *result, int offr, int shCount)
6925 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6926 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6927 /* shift right accumulator */
6929 /* or with result */
6930 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6931 /* back to result */
6932 pic16_aopPut(AOP(result),"a",offr);
6935 /*-----------------------------------------------------------------*/
6936 /* genlshOne - left shift a one byte quantity by known count */
6937 /*-----------------------------------------------------------------*/
6938 static void genlshOne (operand *result, operand *left, int shCount)
6940 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6941 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6944 /*-----------------------------------------------------------------*/
6945 /* genlshTwo - left shift two bytes by known amount != 0 */
6946 /*-----------------------------------------------------------------*/
6947 static void genlshTwo (operand *result,operand *left, int shCount)
6951 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6952 size = pic16_getDataSize(result);
6954 /* if shCount >= 8 */
6960 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6962 movLeft2Result(left, LSB, result, MSB16);
6964 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6967 /* 1 <= shCount <= 7 */
6970 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6972 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6976 /*-----------------------------------------------------------------*/
6977 /* shiftLLong - shift left one long from left to result */
6978 /* offl = LSB or MSB16 */
6979 /*-----------------------------------------------------------------*/
6980 static void shiftLLong (operand *left, operand *result, int offr )
6983 int size = AOP_SIZE(result);
6985 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6986 if(size >= LSB+offr){
6987 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
6989 pic16_emitcode("add","a,acc");
6990 if (pic16_sameRegs(AOP(left),AOP(result)) &&
6991 size >= MSB16+offr && offr != LSB )
6992 pic16_emitcode("xch","a,%s",
6993 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6995 pic16_aopPut(AOP(result),"a",LSB+offr);
6998 if(size >= MSB16+offr){
6999 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7000 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7003 pic16_emitcode("rlc","a");
7004 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7005 size >= MSB24+offr && offr != LSB)
7006 pic16_emitcode("xch","a,%s",
7007 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7009 pic16_aopPut(AOP(result),"a",MSB16+offr);
7012 if(size >= MSB24+offr){
7013 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7014 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7017 pic16_emitcode("rlc","a");
7018 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7019 size >= MSB32+offr && offr != LSB )
7020 pic16_emitcode("xch","a,%s",
7021 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7023 pic16_aopPut(AOP(result),"a",MSB24+offr);
7026 if(size > MSB32+offr){
7027 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7028 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7031 pic16_emitcode("rlc","a");
7032 pic16_aopPut(AOP(result),"a",MSB32+offr);
7035 pic16_aopPut(AOP(result),zero,LSB);
7038 /*-----------------------------------------------------------------*/
7039 /* genlshFour - shift four byte by a known amount != 0 */
7040 /*-----------------------------------------------------------------*/
7041 static void genlshFour (operand *result, operand *left, int shCount)
7045 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7046 size = AOP_SIZE(result);
7048 /* if shifting more that 3 bytes */
7049 if (shCount >= 24 ) {
7052 /* lowest order of left goes to the highest
7053 order of the destination */
7054 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7056 movLeft2Result(left, LSB, result, MSB32);
7057 pic16_aopPut(AOP(result),zero,LSB);
7058 pic16_aopPut(AOP(result),zero,MSB16);
7059 pic16_aopPut(AOP(result),zero,MSB32);
7063 /* more than two bytes */
7064 else if ( shCount >= 16 ) {
7065 /* lower order two bytes goes to higher order two bytes */
7067 /* if some more remaining */
7069 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7071 movLeft2Result(left, MSB16, result, MSB32);
7072 movLeft2Result(left, LSB, result, MSB24);
7074 pic16_aopPut(AOP(result),zero,MSB16);
7075 pic16_aopPut(AOP(result),zero,LSB);
7079 /* if more than 1 byte */
7080 else if ( shCount >= 8 ) {
7081 /* lower order three bytes goes to higher order three bytes */
7085 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7087 movLeft2Result(left, LSB, result, MSB16);
7089 else{ /* size = 4 */
7091 movLeft2Result(left, MSB24, result, MSB32);
7092 movLeft2Result(left, MSB16, result, MSB24);
7093 movLeft2Result(left, LSB, result, MSB16);
7094 pic16_aopPut(AOP(result),zero,LSB);
7096 else if(shCount == 1)
7097 shiftLLong(left, result, MSB16);
7099 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7100 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7101 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7102 pic16_aopPut(AOP(result),zero,LSB);
7107 /* 1 <= shCount <= 7 */
7108 else if(shCount <= 2){
7109 shiftLLong(left, result, LSB);
7111 shiftLLong(result, result, LSB);
7113 /* 3 <= shCount <= 7, optimize */
7115 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7116 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7117 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7121 /*-----------------------------------------------------------------*/
7122 /* genLeftShiftLiteral - left shifting by known count */
7123 /*-----------------------------------------------------------------*/
7124 static void genLeftShiftLiteral (operand *left,
7129 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7132 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7133 pic16_freeAsmop(right,NULL,ic,TRUE);
7135 pic16_aopOp(left,ic,FALSE);
7136 pic16_aopOp(result,ic,FALSE);
7138 size = getSize(operandType(result));
7141 pic16_emitcode("; shift left ","result %d, left %d",size,
7145 /* I suppose that the left size >= result size */
7148 movLeft2Result(left, size, result, size);
7152 else if(shCount >= (size * 8))
7154 pic16_aopPut(AOP(result),zero,size);
7158 genlshOne (result,left,shCount);
7163 genlshTwo (result,left,shCount);
7167 genlshFour (result,left,shCount);
7171 pic16_freeAsmop(left,NULL,ic,TRUE);
7172 pic16_freeAsmop(result,NULL,ic,TRUE);
7175 /*-----------------------------------------------------------------*
7176 * genMultiAsm - repeat assembly instruction for size of register.
7177 * if endian == 1, then the high byte (i.e base address + size of
7178 * register) is used first else the low byte is used first;
7179 *-----------------------------------------------------------------*/
7180 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7185 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7198 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7203 /*-----------------------------------------------------------------*/
7204 /* genLeftShift - generates code for left shifting */
7205 /*-----------------------------------------------------------------*/
7206 static void genLeftShift (iCode *ic)
7208 operand *left,*right, *result;
7211 symbol *tlbl , *tlbl1;
7214 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7216 right = IC_RIGHT(ic);
7218 result = IC_RESULT(ic);
7220 pic16_aopOp(right,ic,FALSE);
7222 /* if the shift count is known then do it
7223 as efficiently as possible */
7224 if (AOP_TYPE(right) == AOP_LIT) {
7225 genLeftShiftLiteral (left,right,result,ic);
7229 /* shift count is unknown then we have to form
7230 a loop get the loop count in B : Note: we take
7231 only the lower order byte since shifting
7232 more that 32 bits make no sense anyway, ( the
7233 largest size of an object can be only 32 bits ) */
7236 pic16_aopOp(left,ic,FALSE);
7237 pic16_aopOp(result,ic,FALSE);
7239 /* now move the left to the result if they are not the
7241 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7242 AOP_SIZE(result) > 1) {
7244 size = AOP_SIZE(result);
7247 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7248 if (*l == '@' && (IS_AOP_PREG(result))) {
7250 pic16_emitcode("mov","a,%s",l);
7251 pic16_aopPut(AOP(result),"a",offset);
7253 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7254 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7255 //pic16_aopPut(AOP(result),l,offset);
7261 size = AOP_SIZE(result);
7263 /* if it is only one byte then */
7265 if(optimized_for_speed) {
7266 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7267 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7268 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7269 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7270 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7271 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7272 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7273 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7274 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7275 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7276 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7277 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7280 tlbl = newiTempLabel(NULL);
7281 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7282 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7283 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7286 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7287 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7288 pic16_emitpLabel(tlbl->key);
7289 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7290 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7292 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7297 if (pic16_sameRegs(AOP(left),AOP(result))) {
7299 tlbl = newiTempLabel(NULL);
7300 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7301 genMultiAsm(POC_RRCF, result, size,1);
7302 pic16_emitpLabel(tlbl->key);
7303 genMultiAsm(POC_RLCF, result, size,0);
7304 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7306 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7310 //tlbl = newiTempLabel(NULL);
7312 //tlbl1 = newiTempLabel(NULL);
7314 //reAdjustPreg(AOP(result));
7316 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7317 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7318 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7320 //pic16_emitcode("add","a,acc");
7321 //pic16_aopPut(AOP(result),"a",offset++);
7323 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7325 // pic16_emitcode("rlc","a");
7326 // pic16_aopPut(AOP(result),"a",offset++);
7328 //reAdjustPreg(AOP(result));
7330 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7331 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7334 tlbl = newiTempLabel(NULL);
7335 tlbl1= newiTempLabel(NULL);
7337 size = AOP_SIZE(result);
7340 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7342 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7344 /* offset should be 0, 1 or 3 */
7345 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7347 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7349 pic16_emitpcode(POC_MOVWF, pctemp);
7352 pic16_emitpLabel(tlbl->key);
7355 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7357 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7359 pic16_emitpcode(POC_DECFSZ, pctemp);
7360 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7361 pic16_emitpLabel(tlbl1->key);
7363 pic16_popReleaseTempReg(pctemp);
7367 pic16_freeAsmop (right,NULL,ic,TRUE);
7368 pic16_freeAsmop(left,NULL,ic,TRUE);
7369 pic16_freeAsmop(result,NULL,ic,TRUE);
7372 /*-----------------------------------------------------------------*/
7373 /* genrshOne - right shift a one byte quantity by known count */
7374 /*-----------------------------------------------------------------*/
7375 static void genrshOne (operand *result, operand *left,
7376 int shCount, int sign)
7378 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7379 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7382 /*-----------------------------------------------------------------*/
7383 /* genrshTwo - right shift two bytes by known amount != 0 */
7384 /*-----------------------------------------------------------------*/
7385 static void genrshTwo (operand *result,operand *left,
7386 int shCount, int sign)
7388 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7389 /* if shCount >= 8 */
7393 shiftR1Left2Result(left, MSB16, result, LSB,
7396 movLeft2Result(left, MSB16, result, LSB);
7398 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7401 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7402 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7406 /* 1 <= shCount <= 7 */
7408 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7411 /*-----------------------------------------------------------------*/
7412 /* shiftRLong - shift right one long from left to result */
7413 /* offl = LSB or MSB16 */
7414 /*-----------------------------------------------------------------*/
7415 static void shiftRLong (operand *left, int offl,
7416 operand *result, int sign)
7418 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7420 pic16_emitcode("clr","c");
7421 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7423 pic16_emitcode("mov","c,acc.7");
7424 pic16_emitcode("rrc","a");
7425 pic16_aopPut(AOP(result),"a",MSB32-offl);
7427 /* add sign of "a" */
7428 pic16_addSign(result, MSB32, sign);
7430 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7431 pic16_emitcode("rrc","a");
7432 pic16_aopPut(AOP(result),"a",MSB24-offl);
7434 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7435 pic16_emitcode("rrc","a");
7436 pic16_aopPut(AOP(result),"a",MSB16-offl);
7439 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7440 pic16_emitcode("rrc","a");
7441 pic16_aopPut(AOP(result),"a",LSB);
7445 /*-----------------------------------------------------------------*/
7446 /* genrshFour - shift four byte by a known amount != 0 */
7447 /*-----------------------------------------------------------------*/
7448 static void genrshFour (operand *result, operand *left,
7449 int shCount, int sign)
7451 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7452 /* if shifting more that 3 bytes */
7453 if(shCount >= 24 ) {
7456 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7458 movLeft2Result(left, MSB32, result, LSB);
7460 pic16_addSign(result, MSB16, sign);
7462 else if(shCount >= 16){
7465 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7467 movLeft2Result(left, MSB24, result, LSB);
7468 movLeft2Result(left, MSB32, result, MSB16);
7470 pic16_addSign(result, MSB24, sign);
7472 else if(shCount >= 8){
7475 shiftRLong(left, MSB16, result, sign);
7476 else if(shCount == 0){
7477 movLeft2Result(left, MSB16, result, LSB);
7478 movLeft2Result(left, MSB24, result, MSB16);
7479 movLeft2Result(left, MSB32, result, MSB24);
7480 pic16_addSign(result, MSB32, sign);
7483 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7484 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7485 /* the last shift is signed */
7486 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7487 pic16_addSign(result, MSB32, sign);
7490 else{ /* 1 <= shCount <= 7 */
7492 shiftRLong(left, LSB, result, sign);
7494 shiftRLong(result, LSB, result, sign);
7497 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7498 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7499 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7504 /*-----------------------------------------------------------------*/
7505 /* genRightShiftLiteral - right shifting by known count */
7506 /*-----------------------------------------------------------------*/
7507 static void genRightShiftLiteral (operand *left,
7513 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7516 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7517 pic16_freeAsmop(right,NULL,ic,TRUE);
7519 pic16_aopOp(left,ic,FALSE);
7520 pic16_aopOp(result,ic,FALSE);
7523 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7527 lsize = pic16_getDataSize(left);
7528 res_size = pic16_getDataSize(result);
7529 /* test the LEFT size !!! */
7531 /* I suppose that the left size >= result size */
7534 movLeft2Result(left, lsize, result, res_size);
7537 else if(shCount >= (lsize * 8)){
7540 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7542 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7543 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7548 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7549 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7550 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7552 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7557 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7564 genrshOne (result,left,shCount,sign);
7568 genrshTwo (result,left,shCount,sign);
7572 genrshFour (result,left,shCount,sign);
7580 pic16_freeAsmop(left,NULL,ic,TRUE);
7581 pic16_freeAsmop(result,NULL,ic,TRUE);
7584 /*-----------------------------------------------------------------*/
7585 /* genSignedRightShift - right shift of signed number */
7586 /*-----------------------------------------------------------------*/
7587 static void genSignedRightShift (iCode *ic)
7589 operand *right, *left, *result;
7592 symbol *tlbl, *tlbl1 ;
7595 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7597 /* we do it the hard way put the shift count in b
7598 and loop thru preserving the sign */
7599 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7601 right = IC_RIGHT(ic);
7603 result = IC_RESULT(ic);
7605 pic16_aopOp(right,ic,FALSE);
7606 pic16_aopOp(left,ic,FALSE);
7607 pic16_aopOp(result,ic,FALSE);
7610 if ( AOP_TYPE(right) == AOP_LIT) {
7611 genRightShiftLiteral (left,right,result,ic,1);
7614 /* shift count is unknown then we have to form
7615 a loop get the loop count in B : Note: we take
7616 only the lower order byte since shifting
7617 more that 32 bits make no sense anyway, ( the
7618 largest size of an object can be only 32 bits ) */
7620 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7621 //pic16_emitcode("inc","b");
7622 //pic16_freeAsmop (right,NULL,ic,TRUE);
7623 //pic16_aopOp(left,ic,FALSE);
7624 //pic16_aopOp(result,ic,FALSE);
7626 /* now move the left to the result if they are not the
7628 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7629 AOP_SIZE(result) > 1) {
7631 size = AOP_SIZE(result);
7635 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7636 if (*l == '@' && IS_AOP_PREG(result)) {
7638 pic16_emitcode("mov","a,%s",l);
7639 pic16_aopPut(AOP(result),"a",offset);
7641 pic16_aopPut(AOP(result),l,offset);
7643 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7644 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7650 /* mov the highest order bit to OVR */
7651 tlbl = newiTempLabel(NULL);
7652 tlbl1= newiTempLabel(NULL);
7654 size = AOP_SIZE(result);
7657 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7659 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7661 /* offset should be 0, 1 or 3 */
7662 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7664 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7666 pic16_emitpcode(POC_MOVWF, pctemp);
7669 pic16_emitpLabel(tlbl->key);
7671 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7672 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7675 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7678 pic16_emitpcode(POC_DECFSZ, pctemp);
7679 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7680 pic16_emitpLabel(tlbl1->key);
7682 pic16_popReleaseTempReg(pctemp);
7684 size = AOP_SIZE(result);
7686 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7687 pic16_emitcode("rlc","a");
7688 pic16_emitcode("mov","ov,c");
7689 /* if it is only one byte then */
7691 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7693 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7694 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7695 pic16_emitcode("mov","c,ov");
7696 pic16_emitcode("rrc","a");
7697 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7698 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7699 pic16_aopPut(AOP(result),"a",0);
7703 reAdjustPreg(AOP(result));
7704 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7705 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7706 pic16_emitcode("mov","c,ov");
7708 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7710 pic16_emitcode("rrc","a");
7711 pic16_aopPut(AOP(result),"a",offset--);
7713 reAdjustPreg(AOP(result));
7714 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7715 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7720 pic16_freeAsmop(left,NULL,ic,TRUE);
7721 pic16_freeAsmop(result,NULL,ic,TRUE);
7722 pic16_freeAsmop(right,NULL,ic,TRUE);
7725 /*-----------------------------------------------------------------*/
7726 /* genRightShift - generate code for right shifting */
7727 /*-----------------------------------------------------------------*/
7728 static void genRightShift (iCode *ic)
7730 operand *right, *left, *result;
7734 symbol *tlbl, *tlbl1 ;
7736 /* if signed then we do it the hard way preserve the
7737 sign bit moving it inwards */
7738 retype = getSpec(operandType(IC_RESULT(ic)));
7739 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7741 if (!SPEC_USIGN(retype)) {
7742 genSignedRightShift (ic);
7746 /* signed & unsigned types are treated the same : i.e. the
7747 signed is NOT propagated inwards : quoting from the
7748 ANSI - standard : "for E1 >> E2, is equivalent to division
7749 by 2**E2 if unsigned or if it has a non-negative value,
7750 otherwise the result is implementation defined ", MY definition
7751 is that the sign does not get propagated */
7753 right = IC_RIGHT(ic);
7755 result = IC_RESULT(ic);
7757 pic16_aopOp(right,ic,FALSE);
7759 /* if the shift count is known then do it
7760 as efficiently as possible */
7761 if (AOP_TYPE(right) == AOP_LIT) {
7762 genRightShiftLiteral (left,right,result,ic, 0);
7766 /* shift count is unknown then we have to form
7767 a loop get the loop count in B : Note: we take
7768 only the lower order byte since shifting
7769 more that 32 bits make no sense anyway, ( the
7770 largest size of an object can be only 32 bits ) */
7772 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7773 pic16_emitcode("inc","b");
7774 pic16_aopOp(left,ic,FALSE);
7775 pic16_aopOp(result,ic,FALSE);
7777 /* now move the left to the result if they are not the
7779 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7780 AOP_SIZE(result) > 1) {
7782 size = AOP_SIZE(result);
7785 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7786 if (*l == '@' && IS_AOP_PREG(result)) {
7788 pic16_emitcode("mov","a,%s",l);
7789 pic16_aopPut(AOP(result),"a",offset);
7791 pic16_aopPut(AOP(result),l,offset);
7796 tlbl = newiTempLabel(NULL);
7797 tlbl1= newiTempLabel(NULL);
7798 size = AOP_SIZE(result);
7801 /* if it is only one byte then */
7804 tlbl = newiTempLabel(NULL);
7805 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7806 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7807 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7810 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7811 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7812 pic16_emitpLabel(tlbl->key);
7813 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7814 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7816 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7821 reAdjustPreg(AOP(result));
7822 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7823 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7826 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7828 pic16_emitcode("rrc","a");
7829 pic16_aopPut(AOP(result),"a",offset--);
7831 reAdjustPreg(AOP(result));
7833 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7834 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7837 pic16_freeAsmop(left,NULL,ic,TRUE);
7838 pic16_freeAsmop (right,NULL,ic,TRUE);
7839 pic16_freeAsmop(result,NULL,ic,TRUE);
7842 /*-----------------------------------------------------------------*/
7843 /* genUnpackBits - generates code for unpacking bits */
7844 /*-----------------------------------------------------------------*/
7845 static void genUnpackBits (operand *result, char *rname, int ptype)
7852 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7853 etype = getSpec(operandType(result));
7855 /* read the first byte */
7860 pic16_emitcode("mov","a,@%s",rname);
7864 pic16_emitcode("movx","a,@%s",rname);
7868 pic16_emitcode("movx","a,@dptr");
7872 pic16_emitcode("clr","a");
7873 pic16_emitcode("movc","a","@a+dptr");
7877 pic16_emitcode("lcall","__gptrget");
7881 /* if we have bitdisplacement then it fits */
7882 /* into this byte completely or if length is */
7883 /* less than a byte */
7884 if ((shCnt = SPEC_BSTR(etype)) ||
7885 (SPEC_BLEN(etype) <= 8)) {
7887 /* shift right acc */
7890 pic16_emitcode("anl","a,#0x%02x",
7891 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7892 pic16_aopPut(AOP(result),"a",offset);
7896 /* bit field did not fit in a byte */
7897 rlen = SPEC_BLEN(etype) - 8;
7898 pic16_aopPut(AOP(result),"a",offset++);
7905 pic16_emitcode("inc","%s",rname);
7906 pic16_emitcode("mov","a,@%s",rname);
7910 pic16_emitcode("inc","%s",rname);
7911 pic16_emitcode("movx","a,@%s",rname);
7915 pic16_emitcode("inc","dptr");
7916 pic16_emitcode("movx","a,@dptr");
7920 pic16_emitcode("clr","a");
7921 pic16_emitcode("inc","dptr");
7922 pic16_emitcode("movc","a","@a+dptr");
7926 pic16_emitcode("inc","dptr");
7927 pic16_emitcode("lcall","__gptrget");
7932 /* if we are done */
7936 pic16_aopPut(AOP(result),"a",offset++);
7941 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7942 pic16_aopPut(AOP(result),"a",offset);
7949 /*-----------------------------------------------------------------*/
7950 /* genDataPointerGet - generates code when ptr offset is known */
7951 /*-----------------------------------------------------------------*/
7952 static void genDataPointerGet (operand *left,
7956 int size , offset = 0;
7959 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7962 /* optimization - most of the time, left and result are the same
7963 * address, but different types. for the pic code, we could omit
7967 pic16_aopOp(result,ic,TRUE);
7969 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7971 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7973 size = AOP_SIZE(result);
7976 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7980 pic16_freeAsmop(left,NULL,ic,TRUE);
7981 pic16_freeAsmop(result,NULL,ic,TRUE);
7984 /*-----------------------------------------------------------------*/
7985 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
7986 /*-----------------------------------------------------------------*/
7987 static void genNearPointerGet (operand *left,
7992 //regs *preg = NULL ;
7994 sym_link *rtype, *retype;
7995 sym_link *ltype = operandType(left);
7998 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8000 rtype = operandType(result);
8001 retype= getSpec(rtype);
8003 pic16_aopOp(left,ic,FALSE);
8005 /* if left is rematerialisable and
8006 result is not bit variable type and
8007 the left is pointer to data space i.e
8008 lower 128 bytes of space */
8009 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8010 !IS_BITVAR(retype) &&
8011 DCL_TYPE(ltype) == POINTER) {
8012 //genDataPointerGet (left,result,ic);
8016 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8018 /* if the value is already in a pointer register
8019 then don't need anything more */
8020 if (!AOP_INPREG(AOP(left))) {
8021 /* otherwise get a free pointer register */
8022 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8025 preg = getFreePtr(ic,&aop,FALSE);
8026 pic16_emitcode("mov","%s,%s",
8028 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8029 rname = preg->name ;
8033 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8035 pic16_aopOp (result,ic,FALSE);
8037 /* if bitfield then unpack the bits */
8038 if (IS_BITVAR(retype))
8039 genUnpackBits (result,rname,POINTER);
8041 /* we have can just get the values */
8042 int size = AOP_SIZE(result);
8045 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8047 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8048 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8050 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8051 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8053 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8057 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8059 pic16_emitcode("mov","a,@%s",rname);
8060 pic16_aopPut(AOP(result),"a",offset);
8062 sprintf(buffer,"@%s",rname);
8063 pic16_aopPut(AOP(result),buffer,offset);
8067 pic16_emitcode("inc","%s",rname);
8072 /* now some housekeeping stuff */
8074 /* we had to allocate for this iCode */
8075 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8076 pic16_freeAsmop(NULL,aop,ic,TRUE);
8078 /* we did not allocate which means left
8079 already in a pointer register, then
8080 if size > 0 && this could be used again
8081 we have to point it back to where it
8083 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8084 if (AOP_SIZE(result) > 1 &&
8085 !OP_SYMBOL(left)->remat &&
8086 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8088 int size = AOP_SIZE(result) - 1;
8090 pic16_emitcode("dec","%s",rname);
8095 pic16_freeAsmop(left,NULL,ic,TRUE);
8096 pic16_freeAsmop(result,NULL,ic,TRUE);
8100 /*-----------------------------------------------------------------*/
8101 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8102 /*-----------------------------------------------------------------*/
8103 static void genPagedPointerGet (operand *left,
8110 sym_link *rtype, *retype;
8112 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8114 rtype = operandType(result);
8115 retype= getSpec(rtype);
8117 pic16_aopOp(left,ic,FALSE);
8119 /* if the value is already in a pointer register
8120 then don't need anything more */
8121 if (!AOP_INPREG(AOP(left))) {
8122 /* otherwise get a free pointer register */
8124 preg = getFreePtr(ic,&aop,FALSE);
8125 pic16_emitcode("mov","%s,%s",
8127 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8128 rname = preg->name ;
8130 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8132 pic16_freeAsmop(left,NULL,ic,TRUE);
8133 pic16_aopOp (result,ic,FALSE);
8135 /* if bitfield then unpack the bits */
8136 if (IS_BITVAR(retype))
8137 genUnpackBits (result,rname,PPOINTER);
8139 /* we have can just get the values */
8140 int size = AOP_SIZE(result);
8145 pic16_emitcode("movx","a,@%s",rname);
8146 pic16_aopPut(AOP(result),"a",offset);
8151 pic16_emitcode("inc","%s",rname);
8155 /* now some housekeeping stuff */
8157 /* we had to allocate for this iCode */
8158 pic16_freeAsmop(NULL,aop,ic,TRUE);
8160 /* we did not allocate which means left
8161 already in a pointer register, then
8162 if size > 0 && this could be used again
8163 we have to point it back to where it
8165 if (AOP_SIZE(result) > 1 &&
8166 !OP_SYMBOL(left)->remat &&
8167 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8169 int size = AOP_SIZE(result) - 1;
8171 pic16_emitcode("dec","%s",rname);
8176 pic16_freeAsmop(result,NULL,ic,TRUE);
8181 /*-----------------------------------------------------------------*/
8182 /* genFarPointerGet - gget value from far space */
8183 /*-----------------------------------------------------------------*/
8184 static void genFarPointerGet (operand *left,
8185 operand *result, iCode *ic)
8188 sym_link *retype = getSpec(operandType(result));
8190 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8192 pic16_aopOp(left,ic,FALSE);
8194 /* if the operand is already in dptr
8195 then we do nothing else we move the value to dptr */
8196 if (AOP_TYPE(left) != AOP_STR) {
8197 /* if this is remateriazable */
8198 if (AOP_TYPE(left) == AOP_IMMD)
8199 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8200 else { /* we need to get it byte by byte */
8201 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8202 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8203 if (options.model == MODEL_FLAT24)
8205 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8209 /* so dptr know contains the address */
8210 pic16_freeAsmop(left,NULL,ic,TRUE);
8211 pic16_aopOp(result,ic,FALSE);
8213 /* if bit then unpack */
8214 if (IS_BITVAR(retype))
8215 genUnpackBits(result,"dptr",FPOINTER);
8217 size = AOP_SIZE(result);
8221 pic16_emitcode("movx","a,@dptr");
8222 pic16_aopPut(AOP(result),"a",offset++);
8224 pic16_emitcode("inc","dptr");
8228 pic16_freeAsmop(result,NULL,ic,TRUE);
8231 /*-----------------------------------------------------------------*/
8232 /* genCodePointerGet - get value from code space */
8233 /*-----------------------------------------------------------------*/
8234 static void genCodePointerGet (operand *left,
8235 operand *result, iCode *ic)
8238 sym_link *retype = getSpec(operandType(result));
8240 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8242 pic16_aopOp(left,ic,FALSE);
8244 /* if the operand is already in dptr
8245 then we do nothing else we move the value to dptr */
8246 if (AOP_TYPE(left) != AOP_STR) {
8247 /* if this is remateriazable */
8248 if (AOP_TYPE(left) == AOP_IMMD)
8249 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8250 else { /* we need to get it byte by byte */
8251 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8252 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8253 if (options.model == MODEL_FLAT24)
8255 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8259 /* so dptr know contains the address */
8260 pic16_freeAsmop(left,NULL,ic,TRUE);
8261 pic16_aopOp(result,ic,FALSE);
8263 /* if bit then unpack */
8264 if (IS_BITVAR(retype))
8265 genUnpackBits(result,"dptr",CPOINTER);
8267 size = AOP_SIZE(result);
8271 pic16_emitcode("clr","a");
8272 pic16_emitcode("movc","a,@a+dptr");
8273 pic16_aopPut(AOP(result),"a",offset++);
8275 pic16_emitcode("inc","dptr");
8279 pic16_freeAsmop(result,NULL,ic,TRUE);
8282 /*-----------------------------------------------------------------*/
8283 /* genGenPointerGet - gget value from generic pointer space */
8284 /*-----------------------------------------------------------------*/
8285 static void genGenPointerGet (operand *left,
8286 operand *result, iCode *ic)
8289 sym_link *retype = getSpec(operandType(result));
8291 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8292 pic16_aopOp(left,ic,FALSE);
8293 pic16_aopOp(result,ic,FALSE);
8296 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8298 /* if the operand is already in dptr
8299 then we do nothing else we move the value to dptr */
8300 // if (AOP_TYPE(left) != AOP_STR) {
8301 /* if this is remateriazable */
8302 if (AOP_TYPE(left) == AOP_IMMD) {
8303 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8304 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8306 else { /* we need to get it byte by byte */
8308 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8309 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8311 size = AOP_SIZE(result);
8315 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8316 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8318 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8323 /* so dptr know contains the address */
8325 /* if bit then unpack */
8326 //if (IS_BITVAR(retype))
8327 // genUnpackBits(result,"dptr",GPOINTER);
8330 pic16_freeAsmop(left,NULL,ic,TRUE);
8331 pic16_freeAsmop(result,NULL,ic,TRUE);
8335 /*-----------------------------------------------------------------*/
8336 /* genConstPointerGet - get value from const generic pointer space */
8337 /*-----------------------------------------------------------------*/
8338 static void genConstPointerGet (operand *left,
8339 operand *result, iCode *ic)
8341 //sym_link *retype = getSpec(operandType(result));
8342 symbol *albl = newiTempLabel(NULL);
8343 symbol *blbl = newiTempLabel(NULL);
8346 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8347 pic16_aopOp(left,ic,FALSE);
8348 pic16_aopOp(result,ic,FALSE);
8351 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8353 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8355 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8356 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8357 pic16_emitpLabel(albl->key);
8359 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8361 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8362 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8363 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8364 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8366 pic16_emitpLabel(blbl->key);
8368 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8371 pic16_freeAsmop(left,NULL,ic,TRUE);
8372 pic16_freeAsmop(result,NULL,ic,TRUE);
8375 /*-----------------------------------------------------------------*/
8376 /* genPointerGet - generate code for pointer get */
8377 /*-----------------------------------------------------------------*/
8378 static void genPointerGet (iCode *ic)
8380 operand *left, *result ;
8381 sym_link *type, *etype;
8384 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8387 result = IC_RESULT(ic) ;
8389 /* depending on the type of pointer we need to
8390 move it to the correct pointer register */
8391 type = operandType(left);
8392 etype = getSpec(type);
8394 if (IS_PTR_CONST(type))
8395 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8397 /* if left is of type of pointer then it is simple */
8398 if (IS_PTR(type) && !IS_FUNC(type->next))
8399 p_type = DCL_TYPE(type);
8401 /* we have to go by the storage class */
8402 p_type = PTR_TYPE(SPEC_OCLS(etype));
8404 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8406 if (SPEC_OCLS(etype)->codesp ) {
8407 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8408 //p_type = CPOINTER ;
8411 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8412 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8413 /*p_type = FPOINTER ;*/
8415 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8416 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8417 /* p_type = PPOINTER; */
8419 if (SPEC_OCLS(etype) == idata )
8420 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8421 /* p_type = IPOINTER; */
8423 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8424 /* p_type = POINTER ; */
8427 /* now that we have the pointer type we assign
8428 the pointer values */
8433 genNearPointerGet (left,result,ic);
8437 genPagedPointerGet(left,result,ic);
8441 genFarPointerGet (left,result,ic);
8445 genConstPointerGet (left,result,ic);
8446 //pic16_emitcodePointerGet (left,result,ic);
8450 if (IS_PTR_CONST(type))
8451 genConstPointerGet (left,result,ic);
8453 genGenPointerGet (left,result,ic);
8459 /*-----------------------------------------------------------------*/
8460 /* genPackBits - generates code for packed bit storage */
8461 /*-----------------------------------------------------------------*/
8462 static void genPackBits (sym_link *etype ,
8464 char *rname, int p_type)
8472 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8473 blen = SPEC_BLEN(etype);
8474 bstr = SPEC_BSTR(etype);
8476 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8479 /* if the bit lenth is less than or */
8480 /* it exactly fits a byte then */
8481 if (SPEC_BLEN(etype) <= 8 ) {
8482 shCount = SPEC_BSTR(etype) ;
8484 /* shift left acc */
8487 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8492 pic16_emitcode ("mov","b,a");
8493 pic16_emitcode("mov","a,@%s",rname);
8497 pic16_emitcode ("mov","b,a");
8498 pic16_emitcode("movx","a,@dptr");
8502 pic16_emitcode ("push","b");
8503 pic16_emitcode ("push","acc");
8504 pic16_emitcode ("lcall","__gptrget");
8505 pic16_emitcode ("pop","b");
8509 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8510 ((unsigned char)(0xFF << (blen+bstr)) |
8511 (unsigned char)(0xFF >> (8-bstr)) ) );
8512 pic16_emitcode ("orl","a,b");
8513 if (p_type == GPOINTER)
8514 pic16_emitcode("pop","b");
8520 pic16_emitcode("mov","@%s,a",rname);
8524 pic16_emitcode("movx","@dptr,a");
8528 DEBUGpic16_emitcode(";lcall","__gptrput");
8533 if ( SPEC_BLEN(etype) <= 8 )
8536 pic16_emitcode("inc","%s",rname);
8537 rLen = SPEC_BLEN(etype) ;
8539 /* now generate for lengths greater than one byte */
8542 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8552 pic16_emitcode("mov","@%s,a",rname);
8554 pic16_emitcode("mov","@%s,%s",rname,l);
8559 pic16_emitcode("movx","@dptr,a");
8564 DEBUGpic16_emitcode(";lcall","__gptrput");
8567 pic16_emitcode ("inc","%s",rname);
8572 /* last last was not complete */
8574 /* save the byte & read byte */
8577 pic16_emitcode ("mov","b,a");
8578 pic16_emitcode("mov","a,@%s",rname);
8582 pic16_emitcode ("mov","b,a");
8583 pic16_emitcode("movx","a,@dptr");
8587 pic16_emitcode ("push","b");
8588 pic16_emitcode ("push","acc");
8589 pic16_emitcode ("lcall","__gptrget");
8590 pic16_emitcode ("pop","b");
8594 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8595 pic16_emitcode ("orl","a,b");
8598 if (p_type == GPOINTER)
8599 pic16_emitcode("pop","b");
8604 pic16_emitcode("mov","@%s,a",rname);
8608 pic16_emitcode("movx","@dptr,a");
8612 DEBUGpic16_emitcode(";lcall","__gptrput");
8616 /*-----------------------------------------------------------------*/
8617 /* genDataPointerSet - remat pointer to data space */
8618 /*-----------------------------------------------------------------*/
8619 static void genDataPointerSet(operand *right,
8623 int size, offset = 0 ;
8624 char *l, buffer[256];
8626 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8627 pic16_aopOp(right,ic,FALSE);
8629 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8630 size = AOP_SIZE(right);
8632 if ( AOP_TYPE(result) == AOP_PCODE) {
8633 fprintf(stderr,"genDataPointerSet %s, %d\n",
8634 AOP(result)->aopu.pcop->name,
8635 PCOI(AOP(result)->aopu.pcop)->offset);
8639 // tsd, was l+1 - the underline `_' prefix was being stripped
8642 sprintf(buffer,"(%s + %d)",l,offset);
8643 fprintf(stderr,"oops %s\n",buffer);
8645 sprintf(buffer,"%s",l);
8647 if (AOP_TYPE(right) == AOP_LIT) {
8648 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8649 lit = lit >> (8*offset);
8651 pic16_emitcode("movlw","%d",lit);
8652 pic16_emitcode("movwf","%s",buffer);
8654 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8655 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8656 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8659 pic16_emitcode("clrf","%s",buffer);
8660 //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8661 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8664 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8665 pic16_emitcode("movwf","%s",buffer);
8667 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8668 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8669 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8676 pic16_freeAsmop(right,NULL,ic,TRUE);
8677 pic16_freeAsmop(result,NULL,ic,TRUE);
8680 /*-----------------------------------------------------------------*/
8681 /* genNearPointerSet - pic16_emitcode for near pointer put */
8682 /*-----------------------------------------------------------------*/
8683 static void genNearPointerSet (operand *right,
8690 sym_link *ptype = operandType(result);
8693 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8694 retype= getSpec(operandType(right));
8696 pic16_aopOp(result,ic,FALSE);
8699 /* if the result is rematerializable &
8700 in data space & not a bit variable */
8701 //if (AOP_TYPE(result) == AOP_IMMD &&
8702 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8703 DCL_TYPE(ptype) == POINTER &&
8704 !IS_BITVAR(retype)) {
8705 genDataPointerSet (right,result,ic);
8706 pic16_freeAsmop(result,NULL,ic,TRUE);
8710 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8711 pic16_aopOp(right,ic,FALSE);
8712 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8714 /* if the value is already in a pointer register
8715 then don't need anything more */
8716 if (!AOP_INPREG(AOP(result))) {
8717 /* otherwise get a free pointer register */
8718 //aop = newAsmop(0);
8719 //preg = getFreePtr(ic,&aop,FALSE);
8720 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8721 //pic16_emitcode("mov","%s,%s",
8723 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8724 //rname = preg->name ;
8725 //pic16_emitcode("movwf","fsr0");
8726 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8727 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8728 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8729 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8733 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8736 /* if bitfield then unpack the bits */
8737 if (IS_BITVAR(retype)) {
8738 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8739 "The programmer is obviously confused");
8740 //genPackBits (retype,right,rname,POINTER);
8744 /* we have can just get the values */
8745 int size = AOP_SIZE(right);
8748 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8750 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8753 //pic16_emitcode("mov","@%s,a",rname);
8754 pic16_emitcode("movf","indf0,w ;1");
8757 if (AOP_TYPE(right) == AOP_LIT) {
8758 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8760 pic16_emitcode("movlw","%s",l);
8761 pic16_emitcode("movwf","indf0 ;2");
8763 pic16_emitcode("clrf","indf0");
8765 pic16_emitcode("movf","%s,w",l);
8766 pic16_emitcode("movwf","indf0 ;2");
8768 //pic16_emitcode("mov","@%s,%s",rname,l);
8771 pic16_emitcode("incf","fsr0,f ;3");
8772 //pic16_emitcode("inc","%s",rname);
8777 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8778 /* now some housekeeping stuff */
8780 /* we had to allocate for this iCode */
8781 pic16_freeAsmop(NULL,aop,ic,TRUE);
8783 /* we did not allocate which means left
8784 already in a pointer register, then
8785 if size > 0 && this could be used again
8786 we have to point it back to where it
8788 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8789 if (AOP_SIZE(right) > 1 &&
8790 !OP_SYMBOL(result)->remat &&
8791 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8793 int size = AOP_SIZE(right) - 1;
8795 pic16_emitcode("decf","fsr0,f");
8796 //pic16_emitcode("dec","%s",rname);
8800 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8803 pic16_freeAsmop(right,NULL,ic,TRUE);
8804 pic16_freeAsmop(result,NULL,ic,TRUE);
8807 /*-----------------------------------------------------------------*/
8808 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8809 /*-----------------------------------------------------------------*/
8810 static void genPagedPointerSet (operand *right,
8819 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8821 retype= getSpec(operandType(right));
8823 pic16_aopOp(result,ic,FALSE);
8825 /* if the value is already in a pointer register
8826 then don't need anything more */
8827 if (!AOP_INPREG(AOP(result))) {
8828 /* otherwise get a free pointer register */
8830 preg = getFreePtr(ic,&aop,FALSE);
8831 pic16_emitcode("mov","%s,%s",
8833 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8834 rname = preg->name ;
8836 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8838 pic16_freeAsmop(result,NULL,ic,TRUE);
8839 pic16_aopOp (right,ic,FALSE);
8841 /* if bitfield then unpack the bits */
8842 if (IS_BITVAR(retype))
8843 genPackBits (retype,right,rname,PPOINTER);
8845 /* we have can just get the values */
8846 int size = AOP_SIZE(right);
8850 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8853 pic16_emitcode("movx","@%s,a",rname);
8856 pic16_emitcode("inc","%s",rname);
8862 /* now some housekeeping stuff */
8864 /* we had to allocate for this iCode */
8865 pic16_freeAsmop(NULL,aop,ic,TRUE);
8867 /* we did not allocate which means left
8868 already in a pointer register, then
8869 if size > 0 && this could be used again
8870 we have to point it back to where it
8872 if (AOP_SIZE(right) > 1 &&
8873 !OP_SYMBOL(result)->remat &&
8874 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8876 int size = AOP_SIZE(right) - 1;
8878 pic16_emitcode("dec","%s",rname);
8883 pic16_freeAsmop(right,NULL,ic,TRUE);
8888 /*-----------------------------------------------------------------*/
8889 /* genFarPointerSet - set value from far space */
8890 /*-----------------------------------------------------------------*/
8891 static void genFarPointerSet (operand *right,
8892 operand *result, iCode *ic)
8895 sym_link *retype = getSpec(operandType(right));
8897 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8898 pic16_aopOp(result,ic,FALSE);
8900 /* if the operand is already in dptr
8901 then we do nothing else we move the value to dptr */
8902 if (AOP_TYPE(result) != AOP_STR) {
8903 /* if this is remateriazable */
8904 if (AOP_TYPE(result) == AOP_IMMD)
8905 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8906 else { /* we need to get it byte by byte */
8907 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8908 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8909 if (options.model == MODEL_FLAT24)
8911 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8915 /* so dptr know contains the address */
8916 pic16_freeAsmop(result,NULL,ic,TRUE);
8917 pic16_aopOp(right,ic,FALSE);
8919 /* if bit then unpack */
8920 if (IS_BITVAR(retype))
8921 genPackBits(retype,right,"dptr",FPOINTER);
8923 size = AOP_SIZE(right);
8927 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8929 pic16_emitcode("movx","@dptr,a");
8931 pic16_emitcode("inc","dptr");
8935 pic16_freeAsmop(right,NULL,ic,TRUE);
8938 /*-----------------------------------------------------------------*/
8939 /* genGenPointerSet - set value from generic pointer space */
8940 /*-----------------------------------------------------------------*/
8941 static void genGenPointerSet (operand *right,
8942 operand *result, iCode *ic)
8945 sym_link *retype = getSpec(operandType(right));
8947 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8949 pic16_aopOp(result,ic,FALSE);
8950 pic16_aopOp(right,ic,FALSE);
8951 size = AOP_SIZE(right);
8953 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8955 /* if the operand is already in dptr
8956 then we do nothing else we move the value to dptr */
8957 if (AOP_TYPE(result) != AOP_STR) {
8958 /* if this is remateriazable */
8959 if (AOP_TYPE(result) == AOP_IMMD) {
8960 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8961 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8963 else { /* we need to get it byte by byte */
8964 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8965 size = AOP_SIZE(right);
8968 /* hack hack! see if this the FSR. If so don't load W */
8969 if(AOP_TYPE(right) != AOP_ACC) {
8972 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
8973 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8975 if(AOP_SIZE(result) > 1) {
8976 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8977 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
8978 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8983 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
8985 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
8986 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
8990 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
8991 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
8994 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9001 if(aopIdx(AOP(result),0) != 4) {
9003 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9007 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9012 /* so dptr know contains the address */
9015 /* if bit then unpack */
9016 if (IS_BITVAR(retype))
9017 genPackBits(retype,right,"dptr",GPOINTER);
9019 size = AOP_SIZE(right);
9022 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9026 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9027 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9029 if (AOP_TYPE(right) == AOP_LIT)
9030 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9032 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9034 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9041 pic16_freeAsmop(right,NULL,ic,TRUE);
9042 pic16_freeAsmop(result,NULL,ic,TRUE);
9045 /*-----------------------------------------------------------------*/
9046 /* genPointerSet - stores the value into a pointer location */
9047 /*-----------------------------------------------------------------*/
9048 static void genPointerSet (iCode *ic)
9050 operand *right, *result ;
9051 sym_link *type, *etype;
9054 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9056 right = IC_RIGHT(ic);
9057 result = IC_RESULT(ic) ;
9059 /* depending on the type of pointer we need to
9060 move it to the correct pointer register */
9061 type = operandType(result);
9062 etype = getSpec(type);
9063 /* if left is of type of pointer then it is simple */
9064 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9065 p_type = DCL_TYPE(type);
9068 /* we have to go by the storage class */
9069 p_type = PTR_TYPE(SPEC_OCLS(etype));
9071 /* if (SPEC_OCLS(etype)->codesp ) { */
9072 /* p_type = CPOINTER ; */
9075 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9076 /* p_type = FPOINTER ; */
9078 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9079 /* p_type = PPOINTER ; */
9081 /* if (SPEC_OCLS(etype) == idata ) */
9082 /* p_type = IPOINTER ; */
9084 /* p_type = POINTER ; */
9087 /* now that we have the pointer type we assign
9088 the pointer values */
9093 genNearPointerSet (right,result,ic);
9097 genPagedPointerSet (right,result,ic);
9101 genFarPointerSet (right,result,ic);
9105 genGenPointerSet (right,result,ic);
9109 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9110 "genPointerSet: illegal pointer type");
9114 /*-----------------------------------------------------------------*/
9115 /* genIfx - generate code for Ifx statement */
9116 /*-----------------------------------------------------------------*/
9117 static void genIfx (iCode *ic, iCode *popIc)
9119 operand *cond = IC_COND(ic);
9122 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9124 pic16_aopOp(cond,ic,FALSE);
9126 /* get the value into acc */
9127 if (AOP_TYPE(cond) != AOP_CRY)
9128 pic16_toBoolean(cond);
9131 /* the result is now in the accumulator */
9132 pic16_freeAsmop(cond,NULL,ic,TRUE);
9134 /* if there was something to be popped then do it */
9138 /* if the condition is a bit variable */
9139 if (isbit && IS_ITEMP(cond) &&
9141 genIfxJump(ic,SPIL_LOC(cond)->rname);
9142 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9145 if (isbit && !IS_ITEMP(cond))
9146 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9154 /*-----------------------------------------------------------------*/
9155 /* genAddrOf - generates code for address of */
9156 /*-----------------------------------------------------------------*/
9157 static void genAddrOf (iCode *ic)
9159 operand *right, *result, *left;
9162 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9165 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9167 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9168 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9169 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9171 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9173 size = AOP_SIZE(IC_RESULT(ic));
9177 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9178 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9182 pic16_freeAsmop(left,NULL,ic,FALSE);
9183 pic16_freeAsmop(result,NULL,ic,TRUE);
9188 /*-----------------------------------------------------------------*/
9189 /* genFarFarAssign - assignment when both are in far space */
9190 /*-----------------------------------------------------------------*/
9191 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9193 int size = AOP_SIZE(right);
9196 /* first push the right side on to the stack */
9198 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9200 pic16_emitcode ("push","acc");
9203 pic16_freeAsmop(right,NULL,ic,FALSE);
9204 /* now assign DPTR to result */
9205 pic16_aopOp(result,ic,FALSE);
9206 size = AOP_SIZE(result);
9208 pic16_emitcode ("pop","acc");
9209 pic16_aopPut(AOP(result),"a",--offset);
9211 pic16_freeAsmop(result,NULL,ic,FALSE);
9216 /*-----------------------------------------------------------------*/
9217 /* genAssign - generate code for assignment */
9218 /*-----------------------------------------------------------------*/
9219 static void genAssign (iCode *ic)
9221 operand *result, *right;
9222 int size, offset,know_W;
9223 unsigned long lit = 0L;
9225 result = IC_RESULT(ic);
9226 right = IC_RIGHT(ic) ;
9228 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9230 /* if they are the same */
9231 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9234 pic16_aopOp(right,ic,FALSE);
9235 pic16_aopOp(result,ic,TRUE);
9237 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9239 /* if they are the same registers */
9240 if (pic16_sameRegs(AOP(right),AOP(result)))
9243 /* if the result is a bit */
9244 if (AOP_TYPE(result) == AOP_CRY) {
9246 /* if the right size is a literal then
9247 we know what the value is */
9248 if (AOP_TYPE(right) == AOP_LIT) {
9250 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9251 pic16_popGet(AOP(result),0));
9253 if (((int) operandLitValue(right)))
9254 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9255 AOP(result)->aopu.aop_dir,
9256 AOP(result)->aopu.aop_dir);
9258 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9259 AOP(result)->aopu.aop_dir,
9260 AOP(result)->aopu.aop_dir);
9264 /* the right is also a bit variable */
9265 if (AOP_TYPE(right) == AOP_CRY) {
9266 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9267 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9268 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9270 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9271 AOP(result)->aopu.aop_dir,
9272 AOP(result)->aopu.aop_dir);
9273 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9274 AOP(right)->aopu.aop_dir,
9275 AOP(right)->aopu.aop_dir);
9276 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9277 AOP(result)->aopu.aop_dir,
9278 AOP(result)->aopu.aop_dir);
9283 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9284 pic16_toBoolean(right);
9286 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9287 //pic16_aopPut(AOP(result),"a",0);
9291 /* bit variables done */
9293 size = AOP_SIZE(result);
9295 if(AOP_TYPE(right) == AOP_LIT)
9296 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9298 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9299 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9300 if(aopIdx(AOP(result),0) == 4) {
9301 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9302 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9303 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9306 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9311 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9312 if(AOP_TYPE(right) == AOP_LIT) {
9314 if(know_W != (lit&0xff))
9315 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9317 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9319 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9323 } else if (AOP_TYPE(right) == AOP_CRY) {
9324 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9326 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9327 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9330 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9331 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9332 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9340 pic16_freeAsmop (right,NULL,ic,FALSE);
9341 pic16_freeAsmop (result,NULL,ic,TRUE);
9344 /*-----------------------------------------------------------------*/
9345 /* genJumpTab - genrates code for jump table */
9346 /*-----------------------------------------------------------------*/
9347 static void genJumpTab (iCode *ic)
9352 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9354 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9355 /* get the condition into accumulator */
9356 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9358 /* multiply by three */
9359 pic16_emitcode("add","a,acc");
9360 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9362 jtab = newiTempLabel(NULL);
9363 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9364 pic16_emitcode("jmp","@a+dptr");
9365 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9367 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9368 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9370 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9371 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9372 pic16_emitpLabel(jtab->key);
9374 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9376 /* now generate the jump labels */
9377 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9378 jtab = setNextItem(IC_JTLABELS(ic))) {
9379 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9380 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9386 /*-----------------------------------------------------------------*/
9387 /* genMixedOperation - gen code for operators between mixed types */
9388 /*-----------------------------------------------------------------*/
9390 TSD - Written for the PIC port - but this unfortunately is buggy.
9391 This routine is good in that it is able to efficiently promote
9392 types to different (larger) sizes. Unfortunately, the temporary
9393 variables that are optimized out by this routine are sometimes
9394 used in other places. So until I know how to really parse the
9395 iCode tree, I'm going to not be using this routine :(.
9397 static int genMixedOperation (iCode *ic)
9400 operand *result = IC_RESULT(ic);
9401 sym_link *ctype = operandType(IC_LEFT(ic));
9402 operand *right = IC_RIGHT(ic);
9408 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9410 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9416 nextright = IC_RIGHT(nextic);
9417 nextleft = IC_LEFT(nextic);
9418 nextresult = IC_RESULT(nextic);
9420 pic16_aopOp(right,ic,FALSE);
9421 pic16_aopOp(result,ic,FALSE);
9422 pic16_aopOp(nextright, nextic, FALSE);
9423 pic16_aopOp(nextleft, nextic, FALSE);
9424 pic16_aopOp(nextresult, nextic, FALSE);
9426 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9432 pic16_emitcode(";remove right +","");
9434 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9440 pic16_emitcode(";remove left +","");
9444 big = AOP_SIZE(nextleft);
9445 small = AOP_SIZE(nextright);
9447 switch(nextic->op) {
9450 pic16_emitcode(";optimize a +","");
9451 /* if unsigned or not an integral type */
9452 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9453 pic16_emitcode(";add a bit to something","");
9456 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9458 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9459 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9460 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9462 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9470 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9471 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9472 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9475 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9477 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9478 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9479 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9480 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9481 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9484 pic16_emitcode("rlf","known_zero,w");
9491 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9492 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9493 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9495 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9505 pic16_freeAsmop(right,NULL,ic,TRUE);
9506 pic16_freeAsmop(result,NULL,ic,TRUE);
9507 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9508 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9510 nextic->generated = 1;
9517 /*-----------------------------------------------------------------*/
9518 /* genCast - gen code for casting */
9519 /*-----------------------------------------------------------------*/
9520 static void genCast (iCode *ic)
9522 operand *result = IC_RESULT(ic);
9523 sym_link *ctype = operandType(IC_LEFT(ic));
9524 sym_link *rtype = operandType(IC_RIGHT(ic));
9525 operand *right = IC_RIGHT(ic);
9528 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9529 /* if they are equivalent then do nothing */
9530 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9533 pic16_aopOp(right,ic,FALSE) ;
9534 pic16_aopOp(result,ic,FALSE);
9536 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9538 /* if the result is a bit */
9539 if (AOP_TYPE(result) == AOP_CRY) {
9540 /* if the right size is a literal then
9541 we know what the value is */
9542 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9543 if (AOP_TYPE(right) == AOP_LIT) {
9545 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9546 pic16_popGet(AOP(result),0));
9548 if (((int) operandLitValue(right)))
9549 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9550 AOP(result)->aopu.aop_dir,
9551 AOP(result)->aopu.aop_dir);
9553 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9554 AOP(result)->aopu.aop_dir,
9555 AOP(result)->aopu.aop_dir);
9560 /* the right is also a bit variable */
9561 if (AOP_TYPE(right) == AOP_CRY) {
9564 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9566 pic16_emitcode("clrc","");
9567 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9568 AOP(right)->aopu.aop_dir,
9569 AOP(right)->aopu.aop_dir);
9570 pic16_aopPut(AOP(result),"c",0);
9575 if (AOP_TYPE(right) == AOP_REG) {
9576 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9577 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9578 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9580 pic16_toBoolean(right);
9581 pic16_aopPut(AOP(result),"a",0);
9585 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9587 size = AOP_SIZE(result);
9589 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9591 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9592 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9593 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9596 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9601 /* if they are the same size : or less */
9602 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9604 /* if they are in the same place */
9605 if (pic16_sameRegs(AOP(right),AOP(result)))
9608 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9609 if (IS_PTR_CONST(rtype))
9610 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9611 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9612 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9614 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9615 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9616 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9617 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9618 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9619 if(AOP_SIZE(result) <2)
9620 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9624 /* if they in different places then copy */
9625 size = AOP_SIZE(result);
9628 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9629 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9631 //pic16_aopPut(AOP(result),
9632 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9642 /* if the result is of type pointer */
9643 if (IS_PTR(ctype)) {
9646 sym_link *type = operandType(right);
9647 sym_link *etype = getSpec(type);
9648 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9650 /* pointer to generic pointer */
9651 if (IS_GENPTR(ctype)) {
9655 p_type = DCL_TYPE(type);
9657 /* we have to go by the storage class */
9658 p_type = PTR_TYPE(SPEC_OCLS(etype));
9660 /* if (SPEC_OCLS(etype)->codesp ) */
9661 /* p_type = CPOINTER ; */
9663 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9664 /* p_type = FPOINTER ; */
9666 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9667 /* p_type = PPOINTER; */
9669 /* if (SPEC_OCLS(etype) == idata ) */
9670 /* p_type = IPOINTER ; */
9672 /* p_type = POINTER ; */
9675 /* the first two bytes are known */
9676 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9677 size = GPTRSIZE - 1;
9680 if(offset < AOP_SIZE(right)) {
9681 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9682 if ((AOP_TYPE(right) == AOP_PCODE) &&
9683 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9684 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9685 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9687 pic16_aopPut(AOP(result),
9688 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9692 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9695 /* the last byte depending on type */
9699 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9702 pic16_emitcode(";BUG!? ","%d",__LINE__);
9706 pic16_emitcode(";BUG!? ","%d",__LINE__);
9710 pic16_emitcode(";BUG!? ","%d",__LINE__);
9715 /* this should never happen */
9716 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9717 "got unknown pointer type");
9720 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9724 /* just copy the pointers */
9725 size = AOP_SIZE(result);
9728 pic16_aopPut(AOP(result),
9729 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9738 /* so we now know that the size of destination is greater
9739 than the size of the source.
9740 Now, if the next iCode is an operator then we might be
9741 able to optimize the operation without performing a cast.
9743 if(genMixedOperation(ic))
9746 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9748 /* we move to result for the size of source */
9749 size = AOP_SIZE(right);
9752 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9753 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9757 /* now depending on the sign of the destination */
9758 size = AOP_SIZE(result) - AOP_SIZE(right);
9759 /* if unsigned or not an integral type */
9760 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9762 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9764 /* we need to extend the sign :{ */
9767 /* Save one instruction of casting char to int */
9768 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9769 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9770 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
9772 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9775 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9777 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9779 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9782 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
9787 pic16_freeAsmop(right,NULL,ic,TRUE);
9788 pic16_freeAsmop(result,NULL,ic,TRUE);
9792 /*-----------------------------------------------------------------*/
9793 /* genDjnz - generate decrement & jump if not zero instrucion */
9794 /*-----------------------------------------------------------------*/
9795 static int genDjnz (iCode *ic, iCode *ifx)
9798 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9803 /* if the if condition has a false label
9804 then we cannot save */
9808 /* if the minus is not of the form
9810 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9811 !IS_OP_LITERAL(IC_RIGHT(ic)))
9814 if (operandLitValue(IC_RIGHT(ic)) != 1)
9817 /* if the size of this greater than one then no
9819 if (getSize(operandType(IC_RESULT(ic))) > 1)
9822 /* otherwise we can save BIG */
9823 lbl = newiTempLabel(NULL);
9824 lbl1= newiTempLabel(NULL);
9826 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9828 if (IS_AOP_PREG(IC_RESULT(ic))) {
9829 pic16_emitcode("dec","%s",
9830 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9831 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9832 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9836 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9837 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9839 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9840 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9843 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9844 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9845 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9846 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9849 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9854 /*-----------------------------------------------------------------*/
9855 /* genReceive - generate code for a receive iCode */
9856 /*-----------------------------------------------------------------*/
9857 static void genReceive (iCode *ic)
9859 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9861 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9862 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9863 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9865 int size = getSize(operandType(IC_RESULT(ic)));
9866 int offset = pic16_fReturnSizePic - size;
9868 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9869 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9872 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9873 size = AOP_SIZE(IC_RESULT(ic));
9876 pic16_emitcode ("pop","acc");
9877 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9882 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9884 assignResultValue(IC_RESULT(ic));
9887 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9890 /*-----------------------------------------------------------------*/
9891 /* genpic16Code - generate code for pic16 based controllers */
9892 /*-----------------------------------------------------------------*/
9894 * At this point, ralloc.c has gone through the iCode and attempted
9895 * to optimize in a way suitable for a PIC. Now we've got to generate
9896 * PIC instructions that correspond to the iCode.
9898 * Once the instructions are generated, we'll pass through both the
9899 * peep hole optimizer and the pCode optimizer.
9900 *-----------------------------------------------------------------*/
9902 void genpic16Code (iCode *lic)
9907 lineHead = lineCurr = NULL;
9909 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9910 pic16_addpBlock(pb);
9912 /* if debug information required */
9913 if (options.debug && currFunc) {
9915 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9917 if (IS_STATIC(currFunc->etype)) {
9918 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9919 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9921 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9922 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
9929 for (ic = lic ; ic ; ic = ic->next ) {
9931 DEBUGpic16_emitcode(";ic","");
9932 if ( cln != ic->lineno ) {
9933 if ( options.debug ) {
9935 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
9936 FileBaseName(ic->filename),ic->lineno,
9937 ic->level,ic->block);
9941 pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9942 pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9943 printCLine(ic->filename, ic->lineno));
9945 pic16_addpCode2pBlock(pb,
9946 pic16_newpCodeCSource(ic->lineno,
9948 printCLine(ic->filename, ic->lineno)));
9952 /* if the result is marked as
9953 spilt and rematerializable or code for
9954 this has already been generated then
9956 if (resultRemat(ic) || ic->generated )
9959 /* depending on the operation */
9978 /* IPOP happens only when trying to restore a
9979 spilt live range, if there is an ifx statement
9980 following this pop then the if statement might
9981 be using some of the registers being popped which
9982 would destroy the contents of the register so
9983 we need to check for this condition and handle it */
9985 ic->next->op == IFX &&
9986 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9987 genIfx (ic->next,ic);
10005 genEndFunction (ic);
10021 pic16_genPlus (ic) ;
10025 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10026 pic16_genMinus (ic);
10042 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10046 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10053 /* note these two are xlated by algebraic equivalence
10054 during parsing SDCC.y */
10055 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10056 "got '>=' or '<=' shouldn't have come here");
10060 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10072 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10076 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10080 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10104 genRightShift (ic);
10107 case GET_VALUE_AT_ADDRESS:
10112 if (POINTER_SET(ic))
10139 addSet(&_G.sendSet,ic);
10148 /* now we are ready to call the
10149 peep hole optimizer */
10150 if (!options.nopeep) {
10151 peepHole (&lineHead);
10153 /* now do the actual printing */
10154 printLine (lineHead,codeOutFile);
10157 DFPRINTF((stderr,"printing pBlock\n\n"));
10158 pic16_printpBlock(stdout,pb);