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"
40 #ifdef HAVE_SYS_ISA_DEFS_H
41 #include <sys/isa_defs.h>
43 #ifdef HAVE_MACHINE_ENDIAN_H
44 #include <machine/endian.h>
49 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
50 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
51 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
58 #include "SDCCpeeph.h"
64 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
66 void pic16_genMult8X8_8 (operand *, operand *,operand *);
67 pCode *pic16_AssembleLine(char *line);
68 extern void pic16_printpBlock(FILE *of, pBlock *pb);
69 static asmop *newAsmop (short type);
70 static pCodeOp *popRegFromString(char *str, int size, int offset);
71 static void mov2w (asmop *aop, int offset);
72 static int aopIdx (asmop *aop, int offset);
74 static int labelOffset=0;
75 extern int pic16_debug_verbose;
76 static int optimized_for_speed = 0;
78 /* max_key keeps track of the largest label number used in
79 a function. This is then used to adjust the label offset
80 for the next function.
83 static int GpsuedoStkPtr=0;
85 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
86 unsigned int pic16aopLiteral (value *val, int offset);
87 const char *pic16_AopType(short type);
88 static iCode *ifxForOp ( operand *op, iCode *ic );
90 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
92 /* this is the down and dirty file with all kinds of
93 kludgy & hacky stuff. This is what it is all about
94 CODE GENERATION for a specific MCU . some of the
95 routines may be reusable, will have to see */
97 static char *zero = "#0x00";
98 static char *one = "#0x01";
99 static char *spname = "sp";
101 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
102 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
103 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
104 static char **fReturn = fReturnpic16;
106 static char *accUse[] = {"a","b"};
108 //static short rbank = -1;
120 /* Resolved ifx structure. This structure stores information
121 about an iCode ifx that makes it easier to generate code.
123 typedef struct resolvedIfx {
124 symbol *lbl; /* pointer to a label */
125 int condition; /* true or false ifx */
126 int generated; /* set true when the code associated with the ifx
130 extern int pic16_ptrRegReq ;
131 extern int pic16_nRegs;
132 extern FILE *codeOutFile;
133 static void saverbank (int, iCode *,bool);
135 static lineNode *lineHead = NULL;
136 static lineNode *lineCurr = NULL;
138 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
139 0xE0, 0xC0, 0x80, 0x00};
140 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
141 0x07, 0x03, 0x01, 0x00};
145 /*-----------------------------------------------------------------*/
146 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
147 /* exponent of 2 is returned, otherwise -1 is */
149 /* note that this is similar to the function `powof2' in SDCCsymt */
153 /*-----------------------------------------------------------------*/
154 static int my_powof2 (unsigned long num)
157 if( (num & (num-1)) == 0) {
170 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
173 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
175 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
176 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
177 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
178 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
179 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
180 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
181 ((result) ? AOP_SIZE(result) : 0));
185 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
188 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
190 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
191 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
192 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
193 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
194 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
195 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
199 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
202 char lb[INITIAL_INLINEASM];
205 if(!pic16_debug_verbose)
212 sprintf(lb,"%s\t",inst);
214 sprintf(lb,"%s",inst);
215 vsprintf(lb+(strlen(lb)),fmt,ap);
219 while (isspace(*lbp)) lbp++;
222 lineCurr = (lineCurr ?
223 connectLine(lineCurr,newLineNode(lb)) :
224 (lineHead = newLineNode(lb)));
225 lineCurr->isInline = _G.inLine;
226 lineCurr->isDebug = _G.debugLine;
228 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
234 void pic16_emitpLabel(int key)
236 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
239 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
243 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
245 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
248 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
251 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
255 /*-----------------------------------------------------------------*/
256 /* pic16_emitcode - writes the code into a file : for now it is simple */
257 /*-----------------------------------------------------------------*/
258 void pic16_emitcode (char *inst,char *fmt, ...)
261 char lb[INITIAL_INLINEASM];
268 sprintf(lb,"%s\t",inst);
270 sprintf(lb,"%s",inst);
271 vsprintf(lb+(strlen(lb)),fmt,ap);
275 while (isspace(*lbp)) lbp++;
278 lineCurr = (lineCurr ?
279 connectLine(lineCurr,newLineNode(lb)) :
280 (lineHead = newLineNode(lb)));
281 lineCurr->isInline = _G.inLine;
282 lineCurr->isDebug = _G.debugLine;
284 if(pic16_debug_verbose)
285 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
291 /*-----------------------------------------------------------------*/
292 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
293 /*-----------------------------------------------------------------*/
294 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
296 bool r0iu = FALSE , r1iu = FALSE;
297 bool r0ou = FALSE , r1ou = FALSE;
299 /* the logic: if r0 & r1 used in the instruction
300 then we are in trouble otherwise */
302 /* first check if r0 & r1 are used by this
303 instruction, in which case we are in trouble */
304 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
305 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
310 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
311 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
313 /* if no usage of r0 then return it */
314 if (!r0iu && !r0ou) {
315 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
316 (*aopp)->type = AOP_R0;
318 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
321 /* if no usage of r1 then return it */
322 if (!r1iu && !r1ou) {
323 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
324 (*aopp)->type = AOP_R1;
326 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
329 /* now we know they both have usage */
330 /* if r0 not used in this instruction */
332 /* push it if not already pushed */
334 //pic16_emitcode ("push","%s",
335 // pic16_regWithIdx(R0_IDX)->dname);
339 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
340 (*aopp)->type = AOP_R0;
342 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
345 /* if r1 not used then */
348 /* push it if not already pushed */
350 //pic16_emitcode ("push","%s",
351 // pic16_regWithIdx(R1_IDX)->dname);
355 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
356 (*aopp)->type = AOP_R1;
357 return pic16_regWithIdx(R1_IDX);
361 /* I said end of world but not quite end of world yet */
362 /* if this is a result then we can push it on the stack*/
364 (*aopp)->type = AOP_STK;
368 /* other wise this is true end of the world */
369 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
370 "getFreePtr should never reach here");
374 /*-----------------------------------------------------------------*/
375 /* newAsmop - creates a new asmOp */
376 /*-----------------------------------------------------------------*/
377 static asmop *newAsmop (short type)
381 aop = Safe_calloc(1,sizeof(asmop));
386 static void genSetDPTR(int n)
390 pic16_emitcode(";", "Select standard DPTR");
391 pic16_emitcode("mov", "dps, #0x00");
395 pic16_emitcode(";", "Select alternate DPTR");
396 pic16_emitcode("mov", "dps, #0x01");
400 /*-----------------------------------------------------------------*/
401 /* resolveIfx - converts an iCode ifx into a form more useful for */
402 /* generating code */
403 /*-----------------------------------------------------------------*/
404 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
409 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
411 resIfx->condition = 1; /* assume that the ifx is true */
412 resIfx->generated = 0; /* indicate that the ifx has not been used */
415 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
417 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
418 __FUNCTION__,__LINE__,resIfx->lbl->key);
422 resIfx->lbl = IC_TRUE(ifx);
424 resIfx->lbl = IC_FALSE(ifx);
425 resIfx->condition = 0;
429 DEBUGpic16_emitcode("; ***","ifx true is non-null");
431 DEBUGpic16_emitcode("; ***","ifx false is non-null");
435 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
438 /*-----------------------------------------------------------------*/
439 /* pointerCode - returns the code for a pointer type */
440 /*-----------------------------------------------------------------*/
441 static int pointerCode (sym_link *etype)
444 return PTR_TYPE(SPEC_OCLS(etype));
448 /*-----------------------------------------------------------------*/
449 /* aopForSym - for a true symbol */
450 /*-----------------------------------------------------------------*/
451 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
454 memmap *space= SPEC_OCLS(sym->etype);
456 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
457 /* if already has one */
461 /* assign depending on the storage class */
462 /* if it is on the stack or indirectly addressable */
463 /* space we need to assign either r0 or r1 to it */
464 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
465 sym->aop = aop = newAsmop(0);
466 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
467 aop->size = getSize(sym->type);
469 /* now assign the address of the variable to
470 the pointer register */
471 if (aop->type != AOP_STK) {
475 pic16_emitcode("push","acc");
477 pic16_emitcode("mov","a,_bp");
478 pic16_emitcode("add","a,#0x%02x",
480 ((char)(sym->stack - _G.nRegsSaved )) :
481 ((char)sym->stack)) & 0xff);
482 pic16_emitcode("mov","%s,a",
483 aop->aopu.aop_ptr->name);
486 pic16_emitcode("pop","acc");
488 pic16_emitcode("mov","%s,#%s",
489 aop->aopu.aop_ptr->name,
491 aop->paged = space->paged;
493 aop->aopu.aop_stk = sym->stack;
497 if (sym->onStack && options.stack10bit)
499 /* It's on the 10 bit stack, which is located in
503 //DEBUGpic16_emitcode(";","%d",__LINE__);
506 pic16_emitcode("push","acc");
508 pic16_emitcode("mov","a,_bp");
509 pic16_emitcode("add","a,#0x%02x",
511 ((char)(sym->stack - _G.nRegsSaved )) :
512 ((char)sym->stack)) & 0xff);
515 pic16_emitcode ("mov","dpx1,#0x40");
516 pic16_emitcode ("mov","dph1,#0x00");
517 pic16_emitcode ("mov","dpl1, a");
521 pic16_emitcode("pop","acc");
523 sym->aop = aop = newAsmop(AOP_DPTR2);
524 aop->size = getSize(sym->type);
528 //DEBUGpic16_emitcode(";","%d",__LINE__);
529 /* if in bit space */
530 if (IN_BITSPACE(space)) {
531 sym->aop = aop = newAsmop (AOP_CRY);
532 aop->aopu.aop_dir = sym->rname ;
533 aop->size = getSize(sym->type);
534 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
537 /* if it is in direct space */
538 if (IN_DIRSPACE(space)) {
539 sym->aop = aop = newAsmop (AOP_DIR);
540 aop->aopu.aop_dir = sym->rname ;
541 aop->size = getSize(sym->type);
542 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
546 /* special case for a function */
547 if (IS_FUNC(sym->type)) {
548 sym->aop = aop = newAsmop(AOP_IMMD);
549 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
550 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
551 strcpy(aop->aopu.aop_immd,sym->rname);
552 aop->size = FPTRSIZE;
553 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
558 /* only remaining is far space */
559 /* in which case DPTR gets the address */
560 sym->aop = aop = newAsmop(AOP_PCODE);
562 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
563 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
564 PCOI(aop->aopu.pcop)->index = 0;
566 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
567 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
569 pic16_allocDirReg (IC_LEFT(ic));
571 aop->size = FPTRSIZE;
573 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
574 sym->aop = aop = newAsmop(AOP_DPTR);
575 pic16_emitcode ("mov","dptr,#%s", sym->rname);
576 aop->size = getSize(sym->type);
578 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
581 /* if it is in code space */
582 if (IN_CODESPACE(space))
588 /*-----------------------------------------------------------------*/
589 /* aopForRemat - rematerialzes an object */
590 /*-----------------------------------------------------------------*/
591 static asmop *aopForRemat (operand *op) // x symbol *sym)
593 symbol *sym = OP_SYMBOL(op);
595 asmop *aop = newAsmop(AOP_PCODE);
599 ic = sym->rematiCode;
601 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
602 if(IS_OP_POINTER(op)) {
603 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
607 val += (int) operandLitValue(IC_RIGHT(ic));
608 } else if (ic->op == '-') {
609 val -= (int) operandLitValue(IC_RIGHT(ic));
613 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
616 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
617 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
618 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
619 PCOI(aop->aopu.pcop)->index = val;
621 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
622 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
623 val, IS_PTR_CONST(operandType(op)));
625 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
627 pic16_allocDirReg (IC_LEFT(ic));
632 static int aopIdx (asmop *aop, int offset)
637 if(aop->type != AOP_REG)
640 return aop->aopu.aop_reg[offset]->rIdx;
643 /*-----------------------------------------------------------------*/
644 /* regsInCommon - two operands have some registers in common */
645 /*-----------------------------------------------------------------*/
646 static bool regsInCommon (operand *op1, operand *op2)
651 /* if they have registers in common */
652 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
655 sym1 = OP_SYMBOL(op1);
656 sym2 = OP_SYMBOL(op2);
658 if (sym1->nRegs == 0 || sym2->nRegs == 0)
661 for (i = 0 ; i < sym1->nRegs ; i++) {
666 for (j = 0 ; j < sym2->nRegs ;j++ ) {
670 if (sym2->regs[j] == sym1->regs[i])
678 /*-----------------------------------------------------------------*/
679 /* operandsEqu - equivalent */
680 /*-----------------------------------------------------------------*/
681 static bool operandsEqu ( operand *op1, operand *op2)
685 /* if they not symbols */
686 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
689 sym1 = OP_SYMBOL(op1);
690 sym2 = OP_SYMBOL(op2);
692 /* if both are itemps & one is spilt
693 and the other is not then false */
694 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
695 sym1->isspilt != sym2->isspilt )
698 /* if they are the same */
702 if (strcmp(sym1->rname,sym2->rname) == 0)
706 /* if left is a tmp & right is not */
710 (sym1->usl.spillLoc == sym2))
717 (sym2->usl.spillLoc == sym1))
723 /*-----------------------------------------------------------------*/
724 /* pic16_sameRegs - two asmops have the same registers */
725 /*-----------------------------------------------------------------*/
726 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
733 if (aop1->type != AOP_REG ||
734 aop2->type != AOP_REG )
737 if (aop1->size != aop2->size )
740 for (i = 0 ; i < aop1->size ; i++ )
741 if (aop1->aopu.aop_reg[i] !=
742 aop2->aopu.aop_reg[i] )
748 /*-----------------------------------------------------------------*/
749 /* pic16_aopOp - allocates an asmop for an operand : */
750 /*-----------------------------------------------------------------*/
751 void pic16_aopOp (operand *op, iCode *ic, bool result)
760 // DEBUGpic16_emitcode(";","%d",__LINE__);
761 /* if this a literal */
762 if (IS_OP_LITERAL(op)) {
763 op->aop = aop = newAsmop(AOP_LIT);
764 aop->aopu.aop_lit = op->operand.valOperand;
765 aop->size = getSize(operandType(op));
770 sym_link *type = operandType(op);
771 if(IS_PTR_CONST(type))
772 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
775 /* if already has a asmop then continue */
779 /* if the underlying symbol has a aop */
780 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
781 DEBUGpic16_emitcode(";","%d",__LINE__);
782 op->aop = OP_SYMBOL(op)->aop;
786 /* if this is a true symbol */
787 if (IS_TRUE_SYMOP(op)) {
788 //DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
789 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
793 /* this is a temporary : this has
799 e) can be a return use only */
804 /* if the type is a conditional */
805 if (sym->regType == REG_CND) {
806 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
811 /* if it is spilt then two situations
813 b) has a spill location */
814 if (sym->isspilt || sym->nRegs == 0) {
816 DEBUGpic16_emitcode(";","%d",__LINE__);
817 /* rematerialize it NOW */
820 sym->aop = op->aop = aop =
822 aop->size = getSize(sym->type);
823 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
829 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
830 aop->size = getSize(sym->type);
831 for ( i = 0 ; i < 2 ; i++ )
832 aop->aopu.aop_str[i] = accUse[i];
833 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
839 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
840 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
841 //pic16_allocDirReg (IC_LEFT(ic));
842 aop->size = getSize(sym->type);
847 aop = op->aop = sym->aop = newAsmop(AOP_STR);
848 aop->size = getSize(sym->type);
849 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
850 aop->aopu.aop_str[i] = fReturn[i];
852 DEBUGpic16_emitcode(";","%d",__LINE__);
856 /* else spill location */
857 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
858 /* force a new aop if sizes differ */
859 sym->usl.spillLoc->aop = NULL;
861 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
862 __FUNCTION__,__LINE__,
863 sym->usl.spillLoc->rname,
864 sym->rname, sym->usl.spillLoc->offset);
866 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
867 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
868 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
870 sym->usl.spillLoc->offset);
871 aop->size = getSize(sym->type);
877 sym_link *type = operandType(op);
878 if(IS_PTR_CONST(type))
879 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
882 /* must be in a register */
883 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
884 sym->aop = op->aop = aop = newAsmop(AOP_REG);
885 aop->size = sym->nRegs;
886 for ( i = 0 ; i < sym->nRegs ;i++)
887 aop->aopu.aop_reg[i] = sym->regs[i];
890 /*-----------------------------------------------------------------*/
891 /* pic16_freeAsmop - free up the asmop given to an operand */
892 /*----------------------------------------------------------------*/
893 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
910 /* depending on the asmop type only three cases need work AOP_RO
911 , AOP_R1 && AOP_STK */
917 pic16_emitcode ("pop","ar0");
921 bitVectUnSetBit(ic->rUsed,R0_IDX);
927 pic16_emitcode ("pop","ar1");
931 bitVectUnSetBit(ic->rUsed,R1_IDX);
937 int stk = aop->aopu.aop_stk + aop->size;
938 bitVectUnSetBit(ic->rUsed,R0_IDX);
939 bitVectUnSetBit(ic->rUsed,R1_IDX);
941 getFreePtr(ic,&aop,FALSE);
943 if (options.stack10bit)
945 /* I'm not sure what to do here yet... */
948 "*** Warning: probably generating bad code for "
949 "10 bit stack mode.\n");
953 pic16_emitcode ("mov","a,_bp");
954 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
955 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
957 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
961 pic16_emitcode("pop","acc");
962 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
964 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
967 pic16_freeAsmop(op,NULL,ic,TRUE);
969 pic16_emitcode("pop","ar0");
974 pic16_emitcode("pop","ar1");
982 /* all other cases just dealloc */
986 OP_SYMBOL(op)->aop = NULL;
987 /* if the symbol has a spill */
989 SPIL_LOC(op)->aop = NULL;
994 /*-----------------------------------------------------------------*/
995 /* pic16_aopGet - for fetching value of the aop */
996 /*-----------------------------------------------------------------*/
997 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1002 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1003 /* offset is greater than
1005 if (offset > (aop->size - 1) &&
1006 aop->type != AOP_LIT)
1009 /* depending on type */
1010 switch (aop->type) {
1014 DEBUGpic16_emitcode(";","%d",__LINE__);
1015 /* if we need to increment it */
1016 while (offset > aop->coff) {
1017 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1021 while (offset < aop->coff) {
1022 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1026 aop->coff = offset ;
1028 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1029 return (dname ? "acc" : "a");
1031 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1032 rs = Safe_calloc(1,strlen(s)+1);
1038 DEBUGpic16_emitcode(";","%d",__LINE__);
1039 if (aop->type == AOP_DPTR2)
1044 while (offset > aop->coff) {
1045 pic16_emitcode ("inc","dptr");
1049 while (offset < aop->coff) {
1050 pic16_emitcode("lcall","__decdptr");
1056 pic16_emitcode("clr","a");
1057 pic16_emitcode("movc","a,@a+dptr");
1060 pic16_emitcode("movx","a,@dptr");
1063 if (aop->type == AOP_DPTR2)
1068 return (dname ? "acc" : "a");
1073 sprintf (s,"%s",aop->aopu.aop_immd);
1076 sprintf(s,"(%s >> %d)",
1081 aop->aopu.aop_immd);
1082 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1083 rs = Safe_calloc(1,strlen(s)+1);
1089 sprintf(s,"(%s + %d)",
1092 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1094 sprintf(s,"%s",aop->aopu.aop_dir);
1095 rs = Safe_calloc(1,strlen(s)+1);
1101 // return aop->aopu.aop_reg[offset]->dname;
1103 return aop->aopu.aop_reg[offset]->name;
1106 //pic16_emitcode(";","%d",__LINE__);
1107 return aop->aopu.aop_dir;
1110 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1111 return "AOP_accumulator_bug";
1114 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1115 rs = Safe_calloc(1,strlen(s)+1);
1120 aop->coff = offset ;
1121 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1124 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1126 return aop->aopu.aop_str[offset];
1130 pCodeOp *pcop = aop->aopu.pcop;
1131 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1133 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1134 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1135 sprintf(s,"%s", pcop->name);
1137 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1140 rs = Safe_calloc(1,strlen(s)+1);
1146 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1147 "aopget got unsupported aop->type");
1152 /*-----------------------------------------------------------------*/
1153 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1154 /*-----------------------------------------------------------------*/
1155 pCodeOp *pic16_popGetTempReg(void)
1160 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1161 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1162 PCOR(pcop)->r->wasUsed=1;
1163 PCOR(pcop)->r->isFree=0;
1169 /*-----------------------------------------------------------------*/
1170 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1171 /*-----------------------------------------------------------------*/
1172 void pic16_popReleaseTempReg(pCodeOp *pcop)
1175 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1176 PCOR(pcop)->r->isFree = 1;
1179 /*-----------------------------------------------------------------*/
1180 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1181 /*-----------------------------------------------------------------*/
1182 pCodeOp *pic16_popGetLabel(unsigned int key)
1185 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1190 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1193 /*-----------------------------------------------------------------*/
1194 /* pic16_popCopyReg - copy a pcode operator */
1195 /*-----------------------------------------------------------------*/
1196 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1200 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1201 pcor->pcop.type = pc->pcop.type;
1203 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1204 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1206 pcor->pcop.name = NULL;
1209 pcor->rIdx = pc->rIdx;
1212 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1216 /*-----------------------------------------------------------------*/
1217 /* pic16_popGet - asm operator to pcode operator conversion */
1218 /*-----------------------------------------------------------------*/
1219 pCodeOp *pic16_popGetLit(unsigned int lit)
1222 return pic16_newpCodeOpLit(lit);
1226 /*-----------------------------------------------------------------*/
1227 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1228 /*-----------------------------------------------------------------*/
1229 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1232 return pic16_newpCodeOpImmd(name, offset,index, 0);
1236 /*-----------------------------------------------------------------*/
1237 /* pic16_popGet - asm operator to pcode operator conversion */
1238 /*-----------------------------------------------------------------*/
1239 pCodeOp *pic16_popGetWithString(char *str)
1245 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1249 pcop = pic16_newpCodeOp(str,PO_STR);
1254 /*-----------------------------------------------------------------*/
1255 /* popRegFromString - */
1256 /*-----------------------------------------------------------------*/
1257 static pCodeOp *popRegFromString(char *str, int size, int offset)
1260 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1261 pcop->type = PO_DIR;
1263 DEBUGpic16_emitcode(";","%d",__LINE__);
1268 pcop->name = Safe_calloc(1,strlen(str)+1);
1269 strcpy(pcop->name,str);
1271 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1273 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1274 if(PCOR(pcop)->r == NULL) {
1275 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1276 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1277 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1279 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1281 PCOR(pcop)->instance = offset;
1286 static pCodeOp *popRegFromIdx(int rIdx)
1290 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1291 __FUNCTION__,__LINE__,rIdx);
1293 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295 PCOR(pcop)->rIdx = rIdx;
1296 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1297 PCOR(pcop)->r->isFree = 0;
1298 PCOR(pcop)->r->wasUsed = 1;
1300 pcop->type = PCOR(pcop)->r->pc_type;
1305 /*-----------------------------------------------------------------*/
1306 /* pic16_popGet - asm operator to pcode operator conversion */
1307 /*-----------------------------------------------------------------*/
1308 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1310 //char *s = buffer ;
1315 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1316 /* offset is greater than
1319 if (offset > (aop->size - 1) &&
1320 aop->type != AOP_LIT)
1321 return NULL; //zero;
1323 /* depending on type */
1324 switch (aop->type) {
1331 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1335 DEBUGpic16_emitcode(";","%d",__LINE__);
1336 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1339 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1341 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1342 pcop->type = PO_DIR;
1346 sprintf(s,"(%s + %d)",
1350 sprintf(s,"%s",aop->aopu.aop_dir);
1351 pcop->name = Safe_calloc(1,strlen(s)+1);
1352 strcpy(pcop->name,s);
1354 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1355 strcpy(pcop->name,aop->aopu.aop_dir);
1356 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1357 if(PCOR(pcop)->r == NULL) {
1358 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1359 PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1360 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1362 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1364 PCOR(pcop)->instance = offset;
1371 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1373 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1374 PCOR(pcop)->rIdx = rIdx;
1375 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1376 PCOR(pcop)->r->wasUsed=1;
1377 PCOR(pcop)->r->isFree=0;
1379 PCOR(pcop)->instance = offset;
1380 pcop->type = PCOR(pcop)->r->pc_type;
1381 //rs = aop->aopu.aop_reg[offset]->name;
1382 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1387 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1388 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1389 //if(PCOR(pcop)->r == NULL)
1390 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1394 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1397 DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1398 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1400 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1401 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1402 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1403 pcop->type = PCOR(pcop)->r->pc_type;
1404 pcop->name = PCOR(pcop)->r->name;
1410 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1412 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1413 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1414 PCOI(pcop)->offset = offset;
1418 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1419 "pic16_popGet got unsupported aop->type");
1422 /*-----------------------------------------------------------------*/
1423 /* pic16_aopPut - puts a string for a aop */
1424 /*-----------------------------------------------------------------*/
1425 void pic16_aopPut (asmop *aop, char *s, int offset)
1430 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1432 if (aop->size && offset > ( aop->size - 1)) {
1433 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1434 "pic16_aopPut got offset > aop->size");
1438 /* will assign value to value */
1439 /* depending on where it is ofcourse */
1440 switch (aop->type) {
1443 sprintf(d,"(%s + %d)",
1444 aop->aopu.aop_dir,offset);
1445 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1448 sprintf(d,"%s",aop->aopu.aop_dir);
1451 DEBUGpic16_emitcode(";","%d",__LINE__);
1453 pic16_emitcode("movf","%s,w",s);
1454 pic16_emitcode("movwf","%s",d);
1457 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1458 if(offset >= aop->size) {
1459 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1462 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1465 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1472 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1473 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1476 strcmp(s,"r0") == 0 ||
1477 strcmp(s,"r1") == 0 ||
1478 strcmp(s,"r2") == 0 ||
1479 strcmp(s,"r3") == 0 ||
1480 strcmp(s,"r4") == 0 ||
1481 strcmp(s,"r5") == 0 ||
1482 strcmp(s,"r6") == 0 ||
1483 strcmp(s,"r7") == 0 )
1484 pic16_emitcode("mov","%s,%s ; %d",
1485 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1489 if(strcmp(s,"W")==0 )
1490 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1492 pic16_emitcode("movwf","%s",
1493 aop->aopu.aop_reg[offset]->name);
1495 if(strcmp(s,zero)==0) {
1496 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1498 } else if(strcmp(s,"W")==0) {
1499 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1500 pcop->type = PO_GPR_REGISTER;
1502 PCOR(pcop)->rIdx = -1;
1503 PCOR(pcop)->r = NULL;
1505 DEBUGpic16_emitcode(";","%d",__LINE__);
1506 pcop->name = Safe_strdup(s);
1507 pic16_emitpcode(POC_MOVFW,pcop);
1508 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1509 } else if(strcmp(s,one)==0) {
1510 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1511 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1513 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1521 if (aop->type == AOP_DPTR2)
1527 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1528 "pic16_aopPut writting to code space");
1532 while (offset > aop->coff) {
1534 pic16_emitcode ("inc","dptr");
1537 while (offset < aop->coff) {
1539 pic16_emitcode("lcall","__decdptr");
1544 /* if not in accumulater */
1547 pic16_emitcode ("movx","@dptr,a");
1549 if (aop->type == AOP_DPTR2)
1557 while (offset > aop->coff) {
1559 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1561 while (offset < aop->coff) {
1563 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1569 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1574 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1576 if (strcmp(s,"r0") == 0 ||
1577 strcmp(s,"r1") == 0 ||
1578 strcmp(s,"r2") == 0 ||
1579 strcmp(s,"r3") == 0 ||
1580 strcmp(s,"r4") == 0 ||
1581 strcmp(s,"r5") == 0 ||
1582 strcmp(s,"r6") == 0 ||
1583 strcmp(s,"r7") == 0 ) {
1585 sprintf(buffer,"a%s",s);
1586 pic16_emitcode("mov","@%s,%s",
1587 aop->aopu.aop_ptr->name,buffer);
1589 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1594 if (strcmp(s,"a") == 0)
1595 pic16_emitcode("push","acc");
1597 pic16_emitcode("push","%s",s);
1602 /* if bit variable */
1603 if (!aop->aopu.aop_dir) {
1604 pic16_emitcode("clr","a");
1605 pic16_emitcode("rlc","a");
1608 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1611 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1614 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1616 lbl = newiTempLabel(NULL);
1618 if (strcmp(s,"a")) {
1621 pic16_emitcode("clr","c");
1622 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1623 pic16_emitcode("cpl","c");
1624 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1625 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1632 if (strcmp(aop->aopu.aop_str[offset],s))
1633 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1638 if (!offset && (strcmp(s,"acc") == 0))
1641 if (strcmp(aop->aopu.aop_str[offset],s))
1642 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1646 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1647 "pic16_aopPut got unsupported aop->type");
1653 /*-----------------------------------------------------------------*/
1654 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1655 /*-----------------------------------------------------------------*/
1656 static void mov2w (asmop *aop, int offset)
1662 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1664 if ( aop->type == AOP_PCODE ||
1665 aop->type == AOP_LIT )
1666 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1668 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1672 /*-----------------------------------------------------------------*/
1673 /* reAdjustPreg - points a register back to where it should */
1674 /*-----------------------------------------------------------------*/
1675 static void reAdjustPreg (asmop *aop)
1679 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1681 if ((size = aop->size) <= 1)
1684 switch (aop->type) {
1688 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1692 if (aop->type == AOP_DPTR2)
1698 pic16_emitcode("lcall","__decdptr");
1701 if (aop->type == AOP_DPTR2)
1711 /*-----------------------------------------------------------------*/
1712 /* genNotFloat - generates not for float operations */
1713 /*-----------------------------------------------------------------*/
1714 static void genNotFloat (operand *op, operand *res)
1720 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1721 /* we will put 127 in the first byte of
1723 pic16_aopPut(AOP(res),"#127",0);
1724 size = AOP_SIZE(op) - 1;
1727 l = pic16_aopGet(op->aop,offset++,FALSE,FALSE);
1731 pic16_emitcode("orl","a,%s",
1732 pic16_aopGet(op->aop,
1733 offset++,FALSE,FALSE));
1735 tlbl = newiTempLabel(NULL);
1737 tlbl = newiTempLabel(NULL);
1738 pic16_aopPut(res->aop,one,1);
1739 pic16_emitcode("jz","%05d_DS_",(tlbl->key+100));
1740 pic16_aopPut(res->aop,zero,1);
1741 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
1743 size = res->aop->size - 2;
1745 /* put zeros in the rest */
1747 pic16_aopPut(res->aop,zero,offset++);
1751 /*-----------------------------------------------------------------*/
1752 /* opIsGptr: returns non-zero if the passed operand is */
1753 /* a generic pointer type. */
1754 /*-----------------------------------------------------------------*/
1755 static int opIsGptr(operand *op)
1757 sym_link *type = operandType(op);
1759 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1760 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1768 /*-----------------------------------------------------------------*/
1769 /* pic16_getDataSize - get the operand data size */
1770 /*-----------------------------------------------------------------*/
1771 int pic16_getDataSize(operand *op)
1773 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1776 return AOP_SIZE(op);
1778 // tsd- in the pic port, the genptr size is 1, so this code here
1779 // fails. ( in the 8051 port, the size was 4).
1782 size = AOP_SIZE(op);
1783 if (size == GPTRSIZE)
1785 sym_link *type = operandType(op);
1786 if (IS_GENPTR(type))
1788 /* generic pointer; arithmetic operations
1789 * should ignore the high byte (pointer type).
1792 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1799 /*-----------------------------------------------------------------*/
1800 /* pic16_outAcc - output Acc */
1801 /*-----------------------------------------------------------------*/
1802 void pic16_outAcc(operand *result)
1805 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1806 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1809 size = pic16_getDataSize(result);
1811 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1814 /* unsigned or positive */
1816 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1821 /*-----------------------------------------------------------------*/
1822 /* pic16_outBitC - output a bit C */
1823 /*-----------------------------------------------------------------*/
1824 void pic16_outBitC(operand *result)
1827 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1828 /* if the result is bit */
1829 if (AOP_TYPE(result) == AOP_CRY)
1830 pic16_aopPut(AOP(result),"c",0);
1832 pic16_emitcode("clr","a ; %d", __LINE__);
1833 pic16_emitcode("rlc","a");
1834 pic16_outAcc(result);
1838 /*-----------------------------------------------------------------*/
1839 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1840 /*-----------------------------------------------------------------*/
1841 void pic16_toBoolean(operand *oper)
1843 int size = AOP_SIZE(oper) - 1;
1846 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1848 if ( AOP_TYPE(oper) != AOP_ACC) {
1849 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1852 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1857 /*-----------------------------------------------------------------*/
1858 /* genNot - generate code for ! operation */
1859 /*-----------------------------------------------------------------*/
1860 static void genNot (iCode *ic)
1863 sym_link *optype = operandType(IC_LEFT(ic));
1866 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1867 /* assign asmOps to operand & result */
1868 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1869 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1871 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1872 /* if in bit space then a special case */
1873 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1874 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1875 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1876 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1878 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1879 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1880 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1885 /* if type float then do float */
1886 if (IS_FLOAT(optype)) {
1887 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1891 size = AOP_SIZE(IC_RESULT(ic));
1893 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1894 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1895 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1898 pic16_toBoolean(IC_LEFT(ic));
1900 tlbl = newiTempLabel(NULL);
1901 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1902 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1903 pic16_outBitC(IC_RESULT(ic));
1906 /* release the aops */
1907 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1908 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1912 /*-----------------------------------------------------------------*/
1913 /* genCpl - generate code for complement */
1914 /*-----------------------------------------------------------------*/
1915 static void genCpl (iCode *ic)
1921 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1922 /* assign asmOps to operand & result */
1923 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1924 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1926 /* if both are in bit space then
1928 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1929 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1931 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1932 pic16_emitcode("cpl","c");
1933 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1937 size = AOP_SIZE(IC_RESULT(ic));
1939 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1941 pic16_emitcode("cpl","a");
1942 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1947 /* release the aops */
1948 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1949 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1952 /*-----------------------------------------------------------------*/
1953 /* genUminusFloat - unary minus for floating points */
1954 /*-----------------------------------------------------------------*/
1955 static void genUminusFloat(operand *op,operand *result)
1957 int size ,offset =0 ;
1960 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1961 /* for this we just need to flip the
1962 first it then copy the rest in place */
1963 size = AOP_SIZE(op) - 1;
1964 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1968 pic16_emitcode("cpl","acc.7");
1969 pic16_aopPut(AOP(result),"a",3);
1972 pic16_aopPut(AOP(result),
1973 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1979 /*-----------------------------------------------------------------*/
1980 /* genUminus - unary minus code generation */
1981 /*-----------------------------------------------------------------*/
1982 static void genUminus (iCode *ic)
1985 sym_link *optype, *rtype;
1988 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1990 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1991 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1993 /* if both in bit space then special
1995 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1996 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1998 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1999 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2000 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2005 optype = operandType(IC_LEFT(ic));
2006 rtype = operandType(IC_RESULT(ic));
2008 /* if float then do float stuff */
2009 if (IS_FLOAT(optype)) {
2010 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2014 /* otherwise subtract from zero by taking the 2's complement */
2015 size = AOP_SIZE(IC_LEFT(ic));
2017 for(i=0; i<size; i++) {
2018 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2019 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2021 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2022 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2026 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2027 for(i=1; i<size; i++) {
2029 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2033 /* release the aops */
2034 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2035 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2038 /*-----------------------------------------------------------------*/
2039 /* saveRegisters - will look for a call and save the registers */
2040 /*-----------------------------------------------------------------*/
2041 static void saveRegisters(iCode *lic)
2048 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2050 for (ic = lic ; ic ; ic = ic->next)
2051 if (ic->op == CALL || ic->op == PCALL)
2055 fprintf(stderr,"found parameter push with no function call\n");
2059 /* if the registers have been saved already then
2061 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2064 /* find the registers in use at this time
2065 and push them away to safety */
2066 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2070 if (options.useXstack) {
2071 if (bitVectBitValue(rsave,R0_IDX))
2072 pic16_emitcode("mov","b,r0");
2073 pic16_emitcode("mov","r0,%s",spname);
2074 for (i = 0 ; i < pic16_nRegs ; i++) {
2075 if (bitVectBitValue(rsave,i)) {
2077 pic16_emitcode("mov","a,b");
2079 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2080 pic16_emitcode("movx","@r0,a");
2081 pic16_emitcode("inc","r0");
2084 pic16_emitcode("mov","%s,r0",spname);
2085 if (bitVectBitValue(rsave,R0_IDX))
2086 pic16_emitcode("mov","r0,b");
2088 //for (i = 0 ; i < pic16_nRegs ; i++) {
2089 // if (bitVectBitValue(rsave,i))
2090 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2093 dtype = operandType(IC_LEFT(ic));
2094 if (currFunc && dtype &&
2095 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2096 IFFUNC_ISISR(currFunc->type) &&
2099 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2102 /*-----------------------------------------------------------------*/
2103 /* unsaveRegisters - pop the pushed registers */
2104 /*-----------------------------------------------------------------*/
2105 static void unsaveRegisters (iCode *ic)
2110 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2111 /* find the registers in use at this time
2112 and push them away to safety */
2113 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2116 if (options.useXstack) {
2117 pic16_emitcode("mov","r0,%s",spname);
2118 for (i = pic16_nRegs ; i >= 0 ; i--) {
2119 if (bitVectBitValue(rsave,i)) {
2120 pic16_emitcode("dec","r0");
2121 pic16_emitcode("movx","a,@r0");
2123 pic16_emitcode("mov","b,a");
2125 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2129 pic16_emitcode("mov","%s,r0",spname);
2130 if (bitVectBitValue(rsave,R0_IDX))
2131 pic16_emitcode("mov","r0,b");
2133 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2134 // if (bitVectBitValue(rsave,i))
2135 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2141 /*-----------------------------------------------------------------*/
2143 /*-----------------------------------------------------------------*/
2144 static void pushSide(operand * oper, int size)
2148 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2150 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2151 if (AOP_TYPE(oper) != AOP_REG &&
2152 AOP_TYPE(oper) != AOP_DIR &&
2154 pic16_emitcode("mov","a,%s",l);
2155 pic16_emitcode("push","acc");
2157 pic16_emitcode("push","%s",l);
2162 /*-----------------------------------------------------------------*/
2163 /* assignResultValue - */
2164 /*-----------------------------------------------------------------*/
2165 static void assignResultValue(operand * oper)
2167 int size = AOP_SIZE(oper);
2169 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2171 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2173 if(!GpsuedoStkPtr) {
2174 /* The last byte in the assignment is in W */
2176 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2181 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2183 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2188 /*-----------------------------------------------------------------*/
2189 /* genIpush - genrate code for pushing this gets a little complex */
2190 /*-----------------------------------------------------------------*/
2191 static void genIpush (iCode *ic)
2194 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2196 int size, offset = 0 ;
2200 /* if this is not a parm push : ie. it is spill push
2201 and spill push is always done on the local stack */
2202 if (!ic->parmPush) {
2204 /* and the item is spilt then do nothing */
2205 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2208 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2209 size = AOP_SIZE(IC_LEFT(ic));
2210 /* push it on the stack */
2212 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2217 pic16_emitcode("push","%s",l);
2222 /* this is a paramter push: in this case we call
2223 the routine to find the call and save those
2224 registers that need to be saved */
2227 /* then do the push */
2228 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2231 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2232 size = AOP_SIZE(IC_LEFT(ic));
2235 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2236 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2237 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2239 pic16_emitcode("mov","a,%s",l);
2240 pic16_emitcode("push","acc");
2242 pic16_emitcode("push","%s",l);
2245 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2249 /*-----------------------------------------------------------------*/
2250 /* genIpop - recover the registers: can happen only for spilling */
2251 /*-----------------------------------------------------------------*/
2252 static void genIpop (iCode *ic)
2254 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2259 /* if the temp was not pushed then */
2260 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2263 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2264 size = AOP_SIZE(IC_LEFT(ic));
2267 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2270 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2274 /*-----------------------------------------------------------------*/
2275 /* unsaverbank - restores the resgister bank from stack */
2276 /*-----------------------------------------------------------------*/
2277 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2279 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2287 if (options.useXstack) {
2289 r = getFreePtr(ic,&aop,FALSE);
2292 pic16_emitcode("mov","%s,_spx",r->name);
2293 pic16_emitcode("movx","a,@%s",r->name);
2294 pic16_emitcode("mov","psw,a");
2295 pic16_emitcode("dec","%s",r->name);
2298 pic16_emitcode ("pop","psw");
2301 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2302 if (options.useXstack) {
2303 pic16_emitcode("movx","a,@%s",r->name);
2304 //pic16_emitcode("mov","(%s+%d),a",
2305 // regspic16[i].base,8*bank+regspic16[i].offset);
2306 pic16_emitcode("dec","%s",r->name);
2309 pic16_emitcode("pop",""); //"(%s+%d)",
2310 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2313 if (options.useXstack) {
2315 pic16_emitcode("mov","_spx,%s",r->name);
2316 pic16_freeAsmop(NULL,aop,ic,TRUE);
2322 /*-----------------------------------------------------------------*/
2323 /* saverbank - saves an entire register bank on the stack */
2324 /*-----------------------------------------------------------------*/
2325 static void saverbank (int bank, iCode *ic, bool pushPsw)
2327 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2333 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2334 if (options.useXstack) {
2337 r = getFreePtr(ic,&aop,FALSE);
2338 pic16_emitcode("mov","%s,_spx",r->name);
2342 for (i = 0 ; i < pic16_nRegs ;i++) {
2343 if (options.useXstack) {
2344 pic16_emitcode("inc","%s",r->name);
2345 //pic16_emitcode("mov","a,(%s+%d)",
2346 // regspic16[i].base,8*bank+regspic16[i].offset);
2347 pic16_emitcode("movx","@%s,a",r->name);
2349 pic16_emitcode("push","");// "(%s+%d)",
2350 //regspic16[i].base,8*bank+regspic16[i].offset);
2354 if (options.useXstack) {
2355 pic16_emitcode("mov","a,psw");
2356 pic16_emitcode("movx","@%s,a",r->name);
2357 pic16_emitcode("inc","%s",r->name);
2358 pic16_emitcode("mov","_spx,%s",r->name);
2359 pic16_freeAsmop (NULL,aop,ic,TRUE);
2362 pic16_emitcode("push","psw");
2364 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2370 /*-----------------------------------------------------------------*/
2371 /* genCall - generates a call statement */
2372 /*-----------------------------------------------------------------*/
2373 static void genCall (iCode *ic)
2377 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2379 /* if caller saves & we have not saved then */
2383 /* if we are calling a function that is not using
2384 the same register bank then we need to save the
2385 destination registers on the stack */
2386 dtype = operandType(IC_LEFT(ic));
2387 if (currFunc && dtype &&
2388 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2389 IFFUNC_ISISR(currFunc->type) &&
2392 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2394 /* if send set is not empty the assign */
2397 /* For the Pic port, there is no data stack.
2398 * So parameters passed to functions are stored
2399 * in registers. (The pCode optimizer will get
2400 * rid of most of these :).
2402 int psuedoStkPtr=-1;
2403 int firstTimeThruLoop = 1;
2405 _G.sendSet = reverseSet(_G.sendSet);
2407 /* First figure how many parameters are getting passed */
2408 for (sic = setFirstItem(_G.sendSet) ; sic ;
2409 sic = setNextItem(_G.sendSet)) {
2411 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2412 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2413 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2416 for (sic = setFirstItem(_G.sendSet) ; sic ;
2417 sic = setNextItem(_G.sendSet)) {
2418 int size, offset = 0;
2420 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2421 size = AOP_SIZE(IC_LEFT(sic));
2424 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2425 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2427 if(!firstTimeThruLoop) {
2428 /* If this is not the first time we've been through the loop
2429 * then we need to save the parameter in a temporary
2430 * register. The last byte of the last parameter is
2432 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2435 firstTimeThruLoop=0;
2437 //if (strcmp(l,fReturn[offset])) {
2438 mov2w (AOP(IC_LEFT(sic)), offset);
2440 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2441 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2442 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2444 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2449 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2454 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2455 OP_SYMBOL(IC_LEFT(ic))->rname :
2456 OP_SYMBOL(IC_LEFT(ic))->name));
2459 /* if we need assign a result value */
2460 if ((IS_ITEMP(IC_RESULT(ic)) &&
2461 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2462 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2463 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2466 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2469 assignResultValue(IC_RESULT(ic));
2471 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2472 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2474 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2477 /* adjust the stack for parameters if
2479 if (ic->parmBytes) {
2481 if (ic->parmBytes > 3) {
2482 pic16_emitcode("mov","a,%s",spname);
2483 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2484 pic16_emitcode("mov","%s,a",spname);
2486 for ( i = 0 ; i < ic->parmBytes ;i++)
2487 pic16_emitcode("dec","%s",spname);
2491 /* if register bank was saved then pop them */
2493 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2495 /* if we hade saved some registers then unsave them */
2496 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2497 unsaveRegisters (ic);
2502 /*-----------------------------------------------------------------*/
2503 /* genPcall - generates a call by pointer statement */
2504 /*-----------------------------------------------------------------*/
2505 static void genPcall (iCode *ic)
2508 symbol *rlbl = newiTempLabel(NULL);
2511 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2512 /* if caller saves & we have not saved then */
2516 /* if we are calling a function that is not using
2517 the same register bank then we need to save the
2518 destination registers on the stack */
2519 dtype = operandType(IC_LEFT(ic));
2520 if (currFunc && dtype &&
2521 IFFUNC_ISISR(currFunc->type) &&
2522 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2523 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2526 /* push the return address on to the stack */
2527 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2528 pic16_emitcode("push","acc");
2529 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2530 pic16_emitcode("push","acc");
2532 if (options.model == MODEL_FLAT24)
2534 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2535 pic16_emitcode("push","acc");
2538 /* now push the calling address */
2539 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2541 pushSide(IC_LEFT(ic), FPTRSIZE);
2543 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2545 /* if send set is not empty the assign */
2549 for (sic = setFirstItem(_G.sendSet) ; sic ;
2550 sic = setNextItem(_G.sendSet)) {
2551 int size, offset = 0;
2552 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2553 size = AOP_SIZE(IC_LEFT(sic));
2555 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2557 if (strcmp(l,fReturn[offset]))
2558 pic16_emitcode("mov","%s,%s",
2563 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2568 pic16_emitcode("ret","");
2569 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2572 /* if we need assign a result value */
2573 if ((IS_ITEMP(IC_RESULT(ic)) &&
2574 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2575 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2576 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2579 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2582 assignResultValue(IC_RESULT(ic));
2584 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2587 /* adjust the stack for parameters if
2589 if (ic->parmBytes) {
2591 if (ic->parmBytes > 3) {
2592 pic16_emitcode("mov","a,%s",spname);
2593 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2594 pic16_emitcode("mov","%s,a",spname);
2596 for ( i = 0 ; i < ic->parmBytes ;i++)
2597 pic16_emitcode("dec","%s",spname);
2601 /* if register bank was saved then unsave them */
2602 if (currFunc && dtype &&
2603 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2604 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2606 /* if we hade saved some registers then
2609 unsaveRegisters (ic);
2613 /*-----------------------------------------------------------------*/
2614 /* resultRemat - result is rematerializable */
2615 /*-----------------------------------------------------------------*/
2616 static int resultRemat (iCode *ic)
2618 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2619 if (SKIP_IC(ic) || ic->op == IFX)
2622 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2623 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2624 if (sym->remat && !POINTER_SET(ic))
2631 #if defined(__BORLANDC__) || defined(_MSC_VER)
2632 #define STRCASECMP stricmp
2634 #define STRCASECMP strcasecmp
2638 /*-----------------------------------------------------------------*/
2639 /* inExcludeList - return 1 if the string is in exclude Reg list */
2640 /*-----------------------------------------------------------------*/
2641 static bool inExcludeList(char *s)
2643 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2646 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2647 if (options.excludeRegs[i] &&
2648 STRCASECMP(options.excludeRegs[i],"none") == 0)
2651 for ( i = 0 ; options.excludeRegs[i]; i++) {
2652 if (options.excludeRegs[i] &&
2653 STRCASECMP(s,options.excludeRegs[i]) == 0)
2660 /*-----------------------------------------------------------------*/
2661 /* genFunction - generated code for function entry */
2662 /*-----------------------------------------------------------------*/
2663 static void genFunction (iCode *ic)
2668 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2670 labelOffset += (max_key+4);
2674 /* create the function header */
2675 pic16_emitcode(";","-----------------------------------------");
2676 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2677 pic16_emitcode(";","-----------------------------------------");
2679 pic16_emitcode("","%s:",sym->rname);
2680 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2682 ftype = operandType(IC_LEFT(ic));
2684 /* if critical function then turn interrupts off */
2685 if (IFFUNC_ISCRITICAL(ftype))
2686 pic16_emitcode("clr","ea");
2688 /* here we need to generate the equates for the
2689 register bank if required */
2691 if (FUNC_REGBANK(ftype) != rbank) {
2694 rbank = FUNC_REGBANK(ftype);
2695 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2696 if (strcmp(regspic16[i].base,"0") == 0)
2697 pic16_emitcode("","%s = 0x%02x",
2699 8*rbank+regspic16[i].offset);
2701 pic16_emitcode ("","%s = %s + 0x%02x",
2704 8*rbank+regspic16[i].offset);
2709 /* if this is an interrupt service routine then
2710 save acc, b, dpl, dph */
2711 if (IFFUNC_ISISR(sym->type)) {
2712 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2713 pic16_emitpcodeNULLop(POC_NOP);
2714 pic16_emitpcodeNULLop(POC_NOP);
2715 pic16_emitpcodeNULLop(POC_NOP);
2716 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2717 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2718 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2719 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2721 pic16_pBlockConvert2ISR(pb);
2723 if (!inExcludeList("acc"))
2724 pic16_emitcode ("push","acc");
2725 if (!inExcludeList("b"))
2726 pic16_emitcode ("push","b");
2727 if (!inExcludeList("dpl"))
2728 pic16_emitcode ("push","dpl");
2729 if (!inExcludeList("dph"))
2730 pic16_emitcode ("push","dph");
2731 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2733 pic16_emitcode ("push", "dpx");
2734 /* Make sure we're using standard DPTR */
2735 pic16_emitcode ("push", "dps");
2736 pic16_emitcode ("mov", "dps, #0x00");
2737 if (options.stack10bit)
2739 /* This ISR could conceivably use DPTR2. Better save it. */
2740 pic16_emitcode ("push", "dpl1");
2741 pic16_emitcode ("push", "dph1");
2742 pic16_emitcode ("push", "dpx1");
2745 /* if this isr has no bank i.e. is going to
2746 run with bank 0 , then we need to save more
2748 if (!FUNC_REGBANK(sym->type)) {
2750 /* if this function does not call any other
2751 function then we can be economical and
2752 save only those registers that are used */
2753 if (! IFFUNC_HASFCALL(sym->type)) {
2756 /* if any registers used */
2757 if (sym->regsUsed) {
2758 /* save the registers used */
2759 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2760 if (bitVectBitValue(sym->regsUsed,i) ||
2761 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2762 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2767 /* this function has a function call cannot
2768 determines register usage so we will have the
2770 saverbank(0,ic,FALSE);
2775 /* if callee-save to be used for this function
2776 then save the registers being used in this function */
2777 if (IFFUNC_CALLEESAVES(sym->type)) {
2780 /* if any registers used */
2781 if (sym->regsUsed) {
2782 /* save the registers used */
2783 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2784 if (bitVectBitValue(sym->regsUsed,i) ||
2785 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2786 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2794 /* set the register bank to the desired value */
2795 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2796 pic16_emitcode("push","psw");
2797 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2800 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2802 if (options.useXstack) {
2803 pic16_emitcode("mov","r0,%s",spname);
2804 pic16_emitcode("mov","a,_bp");
2805 pic16_emitcode("movx","@r0,a");
2806 pic16_emitcode("inc","%s",spname);
2810 /* set up the stack */
2811 pic16_emitcode ("push","_bp"); /* save the callers stack */
2813 pic16_emitcode ("mov","_bp,%s",spname);
2816 /* adjust the stack for the function */
2821 werror(W_STACK_OVERFLOW,sym->name);
2823 if (i > 3 && sym->recvSize < 4) {
2825 pic16_emitcode ("mov","a,sp");
2826 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2827 pic16_emitcode ("mov","sp,a");
2832 pic16_emitcode("inc","sp");
2837 pic16_emitcode ("mov","a,_spx");
2838 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2839 pic16_emitcode ("mov","_spx,a");
2844 /*-----------------------------------------------------------------*/
2845 /* genEndFunction - generates epilogue for functions */
2846 /*-----------------------------------------------------------------*/
2847 static void genEndFunction (iCode *ic)
2849 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2851 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2853 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2855 pic16_emitcode ("mov","%s,_bp",spname);
2858 /* if use external stack but some variables were
2859 added to the local stack then decrement the
2861 if (options.useXstack && sym->stack) {
2862 pic16_emitcode("mov","a,sp");
2863 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2864 pic16_emitcode("mov","sp,a");
2868 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2869 if (options.useXstack) {
2870 pic16_emitcode("mov","r0,%s",spname);
2871 pic16_emitcode("movx","a,@r0");
2872 pic16_emitcode("mov","_bp,a");
2873 pic16_emitcode("dec","%s",spname);
2877 pic16_emitcode ("pop","_bp");
2881 /* restore the register bank */
2882 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2883 pic16_emitcode ("pop","psw");
2885 if (IFFUNC_ISISR(sym->type)) {
2887 /* now we need to restore the registers */
2888 /* if this isr has no bank i.e. is going to
2889 run with bank 0 , then we need to save more
2891 if (!FUNC_REGBANK(sym->type)) {
2893 /* if this function does not call any other
2894 function then we can be economical and
2895 save only those registers that are used */
2896 if (! IFFUNC_HASFCALL(sym->type)) {
2899 /* if any registers used */
2900 if (sym->regsUsed) {
2901 /* save the registers used */
2902 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2903 if (bitVectBitValue(sym->regsUsed,i) ||
2904 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2905 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2910 /* this function has a function call cannot
2911 determines register usage so we will have the
2913 unsaverbank(0,ic,FALSE);
2917 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2919 if (options.stack10bit)
2921 pic16_emitcode ("pop", "dpx1");
2922 pic16_emitcode ("pop", "dph1");
2923 pic16_emitcode ("pop", "dpl1");
2925 pic16_emitcode ("pop", "dps");
2926 pic16_emitcode ("pop", "dpx");
2928 if (!inExcludeList("dph"))
2929 pic16_emitcode ("pop","dph");
2930 if (!inExcludeList("dpl"))
2931 pic16_emitcode ("pop","dpl");
2932 if (!inExcludeList("b"))
2933 pic16_emitcode ("pop","b");
2934 if (!inExcludeList("acc"))
2935 pic16_emitcode ("pop","acc");
2937 if (IFFUNC_ISCRITICAL(sym->type))
2938 pic16_emitcode("setb","ea");
2941 /* if debug then send end of function */
2942 /* if (options.debug && currFunc) { */
2945 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2946 FileBaseName(ic->filename),currFunc->lastLine,
2947 ic->level,ic->block);
2948 if (IS_STATIC(currFunc->etype))
2949 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2951 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2955 pic16_emitcode ("reti","");
2957 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2958 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2959 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
2960 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
2961 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2962 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2964 pic16_emitpcodeNULLop(POC_RETFIE);
2968 if (IFFUNC_ISCRITICAL(sym->type))
2969 pic16_emitcode("setb","ea");
2971 if (IFFUNC_CALLEESAVES(sym->type)) {
2974 /* if any registers used */
2975 if (sym->regsUsed) {
2976 /* save the registers used */
2977 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2978 if (bitVectBitValue(sym->regsUsed,i) ||
2979 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2980 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2986 /* if debug then send end of function */
2989 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2990 FileBaseName(ic->filename),currFunc->lastLine,
2991 ic->level,ic->block);
2992 if (IS_STATIC(currFunc->etype))
2993 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2995 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2999 pic16_emitcode ("return","");
3000 pic16_emitpcodeNULLop(POC_RETURN);
3002 /* Mark the end of a function */
3003 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3008 /*-----------------------------------------------------------------*/
3009 /* genRet - generate code for return statement */
3010 /*-----------------------------------------------------------------*/
3011 static void genRet (iCode *ic)
3013 int size,offset = 0 , pushed = 0;
3015 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3016 /* if we have no return value then
3017 just generate the "ret" */
3021 /* we have something to return then
3022 move the return value into place */
3023 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3024 size = AOP_SIZE(IC_LEFT(ic));
3028 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3030 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3032 pic16_emitcode("push","%s",l);
3035 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3037 if (strcmp(fReturn[offset],l)) {
3038 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3039 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3040 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3042 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3045 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3055 if (strcmp(fReturn[pushed],"a"))
3056 pic16_emitcode("pop",fReturn[pushed]);
3058 pic16_emitcode("pop","acc");
3061 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3064 /* generate a jump to the return label
3065 if the next is not the return statement */
3066 if (!(ic->next && ic->next->op == LABEL &&
3067 IC_LABEL(ic->next) == returnLabel)) {
3069 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3070 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3075 /*-----------------------------------------------------------------*/
3076 /* genLabel - generates a label */
3077 /*-----------------------------------------------------------------*/
3078 static void genLabel (iCode *ic)
3080 /* special case never generate */
3081 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3082 if (IC_LABEL(ic) == entryLabel)
3085 pic16_emitpLabel(IC_LABEL(ic)->key);
3086 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3089 /*-----------------------------------------------------------------*/
3090 /* genGoto - generates a goto */
3091 /*-----------------------------------------------------------------*/
3093 static void genGoto (iCode *ic)
3095 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3096 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3100 /*-----------------------------------------------------------------*/
3101 /* genMultbits :- multiplication of bits */
3102 /*-----------------------------------------------------------------*/
3103 static void genMultbits (operand *left,
3107 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3109 if(!pic16_sameRegs(AOP(result),AOP(right)))
3110 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3112 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3113 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3114 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3119 /*-----------------------------------------------------------------*/
3120 /* genMultOneByte : 8 bit multiplication & division */
3121 /*-----------------------------------------------------------------*/
3122 static void genMultOneByte (operand *left,
3126 sym_link *opetype = operandType(result);
3131 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3132 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3133 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3135 /* (if two literals, the value is computed before) */
3136 /* if one literal, literal on the right */
3137 if (AOP_TYPE(left) == AOP_LIT){
3143 size = AOP_SIZE(result);
3146 if (AOP_TYPE(right) == AOP_LIT){
3147 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3148 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3149 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3150 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3151 pic16_emitcode("call","genMultLit");
3153 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3154 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3155 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3156 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3157 pic16_emitcode("call","pic16_genMult8X8_8");
3160 pic16_genMult8X8_8 (left, right,result);
3163 /* signed or unsigned */
3164 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3165 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3167 //pic16_emitcode("mul","ab");
3168 /* if result size = 1, mul signed = mul unsigned */
3169 //pic16_aopPut(AOP(result),"a",0);
3171 } else { // (size > 1)
3173 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3174 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3175 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3176 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3178 if (SPEC_USIGN(opetype)){
3179 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3180 pic16_genUMult8X8_16 (left, right, result, NULL);
3183 /* for filling the MSBs */
3184 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3185 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3189 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3191 pic16_emitcode("mov","a,b");
3193 /* adjust the MSB if left or right neg */
3195 /* if one literal */
3196 if (AOP_TYPE(right) == AOP_LIT){
3197 pic16_emitcode("multiply ","right is a lit");
3198 /* AND literal negative */
3199 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3200 /* adjust MSB (c==0 after mul) */
3201 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3205 pic16_genSMult8X8_16 (left, right, result, NULL);
3209 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3211 pic16_emitcode("rlc","a");
3212 pic16_emitcode("subb","a,acc");
3220 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3221 //pic16_aopPut(AOP(result),"a",offset++);
3225 /*-----------------------------------------------------------------*/
3226 /* genMult - generates code for multiplication */
3227 /*-----------------------------------------------------------------*/
3228 static void genMult (iCode *ic)
3230 operand *left = IC_LEFT(ic);
3231 operand *right = IC_RIGHT(ic);
3232 operand *result= IC_RESULT(ic);
3234 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3235 /* assign the amsops */
3236 pic16_aopOp (left,ic,FALSE);
3237 pic16_aopOp (right,ic,FALSE);
3238 pic16_aopOp (result,ic,TRUE);
3240 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3242 /* special cases first */
3244 if (AOP_TYPE(left) == AOP_CRY &&
3245 AOP_TYPE(right)== AOP_CRY) {
3246 genMultbits(left,right,result);
3250 /* if both are of size == 1 */
3251 if (AOP_SIZE(left) == 1 &&
3252 AOP_SIZE(right) == 1 ) {
3253 genMultOneByte(left,right,result);
3257 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3259 /* should have been converted to function call */
3263 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3264 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3265 pic16_freeAsmop(result,NULL,ic,TRUE);
3268 /*-----------------------------------------------------------------*/
3269 /* genDivbits :- division of bits */
3270 /*-----------------------------------------------------------------*/
3271 static void genDivbits (operand *left,
3278 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3279 /* the result must be bit */
3280 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3281 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3285 pic16_emitcode("div","ab");
3286 pic16_emitcode("rrc","a");
3287 pic16_aopPut(AOP(result),"c",0);
3290 /*-----------------------------------------------------------------*/
3291 /* genDivOneByte : 8 bit division */
3292 /*-----------------------------------------------------------------*/
3293 static void genDivOneByte (operand *left,
3297 sym_link *opetype = operandType(result);
3302 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3303 size = AOP_SIZE(result) - 1;
3305 /* signed or unsigned */
3306 if (SPEC_USIGN(opetype)) {
3307 /* unsigned is easy */
3308 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3309 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3311 pic16_emitcode("div","ab");
3312 pic16_aopPut(AOP(result),"a",0);
3314 pic16_aopPut(AOP(result),zero,offset++);
3318 /* signed is a little bit more difficult */
3320 /* save the signs of the operands */
3321 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3323 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3324 pic16_emitcode("push","acc"); /* save it on the stack */
3326 /* now sign adjust for both left & right */
3327 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3329 lbl = newiTempLabel(NULL);
3330 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3331 pic16_emitcode("cpl","a");
3332 pic16_emitcode("inc","a");
3333 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3334 pic16_emitcode("mov","b,a");
3336 /* sign adjust left side */
3337 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3340 lbl = newiTempLabel(NULL);
3341 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3342 pic16_emitcode("cpl","a");
3343 pic16_emitcode("inc","a");
3344 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3346 /* now the division */
3347 pic16_emitcode("div","ab");
3348 /* we are interested in the lower order
3350 pic16_emitcode("mov","b,a");
3351 lbl = newiTempLabel(NULL);
3352 pic16_emitcode("pop","acc");
3353 /* if there was an over flow we don't
3354 adjust the sign of the result */
3355 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3356 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3358 pic16_emitcode("clr","a");
3359 pic16_emitcode("subb","a,b");
3360 pic16_emitcode("mov","b,a");
3361 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3363 /* now we are done */
3364 pic16_aopPut(AOP(result),"b",0);
3366 pic16_emitcode("mov","c,b.7");
3367 pic16_emitcode("subb","a,acc");
3370 pic16_aopPut(AOP(result),"a",offset++);
3374 /*-----------------------------------------------------------------*/
3375 /* genDiv - generates code for division */
3376 /*-----------------------------------------------------------------*/
3377 static void genDiv (iCode *ic)
3379 operand *left = IC_LEFT(ic);
3380 operand *right = IC_RIGHT(ic);
3381 operand *result= IC_RESULT(ic);
3383 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3384 /* assign the amsops */
3385 pic16_aopOp (left,ic,FALSE);
3386 pic16_aopOp (right,ic,FALSE);
3387 pic16_aopOp (result,ic,TRUE);
3389 /* special cases first */
3391 if (AOP_TYPE(left) == AOP_CRY &&
3392 AOP_TYPE(right)== AOP_CRY) {
3393 genDivbits(left,right,result);
3397 /* if both are of size == 1 */
3398 if (AOP_SIZE(left) == 1 &&
3399 AOP_SIZE(right) == 1 ) {
3400 genDivOneByte(left,right,result);
3404 /* should have been converted to function call */
3407 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3408 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3409 pic16_freeAsmop(result,NULL,ic,TRUE);
3412 /*-----------------------------------------------------------------*/
3413 /* genModbits :- modulus of bits */
3414 /*-----------------------------------------------------------------*/
3415 static void genModbits (operand *left,
3422 /* the result must be bit */
3423 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3424 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3428 pic16_emitcode("div","ab");
3429 pic16_emitcode("mov","a,b");
3430 pic16_emitcode("rrc","a");
3431 pic16_aopPut(AOP(result),"c",0);
3434 /*-----------------------------------------------------------------*/
3435 /* genModOneByte : 8 bit modulus */
3436 /*-----------------------------------------------------------------*/
3437 static void genModOneByte (operand *left,
3441 sym_link *opetype = operandType(result);
3445 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3446 /* signed or unsigned */
3447 if (SPEC_USIGN(opetype)) {
3448 /* unsigned is easy */
3449 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3450 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3452 pic16_emitcode("div","ab");
3453 pic16_aopPut(AOP(result),"b",0);
3457 /* signed is a little bit more difficult */
3459 /* save the signs of the operands */
3460 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3463 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3464 pic16_emitcode("push","acc"); /* save it on the stack */
3466 /* now sign adjust for both left & right */
3467 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3470 lbl = newiTempLabel(NULL);
3471 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3472 pic16_emitcode("cpl","a");
3473 pic16_emitcode("inc","a");
3474 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3475 pic16_emitcode("mov","b,a");
3477 /* sign adjust left side */
3478 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3481 lbl = newiTempLabel(NULL);
3482 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3483 pic16_emitcode("cpl","a");
3484 pic16_emitcode("inc","a");
3485 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3487 /* now the multiplication */
3488 pic16_emitcode("div","ab");
3489 /* we are interested in the lower order
3491 lbl = newiTempLabel(NULL);
3492 pic16_emitcode("pop","acc");
3493 /* if there was an over flow we don't
3494 adjust the sign of the result */
3495 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3496 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3498 pic16_emitcode("clr","a");
3499 pic16_emitcode("subb","a,b");
3500 pic16_emitcode("mov","b,a");
3501 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3503 /* now we are done */
3504 pic16_aopPut(AOP(result),"b",0);
3508 /*-----------------------------------------------------------------*/
3509 /* genMod - generates code for division */
3510 /*-----------------------------------------------------------------*/
3511 static void genMod (iCode *ic)
3513 operand *left = IC_LEFT(ic);
3514 operand *right = IC_RIGHT(ic);
3515 operand *result= IC_RESULT(ic);
3517 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3518 /* assign the amsops */
3519 pic16_aopOp (left,ic,FALSE);
3520 pic16_aopOp (right,ic,FALSE);
3521 pic16_aopOp (result,ic,TRUE);
3523 /* special cases first */
3525 if (AOP_TYPE(left) == AOP_CRY &&
3526 AOP_TYPE(right)== AOP_CRY) {
3527 genModbits(left,right,result);
3531 /* if both are of size == 1 */
3532 if (AOP_SIZE(left) == 1 &&
3533 AOP_SIZE(right) == 1 ) {
3534 genModOneByte(left,right,result);
3538 /* should have been converted to function call */
3542 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3543 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3544 pic16_freeAsmop(result,NULL,ic,TRUE);
3547 /*-----------------------------------------------------------------*/
3548 /* genIfxJump :- will create a jump depending on the ifx */
3549 /*-----------------------------------------------------------------*/
3551 note: May need to add parameter to indicate when a variable is in bit space.
3553 static void genIfxJump (iCode *ic, char *jval)
3556 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3557 /* if true label then we jump if condition
3559 if ( IC_TRUE(ic) ) {
3561 if(strcmp(jval,"a") == 0)
3563 else if (strcmp(jval,"c") == 0)
3566 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3567 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3570 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3571 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3575 /* false label is present */
3576 if(strcmp(jval,"a") == 0)
3578 else if (strcmp(jval,"c") == 0)
3581 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3582 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3585 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3586 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3591 /* mark the icode as generated */
3595 /*-----------------------------------------------------------------*/
3597 /*-----------------------------------------------------------------*/
3598 static void genSkip(iCode *ifx,int status_bit)
3603 if ( IC_TRUE(ifx) ) {
3604 switch(status_bit) {
3619 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3620 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3624 switch(status_bit) {
3638 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3639 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3645 /*-----------------------------------------------------------------*/
3647 /*-----------------------------------------------------------------*/
3648 static void genSkipc(resolvedIfx *rifx)
3658 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3659 rifx->generated = 1;
3662 /*-----------------------------------------------------------------*/
3664 /*-----------------------------------------------------------------*/
3665 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3670 if( (rifx->condition ^ invert_condition) & 1)
3675 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3676 rifx->generated = 1;
3679 /*-----------------------------------------------------------------*/
3681 /*-----------------------------------------------------------------*/
3682 static void genSkipz(iCode *ifx, int condition)
3693 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3695 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3698 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3700 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3703 /*-----------------------------------------------------------------*/
3705 /*-----------------------------------------------------------------*/
3706 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3712 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3714 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3717 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3718 rifx->generated = 1;
3722 /*-----------------------------------------------------------------*/
3723 /* genChkZeroes :- greater or less than comparison */
3724 /* For each byte in a literal that is zero, inclusive or the */
3725 /* the corresponding byte in the operand with W */
3726 /* returns true if any of the bytes are zero */
3727 /*-----------------------------------------------------------------*/
3728 static int genChkZeroes(operand *op, int lit, int size)
3735 i = (lit >> (size*8)) & 0xff;
3739 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3741 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3750 /*-----------------------------------------------------------------*/
3751 /* genCmp :- greater or less than comparison */
3752 /*-----------------------------------------------------------------*/
3753 static void genCmp (operand *left,operand *right,
3754 operand *result, iCode *ifx, int sign)
3756 int size; //, offset = 0 ;
3757 unsigned long lit = 0L,i = 0;
3758 resolvedIfx rFalseIfx;
3759 // resolvedIfx rTrueIfx;
3761 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3764 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3765 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3769 resolveIfx(&rFalseIfx,ifx);
3770 truelbl = newiTempLabel(NULL);
3771 size = max(AOP_SIZE(left),AOP_SIZE(right));
3773 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3777 /* if literal is on the right then swap with left */
3778 if ((AOP_TYPE(right) == AOP_LIT)) {
3779 operand *tmp = right ;
3780 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3781 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3784 lit = (lit - 1) & mask;
3787 rFalseIfx.condition ^= 1;
3790 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3791 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3795 //if(IC_TRUE(ifx) == NULL)
3796 /* if left & right are bit variables */
3797 if (AOP_TYPE(left) == AOP_CRY &&
3798 AOP_TYPE(right) == AOP_CRY ) {
3799 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3800 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3802 /* subtract right from left if at the
3803 end the carry flag is set then we know that
3804 left is greater than right */
3808 symbol *lbl = newiTempLabel(NULL);
3811 if(AOP_TYPE(right) == AOP_LIT) {
3813 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3815 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3822 genSkipCond(&rFalseIfx,left,size-1,7);
3824 /* no need to compare to 0...*/
3825 /* NOTE: this is a de-generate compare that most certainly
3826 * creates some dead code. */
3827 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3829 if(ifx) ifx->generated = 1;
3836 //i = (lit >> (size*8)) & 0xff;
3837 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3839 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3841 i = ((0-lit) & 0xff);
3844 /* lit is 0x7f, all signed chars are less than
3845 * this except for 0x7f itself */
3846 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3847 genSkipz2(&rFalseIfx,0);
3849 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3850 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3851 genSkipc(&rFalseIfx);
3856 genSkipz2(&rFalseIfx,1);
3858 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3859 genSkipc(&rFalseIfx);
3863 if(ifx) ifx->generated = 1;
3867 /* chars are out of the way. now do ints and longs */
3870 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3877 genSkipCond(&rFalseIfx,left,size,7);
3878 if(ifx) ifx->generated = 1;
3883 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3885 //rFalseIfx.condition ^= 1;
3886 //genSkipCond(&rFalseIfx,left,size,7);
3887 //rFalseIfx.condition ^= 1;
3889 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3890 if(rFalseIfx.condition)
3891 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3893 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3895 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3896 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3897 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3900 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3902 if(rFalseIfx.condition) {
3904 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3910 genSkipc(&rFalseIfx);
3911 pic16_emitpLabel(truelbl->key);
3912 if(ifx) ifx->generated = 1;
3919 if( (lit & 0xff) == 0) {
3920 /* lower byte is zero */
3921 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3922 i = ((lit >> 8) & 0xff) ^0x80;
3923 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3924 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3925 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3926 genSkipc(&rFalseIfx);
3929 if(ifx) ifx->generated = 1;
3934 /* Special cases for signed longs */
3935 if( (lit & 0xffffff) == 0) {
3936 /* lower byte is zero */
3937 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3938 i = ((lit >> 8*3) & 0xff) ^0x80;
3939 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3940 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3941 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3942 genSkipc(&rFalseIfx);
3945 if(ifx) ifx->generated = 1;
3953 if(lit & (0x80 << (size*8))) {
3954 /* lit is negative */
3955 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3957 //genSkipCond(&rFalseIfx,left,size,7);
3959 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3961 if(rFalseIfx.condition)
3962 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3964 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3968 /* lit is positive */
3969 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3970 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3971 if(rFalseIfx.condition)
3972 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3974 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3979 This works, but is only good for ints.
3980 It also requires a "known zero" register.
3981 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3982 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3983 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
3984 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3985 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3986 genSkipc(&rFalseIfx);
3988 pic16_emitpLabel(truelbl->key);
3989 if(ifx) ifx->generated = 1;
3993 /* There are no more special cases, so perform a general compare */
3995 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
3996 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4000 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4002 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4004 //rFalseIfx.condition ^= 1;
4005 genSkipc(&rFalseIfx);
4007 pic16_emitpLabel(truelbl->key);
4009 if(ifx) ifx->generated = 1;
4016 /* sign is out of the way. So now do an unsigned compare */
4017 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4020 /* General case - compare to an unsigned literal on the right.*/
4022 i = (lit >> (size*8)) & 0xff;
4023 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4024 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4026 i = (lit >> (size*8)) & 0xff;
4029 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4031 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4033 /* this byte of the lit is zero,
4034 *if it's not the last then OR in the variable */
4036 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4041 pic16_emitpLabel(lbl->key);
4042 //if(emitFinalCheck)
4043 genSkipc(&rFalseIfx);
4045 pic16_emitpLabel(truelbl->key);
4047 if(ifx) ifx->generated = 1;
4054 if(AOP_TYPE(left) == AOP_LIT) {
4055 //symbol *lbl = newiTempLabel(NULL);
4057 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4060 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4063 if((lit == 0) && (sign == 0)){
4066 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4068 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4070 genSkipz2(&rFalseIfx,0);
4071 if(ifx) ifx->generated = 1;
4078 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4079 /* degenerate compare can never be true */
4080 if(rFalseIfx.condition == 0)
4081 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4083 if(ifx) ifx->generated = 1;
4088 /* signed comparisons to a literal byte */
4090 int lp1 = (lit+1) & 0xff;
4092 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4095 rFalseIfx.condition ^= 1;
4096 genSkipCond(&rFalseIfx,right,0,7);
4099 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4100 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4101 genSkipz2(&rFalseIfx,1);
4104 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4105 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4106 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4107 rFalseIfx.condition ^= 1;
4108 genSkipc(&rFalseIfx);
4112 /* unsigned comparisons to a literal byte */
4114 switch(lit & 0xff ) {
4116 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4117 genSkipz2(&rFalseIfx,0);
4120 rFalseIfx.condition ^= 1;
4121 genSkipCond(&rFalseIfx,right,0,7);
4125 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4126 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4127 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4128 rFalseIfx.condition ^= 1;
4129 if (AOP_TYPE(result) == AOP_CRY)
4130 genSkipc(&rFalseIfx);
4132 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4133 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4139 if(ifx) ifx->generated = 1;
4145 /* Size is greater than 1 */
4153 /* this means lit = 0xffffffff, or -1 */
4156 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4157 rFalseIfx.condition ^= 1;
4158 genSkipCond(&rFalseIfx,right,size,7);
4159 if(ifx) ifx->generated = 1;
4166 if(rFalseIfx.condition) {
4167 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4168 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4171 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4173 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4177 if(rFalseIfx.condition) {
4178 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4179 pic16_emitpLabel(truelbl->key);
4181 rFalseIfx.condition ^= 1;
4182 genSkipCond(&rFalseIfx,right,s,7);
4185 if(ifx) ifx->generated = 1;
4189 if((size == 1) && (0 == (lp1&0xff))) {
4190 /* lower byte of signed word is zero */
4191 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4192 i = ((lp1 >> 8) & 0xff) ^0x80;
4193 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4194 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4195 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4196 rFalseIfx.condition ^= 1;
4197 genSkipc(&rFalseIfx);
4200 if(ifx) ifx->generated = 1;
4204 if(lit & (0x80 << (size*8))) {
4205 /* Lit is less than zero */
4206 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4207 //rFalseIfx.condition ^= 1;
4208 //genSkipCond(&rFalseIfx,left,size,7);
4209 //rFalseIfx.condition ^= 1;
4210 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4211 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4213 if(rFalseIfx.condition)
4214 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4216 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4220 /* Lit is greater than or equal to zero */
4221 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4222 //rFalseIfx.condition ^= 1;
4223 //genSkipCond(&rFalseIfx,right,size,7);
4224 //rFalseIfx.condition ^= 1;
4226 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4227 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4229 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4230 if(rFalseIfx.condition)
4231 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4233 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4238 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4239 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4243 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4245 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4247 rFalseIfx.condition ^= 1;
4248 //rFalseIfx.condition = 1;
4249 genSkipc(&rFalseIfx);
4251 pic16_emitpLabel(truelbl->key);
4253 if(ifx) ifx->generated = 1;
4258 /* compare word or long to an unsigned literal on the right.*/
4263 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4266 break; /* handled above */
4269 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4271 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4272 genSkipz2(&rFalseIfx,0);
4276 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4278 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4281 if(rFalseIfx.condition)
4282 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4284 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4287 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4288 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4290 rFalseIfx.condition ^= 1;
4291 genSkipc(&rFalseIfx);
4294 pic16_emitpLabel(truelbl->key);
4296 if(ifx) ifx->generated = 1;
4302 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4303 i = (lit >> (size*8)) & 0xff;
4305 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4306 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4309 i = (lit >> (size*8)) & 0xff;
4312 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4314 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4316 /* this byte of the lit is zero,
4317 *if it's not the last then OR in the variable */
4319 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4324 pic16_emitpLabel(lbl->key);
4326 rFalseIfx.condition ^= 1;
4327 genSkipc(&rFalseIfx);
4331 pic16_emitpLabel(truelbl->key);
4332 if(ifx) ifx->generated = 1;
4336 /* Compare two variables */
4338 DEBUGpic16_emitcode(";sign","%d",sign);
4342 /* Sigh. thus sucks... */
4344 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4345 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4346 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4347 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4348 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4349 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4351 /* Signed char comparison */
4352 /* Special thanks to Nikolai Golovchenko for this snippet */
4353 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4354 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4355 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4356 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4357 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4358 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4360 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4361 genSkipc(&rFalseIfx);
4363 if(ifx) ifx->generated = 1;
4369 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4370 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4374 /* The rest of the bytes of a multi-byte compare */
4378 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4381 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4382 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4387 pic16_emitpLabel(lbl->key);
4389 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4390 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4391 (AOP_TYPE(result) == AOP_REG)) {
4392 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4393 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4395 genSkipc(&rFalseIfx);
4397 //genSkipc(&rFalseIfx);
4398 if(ifx) ifx->generated = 1;
4405 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4406 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4407 pic16_outBitC(result);
4409 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4410 /* if the result is used in the next
4411 ifx conditional branch then generate
4412 code a little differently */
4414 genIfxJump (ifx,"c");
4416 pic16_outBitC(result);
4417 /* leave the result in acc */
4422 /*-----------------------------------------------------------------*/
4423 /* genCmpGt :- greater than comparison */
4424 /*-----------------------------------------------------------------*/
4425 static void genCmpGt (iCode *ic, iCode *ifx)
4427 operand *left, *right, *result;
4428 sym_link *letype , *retype;
4431 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4433 right= IC_RIGHT(ic);
4434 result = IC_RESULT(ic);
4436 letype = getSpec(operandType(left));
4437 retype =getSpec(operandType(right));
4438 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4439 /* assign the amsops */
4440 pic16_aopOp (left,ic,FALSE);
4441 pic16_aopOp (right,ic,FALSE);
4442 pic16_aopOp (result,ic,TRUE);
4444 genCmp(right, left, result, ifx, sign);
4446 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4447 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4448 pic16_freeAsmop(result,NULL,ic,TRUE);
4451 /*-----------------------------------------------------------------*/
4452 /* genCmpLt - less than comparisons */
4453 /*-----------------------------------------------------------------*/
4454 static void genCmpLt (iCode *ic, iCode *ifx)
4456 operand *left, *right, *result;
4457 sym_link *letype , *retype;
4460 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4462 right= IC_RIGHT(ic);
4463 result = IC_RESULT(ic);
4465 letype = getSpec(operandType(left));
4466 retype =getSpec(operandType(right));
4467 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4469 /* assign the amsops */
4470 pic16_aopOp (left,ic,FALSE);
4471 pic16_aopOp (right,ic,FALSE);
4472 pic16_aopOp (result,ic,TRUE);
4474 genCmp(left, right, result, ifx, sign);
4476 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4477 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4478 pic16_freeAsmop(result,NULL,ic,TRUE);
4481 /*-----------------------------------------------------------------*/
4482 /* genc16bit2lit - compare a 16 bit value to a literal */
4483 /*-----------------------------------------------------------------*/
4484 static void genc16bit2lit(operand *op, int lit, int offset)
4488 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4489 if( (lit&0xff) == 0)
4494 switch( BYTEofLONG(lit,i)) {
4496 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4499 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4502 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4505 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4506 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4511 switch( BYTEofLONG(lit,i)) {
4513 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4517 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4521 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4524 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4526 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4532 /*-----------------------------------------------------------------*/
4533 /* gencjneshort - compare and jump if not equal */
4534 /*-----------------------------------------------------------------*/
4535 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4537 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4539 int res_offset = 0; /* the result may be a different size then left or right */
4540 int res_size = AOP_SIZE(result);
4544 unsigned long lit = 0L;
4545 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4546 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4548 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4549 resolveIfx(&rIfx,ifx);
4550 lbl = newiTempLabel(NULL);
4553 /* if the left side is a literal or
4554 if the right is in a pointer register and left
4556 if ((AOP_TYPE(left) == AOP_LIT) ||
4557 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4562 if(AOP_TYPE(right) == AOP_LIT)
4563 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4565 /* if the right side is a literal then anything goes */
4566 if (AOP_TYPE(right) == AOP_LIT &&
4567 AOP_TYPE(left) != AOP_DIR ) {
4570 genc16bit2lit(left, lit, 0);
4572 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4577 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4578 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4580 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4584 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4586 if(res_offset < res_size-1)
4594 /* if the right side is in a register or in direct space or
4595 if the left is a pointer register & right is not */
4596 else if (AOP_TYPE(right) == AOP_REG ||
4597 AOP_TYPE(right) == AOP_DIR ||
4598 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4599 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4600 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4601 int lbl_key = lbl->key;
4604 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4605 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4607 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4608 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4609 __FUNCTION__,__LINE__);
4613 /* switch(size) { */
4615 /* genc16bit2lit(left, lit, 0); */
4617 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4622 if((AOP_TYPE(left) == AOP_DIR) &&
4623 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4625 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4626 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4628 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4630 switch (lit & 0xff) {
4632 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4635 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4636 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4637 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4641 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4642 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4643 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4644 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4648 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4649 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4654 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4657 if(AOP_TYPE(result) == AOP_CRY) {
4658 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4663 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4665 /* fix me. probably need to check result size too */
4666 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4671 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4672 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4679 if(res_offset < res_size-1)
4684 } else if(AOP_TYPE(right) == AOP_REG &&
4685 AOP_TYPE(left) != AOP_DIR){
4688 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4689 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4690 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4695 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4697 if(res_offset < res_size-1)
4702 /* right is a pointer reg need both a & b */
4704 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4706 pic16_emitcode("mov","b,%s",l);
4707 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4708 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4713 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4715 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4717 pic16_emitpLabel(lbl->key);
4719 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4726 /*-----------------------------------------------------------------*/
4727 /* gencjne - compare and jump if not equal */
4728 /*-----------------------------------------------------------------*/
4729 static void gencjne(operand *left, operand *right, iCode *ifx)
4731 symbol *tlbl = newiTempLabel(NULL);
4733 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4734 gencjneshort(left, right, lbl);
4736 pic16_emitcode("mov","a,%s",one);
4737 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4738 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4739 pic16_emitcode("clr","a");
4740 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4742 pic16_emitpLabel(lbl->key);
4743 pic16_emitpLabel(tlbl->key);
4748 /*-----------------------------------------------------------------*/
4749 /* genCmpEq - generates code for equal to */
4750 /*-----------------------------------------------------------------*/
4751 static void genCmpEq (iCode *ic, iCode *ifx)
4753 operand *left, *right, *result;
4754 unsigned long lit = 0L;
4757 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4760 DEBUGpic16_emitcode ("; ifx is non-null","");
4762 DEBUGpic16_emitcode ("; ifx is null","");
4764 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4765 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4766 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4768 size = max(AOP_SIZE(left),AOP_SIZE(right));
4770 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4772 /* if literal, literal on the right or
4773 if the right is in a pointer register and left
4775 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4776 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4777 operand *tmp = right ;
4783 if(ifx && !AOP_SIZE(result)){
4785 /* if they are both bit variables */
4786 if (AOP_TYPE(left) == AOP_CRY &&
4787 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4788 if(AOP_TYPE(right) == AOP_LIT){
4789 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4791 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4792 pic16_emitcode("cpl","c");
4793 } else if(lit == 1L) {
4794 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4796 pic16_emitcode("clr","c");
4798 /* AOP_TYPE(right) == AOP_CRY */
4800 symbol *lbl = newiTempLabel(NULL);
4801 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4802 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4803 pic16_emitcode("cpl","c");
4804 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4806 /* if true label then we jump if condition
4808 tlbl = newiTempLabel(NULL);
4809 if ( IC_TRUE(ifx) ) {
4810 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4811 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4813 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4814 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4816 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4819 /* left and right are both bit variables, result is carry */
4822 resolveIfx(&rIfx,ifx);
4824 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4825 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4826 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4827 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4832 /* They're not both bit variables. Is the right a literal? */
4833 if(AOP_TYPE(right) == AOP_LIT) {
4834 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4839 switch(lit & 0xff) {
4841 if ( IC_TRUE(ifx) ) {
4842 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4844 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4846 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4847 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4851 if ( IC_TRUE(ifx) ) {
4852 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4854 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4856 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4857 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4861 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4863 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4868 /* end of size == 1 */
4872 genc16bit2lit(left,lit,offset);
4875 /* end of size == 2 */
4880 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4881 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4882 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4883 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4887 /* search for patterns that can be optimized */
4889 genc16bit2lit(left,lit,0);
4892 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4894 genc16bit2lit(left,lit,2);
4896 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4897 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4910 } else if(AOP_TYPE(right) == AOP_CRY ) {
4911 /* we know the left is not a bit, but that the right is */
4912 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4913 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4914 pic16_popGet(AOP(right),offset));
4915 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4917 /* if the two are equal, then W will be 0 and the Z bit is set
4918 * we could test Z now, or go ahead and check the high order bytes if
4919 * the variable we're comparing is larger than a byte. */
4922 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4924 if ( IC_TRUE(ifx) ) {
4926 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4927 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4930 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4931 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4935 /* They're both variables that are larger than bits */
4938 tlbl = newiTempLabel(NULL);
4941 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4942 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4944 if ( IC_TRUE(ifx) ) {
4947 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4948 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4951 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4952 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4956 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4957 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4961 if(s>1 && IC_TRUE(ifx)) {
4962 pic16_emitpLabel(tlbl->key);
4963 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4967 /* mark the icode as generated */
4972 /* if they are both bit variables */
4973 if (AOP_TYPE(left) == AOP_CRY &&
4974 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4975 if(AOP_TYPE(right) == AOP_LIT){
4976 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4978 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4979 pic16_emitcode("cpl","c");
4980 } else if(lit == 1L) {
4981 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4983 pic16_emitcode("clr","c");
4985 /* AOP_TYPE(right) == AOP_CRY */
4987 symbol *lbl = newiTempLabel(NULL);
4988 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4989 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4990 pic16_emitcode("cpl","c");
4991 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4994 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4995 pic16_outBitC(result);
4999 genIfxJump (ifx,"c");
5002 /* if the result is used in an arithmetic operation
5003 then put the result in place */
5004 pic16_outBitC(result);
5007 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5008 gencjne(left,right,result,ifx);
5011 gencjne(left,right,newiTempLabel(NULL));
5013 if(IC_TRUE(ifx)->key)
5014 gencjne(left,right,IC_TRUE(ifx)->key);
5016 gencjne(left,right,IC_FALSE(ifx)->key);
5020 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5021 pic16_aopPut(AOP(result),"a",0);
5026 genIfxJump (ifx,"a");
5030 /* if the result is used in an arithmetic operation
5031 then put the result in place */
5033 if (AOP_TYPE(result) != AOP_CRY)
5034 pic16_outAcc(result);
5036 /* leave the result in acc */
5040 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5041 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5042 pic16_freeAsmop(result,NULL,ic,TRUE);
5045 /*-----------------------------------------------------------------*/
5046 /* ifxForOp - returns the icode containing the ifx for operand */
5047 /*-----------------------------------------------------------------*/
5048 static iCode *ifxForOp ( operand *op, iCode *ic )
5050 /* if true symbol then needs to be assigned */
5051 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5052 if (IS_TRUE_SYMOP(op))
5055 /* if this has register type condition and
5056 the next instruction is ifx with the same operand
5057 and live to of the operand is upto the ifx only then */
5059 ic->next->op == IFX &&
5060 IC_COND(ic->next)->key == op->key &&
5061 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5065 ic->next->op == IFX &&
5066 IC_COND(ic->next)->key == op->key) {
5067 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5071 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5073 ic->next->op == IFX)
5074 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5077 ic->next->op == IFX &&
5078 IC_COND(ic->next)->key == op->key) {
5079 DEBUGpic16_emitcode ("; "," key is okay");
5080 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5081 OP_SYMBOL(op)->liveTo,
5088 /*-----------------------------------------------------------------*/
5089 /* genAndOp - for && operation */
5090 /*-----------------------------------------------------------------*/
5091 static void genAndOp (iCode *ic)
5093 operand *left,*right, *result;
5096 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5097 /* note here that && operations that are in an
5098 if statement are taken away by backPatchLabels
5099 only those used in arthmetic operations remain */
5100 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5101 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5102 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5104 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5106 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5107 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5108 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5110 /* if both are bit variables */
5111 /* if (AOP_TYPE(left) == AOP_CRY && */
5112 /* AOP_TYPE(right) == AOP_CRY ) { */
5113 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5114 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5115 /* pic16_outBitC(result); */
5117 /* tlbl = newiTempLabel(NULL); */
5118 /* pic16_toBoolean(left); */
5119 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5120 /* pic16_toBoolean(right); */
5121 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5122 /* pic16_outBitAcc(result); */
5125 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5126 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5127 pic16_freeAsmop(result,NULL,ic,TRUE);
5131 /*-----------------------------------------------------------------*/
5132 /* genOrOp - for || operation */
5133 /*-----------------------------------------------------------------*/
5136 modified this code, but it doesn't appear to ever get called
5139 static void genOrOp (iCode *ic)
5141 operand *left,*right, *result;
5144 /* note here that || operations that are in an
5145 if statement are taken away by backPatchLabels
5146 only those used in arthmetic operations remain */
5147 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5148 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5149 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5150 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5152 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5154 /* if both are bit variables */
5155 if (AOP_TYPE(left) == AOP_CRY &&
5156 AOP_TYPE(right) == AOP_CRY ) {
5157 pic16_emitcode("clrc","");
5158 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5159 AOP(left)->aopu.aop_dir,
5160 AOP(left)->aopu.aop_dir);
5161 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5162 AOP(right)->aopu.aop_dir,
5163 AOP(right)->aopu.aop_dir);
5164 pic16_emitcode("setc","");
5167 tlbl = newiTempLabel(NULL);
5168 pic16_toBoolean(left);
5170 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5171 pic16_toBoolean(right);
5172 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5174 pic16_outBitAcc(result);
5177 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5178 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5179 pic16_freeAsmop(result,NULL,ic,TRUE);
5182 /*-----------------------------------------------------------------*/
5183 /* isLiteralBit - test if lit == 2^n */
5184 /*-----------------------------------------------------------------*/
5185 static int isLiteralBit(unsigned long lit)
5187 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5188 0x100L,0x200L,0x400L,0x800L,
5189 0x1000L,0x2000L,0x4000L,0x8000L,
5190 0x10000L,0x20000L,0x40000L,0x80000L,
5191 0x100000L,0x200000L,0x400000L,0x800000L,
5192 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5193 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5197 for(idx = 0; idx < 32; idx++)
5203 /*-----------------------------------------------------------------*/
5204 /* continueIfTrue - */
5205 /*-----------------------------------------------------------------*/
5206 static void continueIfTrue (iCode *ic)
5208 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5210 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5214 /*-----------------------------------------------------------------*/
5216 /*-----------------------------------------------------------------*/
5217 static void jumpIfTrue (iCode *ic)
5219 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5221 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5225 /*-----------------------------------------------------------------*/
5226 /* jmpTrueOrFalse - */
5227 /*-----------------------------------------------------------------*/
5228 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5230 // ugly but optimized by peephole
5231 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5233 symbol *nlbl = newiTempLabel(NULL);
5234 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5235 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5236 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5237 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5240 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5241 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5246 /*-----------------------------------------------------------------*/
5247 /* genAnd - code for and */
5248 /*-----------------------------------------------------------------*/
5249 static void genAnd (iCode *ic, iCode *ifx)
5251 operand *left, *right, *result;
5253 unsigned long lit = 0L;
5258 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5259 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5260 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5261 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5263 resolveIfx(&rIfx,ifx);
5265 /* if left is a literal & right is not then exchange them */
5266 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5267 AOP_NEEDSACC(left)) {
5268 operand *tmp = right ;
5273 /* if result = right then exchange them */
5274 if(pic16_sameRegs(AOP(result),AOP(right))){
5275 operand *tmp = right ;
5280 /* if right is bit then exchange them */
5281 if (AOP_TYPE(right) == AOP_CRY &&
5282 AOP_TYPE(left) != AOP_CRY){
5283 operand *tmp = right ;
5287 if(AOP_TYPE(right) == AOP_LIT)
5288 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5290 size = AOP_SIZE(result);
5292 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5295 // result = bit & yy;
5296 if (AOP_TYPE(left) == AOP_CRY){
5297 // c = bit & literal;
5298 if(AOP_TYPE(right) == AOP_LIT){
5300 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5303 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5306 if(size && (AOP_TYPE(result) == AOP_CRY)){
5307 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5310 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5314 pic16_emitcode("clr","c");
5317 if (AOP_TYPE(right) == AOP_CRY){
5319 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5320 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5323 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5325 pic16_emitcode("rrc","a");
5326 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5332 pic16_outBitC(result);
5334 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5335 genIfxJump(ifx, "c");
5339 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5340 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5341 if((AOP_TYPE(right) == AOP_LIT) &&
5342 (AOP_TYPE(result) == AOP_CRY) &&
5343 (AOP_TYPE(left) != AOP_CRY)){
5344 int posbit = isLiteralBit(lit);
5348 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5351 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5357 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5358 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5360 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5361 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5364 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5365 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5366 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5373 symbol *tlbl = newiTempLabel(NULL);
5374 int sizel = AOP_SIZE(left);
5376 pic16_emitcode("setb","c");
5378 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5379 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5381 if((posbit = isLiteralBit(bytelit)) != 0)
5382 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5384 if(bytelit != 0x0FFL)
5385 pic16_emitcode("anl","a,%s",
5386 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5387 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5392 // bit = left & literal
5394 pic16_emitcode("clr","c");
5395 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5397 // if(left & literal)
5400 jmpTrueOrFalse(ifx, tlbl);
5404 pic16_outBitC(result);
5408 /* if left is same as result */
5409 if(pic16_sameRegs(AOP(result),AOP(left))){
5411 for(;size--; offset++,lit>>=8) {
5412 if(AOP_TYPE(right) == AOP_LIT){
5413 switch(lit & 0xff) {
5415 /* and'ing with 0 has clears the result */
5416 pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5417 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5420 /* and'ing with 0xff is a nop when the result and left are the same */
5425 int p = my_powof2( (~lit) & 0xff );
5427 /* only one bit is set in the literal, so use a bcf instruction */
5428 pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5429 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5432 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5433 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5434 if(know_W != (lit&0xff))
5435 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5437 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5442 if (AOP_TYPE(left) == AOP_ACC) {
5443 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5445 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5446 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5453 // left & result in different registers
5454 if(AOP_TYPE(result) == AOP_CRY){
5456 // if(size), result in bit
5457 // if(!size && ifx), conditional oper: if(left & right)
5458 symbol *tlbl = newiTempLabel(NULL);
5459 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5461 pic16_emitcode("setb","c");
5463 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5464 pic16_emitcode("anl","a,%s",
5465 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5466 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5471 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5472 pic16_outBitC(result);
5474 jmpTrueOrFalse(ifx, tlbl);
5476 for(;(size--);offset++) {
5478 // result = left & right
5479 if(AOP_TYPE(right) == AOP_LIT){
5480 int t = (lit >> (offset*8)) & 0x0FFL;
5483 pic16_emitcode("clrf","%s",
5484 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5485 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5488 pic16_emitcode("movf","%s,w",
5489 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5490 pic16_emitcode("movwf","%s",
5491 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5492 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5493 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5496 pic16_emitcode("movlw","0x%x",t);
5497 pic16_emitcode("andwf","%s,w",
5498 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5499 pic16_emitcode("movwf","%s",
5500 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5502 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5503 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5504 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5509 if (AOP_TYPE(left) == AOP_ACC) {
5510 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5511 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5513 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5514 pic16_emitcode("andwf","%s,w",
5515 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5516 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5517 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5519 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5520 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5526 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5527 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5528 pic16_freeAsmop(result,NULL,ic,TRUE);
5531 /*-----------------------------------------------------------------*/
5532 /* genOr - code for or */
5533 /*-----------------------------------------------------------------*/
5534 static void genOr (iCode *ic, iCode *ifx)
5536 operand *left, *right, *result;
5538 unsigned long lit = 0L;
5540 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5542 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5543 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5544 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5546 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5548 /* if left is a literal & right is not then exchange them */
5549 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5550 AOP_NEEDSACC(left)) {
5551 operand *tmp = right ;
5556 /* if result = right then exchange them */
5557 if(pic16_sameRegs(AOP(result),AOP(right))){
5558 operand *tmp = right ;
5563 /* if right is bit then exchange them */
5564 if (AOP_TYPE(right) == AOP_CRY &&
5565 AOP_TYPE(left) != AOP_CRY){
5566 operand *tmp = right ;
5571 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5573 if(AOP_TYPE(right) == AOP_LIT)
5574 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5576 size = AOP_SIZE(result);
5580 if (AOP_TYPE(left) == AOP_CRY){
5581 if(AOP_TYPE(right) == AOP_LIT){
5582 // c = bit & literal;
5584 // lit != 0 => result = 1
5585 if(AOP_TYPE(result) == AOP_CRY){
5587 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5588 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5589 // AOP(result)->aopu.aop_dir,
5590 // AOP(result)->aopu.aop_dir);
5592 continueIfTrue(ifx);
5596 // lit == 0 => result = left
5597 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5599 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5602 if (AOP_TYPE(right) == AOP_CRY){
5603 if(pic16_sameRegs(AOP(result),AOP(left))){
5605 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5606 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5607 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5609 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5610 AOP(result)->aopu.aop_dir,
5611 AOP(result)->aopu.aop_dir);
5612 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5613 AOP(right)->aopu.aop_dir,
5614 AOP(right)->aopu.aop_dir);
5615 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5616 AOP(result)->aopu.aop_dir,
5617 AOP(result)->aopu.aop_dir);
5619 if( AOP_TYPE(result) == AOP_ACC) {
5620 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5621 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5622 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5623 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5627 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5628 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5629 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5630 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5632 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5633 AOP(result)->aopu.aop_dir,
5634 AOP(result)->aopu.aop_dir);
5635 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5636 AOP(right)->aopu.aop_dir,
5637 AOP(right)->aopu.aop_dir);
5638 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5639 AOP(left)->aopu.aop_dir,
5640 AOP(left)->aopu.aop_dir);
5641 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5642 AOP(result)->aopu.aop_dir,
5643 AOP(result)->aopu.aop_dir);
5648 symbol *tlbl = newiTempLabel(NULL);
5649 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5652 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5653 if( AOP_TYPE(right) == AOP_ACC) {
5654 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5656 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5657 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5662 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5663 pic16_emitcode(";XXX setb","c");
5664 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5665 AOP(left)->aopu.aop_dir,tlbl->key+100);
5666 pic16_toBoolean(right);
5667 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5668 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5669 jmpTrueOrFalse(ifx, tlbl);
5673 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5680 pic16_outBitC(result);
5682 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5683 genIfxJump(ifx, "c");
5687 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5688 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5689 if((AOP_TYPE(right) == AOP_LIT) &&
5690 (AOP_TYPE(result) == AOP_CRY) &&
5691 (AOP_TYPE(left) != AOP_CRY)){
5693 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5696 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5698 continueIfTrue(ifx);
5701 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5702 // lit = 0, result = boolean(left)
5704 pic16_emitcode(";XXX setb","c");
5705 pic16_toBoolean(right);
5707 symbol *tlbl = newiTempLabel(NULL);
5708 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5710 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5712 genIfxJump (ifx,"a");
5716 pic16_outBitC(result);
5720 /* if left is same as result */
5721 if(pic16_sameRegs(AOP(result),AOP(left))){
5723 for(;size--; offset++,lit>>=8) {
5724 if(AOP_TYPE(right) == AOP_LIT){
5725 if((lit & 0xff) == 0)
5726 /* or'ing with 0 has no effect */
5729 int p = my_powof2(lit & 0xff);
5731 /* only one bit is set in the literal, so use a bsf instruction */
5732 pic16_emitpcode(POC_BSF,
5733 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5735 if(know_W != (lit & 0xff))
5736 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5737 know_W = lit & 0xff;
5738 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5743 if (AOP_TYPE(left) == AOP_ACC) {
5744 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5745 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5747 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5748 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5750 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5751 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5757 // left & result in different registers
5758 if(AOP_TYPE(result) == AOP_CRY){
5760 // if(size), result in bit
5761 // if(!size && ifx), conditional oper: if(left | right)
5762 symbol *tlbl = newiTempLabel(NULL);
5763 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5764 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5768 pic16_emitcode(";XXX setb","c");
5770 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5771 pic16_emitcode(";XXX orl","a,%s",
5772 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5773 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5778 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5779 pic16_outBitC(result);
5781 jmpTrueOrFalse(ifx, tlbl);
5782 } else for(;(size--);offset++){
5784 // result = left & right
5785 if(AOP_TYPE(right) == AOP_LIT){
5786 int t = (lit >> (offset*8)) & 0x0FFL;
5789 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5790 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5792 pic16_emitcode("movf","%s,w",
5793 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5794 pic16_emitcode("movwf","%s",
5795 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5798 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5799 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5800 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5802 pic16_emitcode("movlw","0x%x",t);
5803 pic16_emitcode("iorwf","%s,w",
5804 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5805 pic16_emitcode("movwf","%s",
5806 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5812 // faster than result <- left, anl result,right
5813 // and better if result is SFR
5814 if (AOP_TYPE(left) == AOP_ACC) {
5815 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5816 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5818 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5819 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5821 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5822 pic16_emitcode("iorwf","%s,w",
5823 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5825 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5826 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5831 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5832 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5833 pic16_freeAsmop(result,NULL,ic,TRUE);
5836 /*-----------------------------------------------------------------*/
5837 /* genXor - code for xclusive or */
5838 /*-----------------------------------------------------------------*/
5839 static void genXor (iCode *ic, iCode *ifx)
5841 operand *left, *right, *result;
5843 unsigned long lit = 0L;
5845 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5847 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5848 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5849 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5851 /* if left is a literal & right is not ||
5852 if left needs acc & right does not */
5853 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5854 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5855 operand *tmp = right ;
5860 /* if result = right then exchange them */
5861 if(pic16_sameRegs(AOP(result),AOP(right))){
5862 operand *tmp = right ;
5867 /* if right is bit then exchange them */
5868 if (AOP_TYPE(right) == AOP_CRY &&
5869 AOP_TYPE(left) != AOP_CRY){
5870 operand *tmp = right ;
5874 if(AOP_TYPE(right) == AOP_LIT)
5875 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5877 size = AOP_SIZE(result);
5881 if (AOP_TYPE(left) == AOP_CRY){
5882 if(AOP_TYPE(right) == AOP_LIT){
5883 // c = bit & literal;
5885 // lit>>1 != 0 => result = 1
5886 if(AOP_TYPE(result) == AOP_CRY){
5888 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
5889 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5891 continueIfTrue(ifx);
5894 pic16_emitcode("setb","c");
5898 // lit == 0, result = left
5899 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5901 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5903 // lit == 1, result = not(left)
5904 if(size && pic16_sameRegs(AOP(result),AOP(left))){
5905 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
5906 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
5907 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5910 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5911 pic16_emitcode("cpl","c");
5918 symbol *tlbl = newiTempLabel(NULL);
5919 if (AOP_TYPE(right) == AOP_CRY){
5921 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5924 int sizer = AOP_SIZE(right);
5926 // if val>>1 != 0, result = 1
5927 pic16_emitcode("setb","c");
5929 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5931 // test the msb of the lsb
5932 pic16_emitcode("anl","a,#0xfe");
5933 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5937 pic16_emitcode("rrc","a");
5939 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5940 pic16_emitcode("cpl","c");
5941 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5946 pic16_outBitC(result);
5948 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5949 genIfxJump(ifx, "c");
5953 if(pic16_sameRegs(AOP(result),AOP(left))){
5954 /* if left is same as result */
5955 for(;size--; offset++) {
5956 if(AOP_TYPE(right) == AOP_LIT){
5957 int t = (lit >> (offset*8)) & 0x0FFL;
5961 if (IS_AOP_PREG(left)) {
5962 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5963 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5964 pic16_aopPut(AOP(result),"a",offset);
5966 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5967 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5968 pic16_emitcode("xrl","%s,%s",
5969 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5970 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5973 if (AOP_TYPE(left) == AOP_ACC)
5974 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5976 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5977 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5979 if (IS_AOP_PREG(left)) {
5980 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5981 pic16_aopPut(AOP(result),"a",offset);
5983 pic16_emitcode("xrl","%s,a",
5984 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5990 // left & result in different registers
5991 if(AOP_TYPE(result) == AOP_CRY){
5993 // if(size), result in bit
5994 // if(!size && ifx), conditional oper: if(left ^ right)
5995 symbol *tlbl = newiTempLabel(NULL);
5996 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5998 pic16_emitcode("setb","c");
6000 if((AOP_TYPE(right) == AOP_LIT) &&
6001 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6002 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6004 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6005 pic16_emitcode("xrl","a,%s",
6006 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6008 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6013 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6014 pic16_outBitC(result);
6016 jmpTrueOrFalse(ifx, tlbl);
6017 } else for(;(size--);offset++){
6019 // result = left & right
6020 if(AOP_TYPE(right) == AOP_LIT){
6021 int t = (lit >> (offset*8)) & 0x0FFL;
6024 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6025 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6026 pic16_emitcode("movf","%s,w",
6027 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6028 pic16_emitcode("movwf","%s",
6029 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6032 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6033 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6034 pic16_emitcode("comf","%s,w",
6035 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6036 pic16_emitcode("movwf","%s",
6037 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6040 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6041 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6042 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6043 pic16_emitcode("movlw","0x%x",t);
6044 pic16_emitcode("xorwf","%s,w",
6045 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6046 pic16_emitcode("movwf","%s",
6047 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6053 // faster than result <- left, anl result,right
6054 // and better if result is SFR
6055 if (AOP_TYPE(left) == AOP_ACC) {
6056 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6057 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6059 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6060 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6061 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6062 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6064 if ( AOP_TYPE(result) != AOP_ACC){
6065 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6066 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6072 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6073 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6074 pic16_freeAsmop(result,NULL,ic,TRUE);
6077 /*-----------------------------------------------------------------*/
6078 /* genInline - write the inline code out */
6079 /*-----------------------------------------------------------------*/
6080 static void genInline (iCode *ic)
6082 char *buffer, *bp, *bp1;
6084 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6086 _G.inLine += (!options.asmpeep);
6088 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6089 strcpy(buffer,IC_INLINE(ic));
6091 /* emit each line as a code */
6097 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6104 pic16_emitcode(bp1,"");
6110 if ((bp1 != bp) && *bp1)
6111 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6115 _G.inLine -= (!options.asmpeep);
6118 /*-----------------------------------------------------------------*/
6119 /* genRRC - rotate right with carry */
6120 /*-----------------------------------------------------------------*/
6121 static void genRRC (iCode *ic)
6123 operand *left , *result ;
6124 int size, offset = 0, same;
6126 /* rotate right with carry */
6128 result=IC_RESULT(ic);
6129 pic16_aopOp (left,ic,FALSE);
6130 pic16_aopOp (result,ic,FALSE);
6132 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6134 same = pic16_sameRegs(AOP(result),AOP(left));
6136 size = AOP_SIZE(result);
6138 /* get the lsb and put it into the carry */
6139 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6146 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6148 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6149 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6155 pic16_freeAsmop(left,NULL,ic,TRUE);
6156 pic16_freeAsmop(result,NULL,ic,TRUE);
6159 /*-----------------------------------------------------------------*/
6160 /* genRLC - generate code for rotate left with carry */
6161 /*-----------------------------------------------------------------*/
6162 static void genRLC (iCode *ic)
6164 operand *left , *result ;
6165 int size, offset = 0;
6168 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6169 /* rotate right with carry */
6171 result=IC_RESULT(ic);
6172 pic16_aopOp (left,ic,FALSE);
6173 pic16_aopOp (result,ic,FALSE);
6175 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6177 same = pic16_sameRegs(AOP(result),AOP(left));
6179 /* move it to the result */
6180 size = AOP_SIZE(result);
6182 /* get the msb and put it into the carry */
6183 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6190 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6192 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6193 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6200 pic16_freeAsmop(left,NULL,ic,TRUE);
6201 pic16_freeAsmop(result,NULL,ic,TRUE);
6204 /*-----------------------------------------------------------------*/
6205 /* genGetHbit - generates code get highest order bit */
6206 /*-----------------------------------------------------------------*/
6207 static void genGetHbit (iCode *ic)
6209 operand *left, *result;
6211 result=IC_RESULT(ic);
6212 pic16_aopOp (left,ic,FALSE);
6213 pic16_aopOp (result,ic,FALSE);
6215 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6216 /* get the highest order byte into a */
6217 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6218 if(AOP_TYPE(result) == AOP_CRY){
6219 pic16_emitcode("rlc","a");
6220 pic16_outBitC(result);
6223 pic16_emitcode("rl","a");
6224 pic16_emitcode("anl","a,#0x01");
6225 pic16_outAcc(result);
6229 pic16_freeAsmop(left,NULL,ic,TRUE);
6230 pic16_freeAsmop(result,NULL,ic,TRUE);
6233 /*-----------------------------------------------------------------*/
6234 /* AccRol - rotate left accumulator by known count */
6235 /*-----------------------------------------------------------------*/
6236 static void AccRol (int shCount)
6238 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6239 shCount &= 0x0007; // shCount : 0..7
6244 pic16_emitcode("rl","a");
6247 pic16_emitcode("rl","a");
6248 pic16_emitcode("rl","a");
6251 pic16_emitcode("swap","a");
6252 pic16_emitcode("rr","a");
6255 pic16_emitcode("swap","a");
6258 pic16_emitcode("swap","a");
6259 pic16_emitcode("rl","a");
6262 pic16_emitcode("rr","a");
6263 pic16_emitcode("rr","a");
6266 pic16_emitcode("rr","a");
6271 /*-----------------------------------------------------------------*/
6272 /* AccLsh - left shift accumulator by known count */
6273 /*-----------------------------------------------------------------*/
6274 static void AccLsh (int shCount)
6276 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6279 pic16_emitcode("add","a,acc");
6282 pic16_emitcode("add","a,acc");
6283 pic16_emitcode("add","a,acc");
6285 /* rotate left accumulator */
6287 /* and kill the lower order bits */
6288 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6293 /*-----------------------------------------------------------------*/
6294 /* AccRsh - right shift accumulator by known count */
6295 /*-----------------------------------------------------------------*/
6296 static void AccRsh (int shCount)
6298 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6302 pic16_emitcode("rrc","a");
6304 /* rotate right accumulator */
6305 AccRol(8 - shCount);
6306 /* and kill the higher order bits */
6307 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6313 /*-----------------------------------------------------------------*/
6314 /* AccSRsh - signed right shift accumulator by known count */
6315 /*-----------------------------------------------------------------*/
6316 static void AccSRsh (int shCount)
6319 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6322 pic16_emitcode("mov","c,acc.7");
6323 pic16_emitcode("rrc","a");
6324 } else if(shCount == 2){
6325 pic16_emitcode("mov","c,acc.7");
6326 pic16_emitcode("rrc","a");
6327 pic16_emitcode("mov","c,acc.7");
6328 pic16_emitcode("rrc","a");
6330 tlbl = newiTempLabel(NULL);
6331 /* rotate right accumulator */
6332 AccRol(8 - shCount);
6333 /* and kill the higher order bits */
6334 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6335 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6336 pic16_emitcode("orl","a,#0x%02x",
6337 (unsigned char)~SRMask[shCount]);
6338 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6343 /*-----------------------------------------------------------------*/
6344 /* shiftR1Left2Result - shift right one byte from left to result */
6345 /*-----------------------------------------------------------------*/
6346 static void shiftR1Left2ResultSigned (operand *left, int offl,
6347 operand *result, int offr,
6352 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6354 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6358 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6360 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6362 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6363 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6369 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6371 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6373 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6374 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6376 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6377 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6383 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6385 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6386 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6389 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6390 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6391 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6393 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6394 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6396 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6400 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6401 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6402 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6403 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6404 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6408 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6410 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6411 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6413 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6414 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6415 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6416 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6417 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6422 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6423 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6424 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6425 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6426 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6427 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6429 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6430 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6431 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6432 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6433 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6439 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6440 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6441 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6442 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6444 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6445 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6446 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6454 /*-----------------------------------------------------------------*/
6455 /* shiftR1Left2Result - shift right one byte from left to result */
6456 /*-----------------------------------------------------------------*/
6457 static void shiftR1Left2Result (operand *left, int offl,
6458 operand *result, int offr,
6459 int shCount, int sign)
6463 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6465 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6467 /* Copy the msb into the carry if signed. */
6469 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6479 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6481 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6482 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6488 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6490 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6491 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6494 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6499 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6501 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6502 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6505 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6506 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6507 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6508 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6512 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6513 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6514 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6518 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6519 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6520 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6522 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6527 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6528 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6529 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6530 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6531 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6536 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6537 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6538 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6547 /*-----------------------------------------------------------------*/
6548 /* shiftL1Left2Result - shift left one byte from left to result */
6549 /*-----------------------------------------------------------------*/
6550 static void shiftL1Left2Result (operand *left, int offl,
6551 operand *result, int offr, int shCount)
6556 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6558 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6559 DEBUGpic16_emitcode ("; ***","same = %d",same);
6560 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6562 /* shift left accumulator */
6563 //AccLsh(shCount); // don't comment out just yet...
6564 // pic16_aopPut(AOP(result),"a",offr);
6568 /* Shift left 1 bit position */
6569 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6571 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6573 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6574 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6578 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6579 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6580 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6581 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6584 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6585 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6586 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6587 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6588 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6591 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6592 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6593 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6596 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6597 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6598 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6599 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6602 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6603 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6604 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6605 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6606 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6609 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6610 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6611 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6615 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6620 /*-----------------------------------------------------------------*/
6621 /* movLeft2Result - move byte from left to result */
6622 /*-----------------------------------------------------------------*/
6623 static void movLeft2Result (operand *left, int offl,
6624 operand *result, int offr)
6627 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6628 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6629 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6631 if (*l == '@' && (IS_AOP_PREG(result))) {
6632 pic16_emitcode("mov","a,%s",l);
6633 pic16_aopPut(AOP(result),"a",offr);
6635 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6636 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6641 /*-----------------------------------------------------------------*/
6642 /* shiftL2Left2Result - shift left two bytes from left to result */
6643 /*-----------------------------------------------------------------*/
6644 static void shiftL2Left2Result (operand *left, int offl,
6645 operand *result, int offr, int shCount)
6649 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6651 if(pic16_sameRegs(AOP(result), AOP(left))) {
6659 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6660 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6661 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6665 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6666 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6672 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6673 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6674 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6675 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6676 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6677 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6678 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6680 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6681 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6685 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6686 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6687 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6688 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6689 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6690 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6691 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6692 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6693 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6694 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6697 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6698 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6699 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6700 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6701 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6711 /* note, use a mov/add for the shift since the mov has a
6712 chance of getting optimized out */
6713 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6714 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6715 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6716 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6717 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6721 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6722 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6728 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6729 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6730 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6731 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6732 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6733 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6734 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6735 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6739 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6740 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6744 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6745 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6746 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6747 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6749 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6750 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6751 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6752 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6753 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6754 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6755 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6756 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6759 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6760 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6761 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6762 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6763 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6768 /*-----------------------------------------------------------------*/
6769 /* shiftR2Left2Result - shift right two bytes from left to result */
6770 /*-----------------------------------------------------------------*/
6771 static void shiftR2Left2Result (operand *left, int offl,
6772 operand *result, int offr,
6773 int shCount, int sign)
6777 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6778 same = pic16_sameRegs(AOP(result), AOP(left));
6780 if(same && ((offl + MSB16) == offr)){
6782 /* don't crash result[offr] */
6783 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6784 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6787 movLeft2Result(left,offl, result, offr);
6788 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6791 /* a:x >> shCount (x = lsb(result))*/
6794 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6796 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6805 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6810 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6811 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6813 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6814 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6815 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6816 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6821 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6824 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6825 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6832 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6833 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6834 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6836 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6837 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6838 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6839 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6841 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6842 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6843 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6845 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6846 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6847 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6848 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6849 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6853 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6854 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6858 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6859 pic16_emitpcode(POC_BTFSC,
6860 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6861 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6869 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6870 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6872 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6873 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6874 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6875 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6877 pic16_emitpcode(POC_BTFSC,
6878 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6879 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6881 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6882 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6883 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6884 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6886 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6887 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6888 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6889 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6890 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6891 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6892 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6893 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6895 pic16_emitpcode(POC_BTFSC,
6896 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6897 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6899 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6900 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6907 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6908 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6909 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6910 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6913 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6915 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6920 /*-----------------------------------------------------------------*/
6921 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6922 /*-----------------------------------------------------------------*/
6923 static void shiftLLeftOrResult (operand *left, int offl,
6924 operand *result, int offr, int shCount)
6926 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6927 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6928 /* shift left accumulator */
6930 /* or with result */
6931 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6932 /* back to result */
6933 pic16_aopPut(AOP(result),"a",offr);
6936 /*-----------------------------------------------------------------*/
6937 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6938 /*-----------------------------------------------------------------*/
6939 static void shiftRLeftOrResult (operand *left, int offl,
6940 operand *result, int offr, int shCount)
6942 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6943 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6944 /* shift right accumulator */
6946 /* or with result */
6947 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6948 /* back to result */
6949 pic16_aopPut(AOP(result),"a",offr);
6952 /*-----------------------------------------------------------------*/
6953 /* genlshOne - left shift a one byte quantity by known count */
6954 /*-----------------------------------------------------------------*/
6955 static void genlshOne (operand *result, operand *left, int shCount)
6957 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6958 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6961 /*-----------------------------------------------------------------*/
6962 /* genlshTwo - left shift two bytes by known amount != 0 */
6963 /*-----------------------------------------------------------------*/
6964 static void genlshTwo (operand *result,operand *left, int shCount)
6968 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6969 size = pic16_getDataSize(result);
6971 /* if shCount >= 8 */
6977 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6979 movLeft2Result(left, LSB, result, MSB16);
6981 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6984 /* 1 <= shCount <= 7 */
6987 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6989 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6993 /*-----------------------------------------------------------------*/
6994 /* shiftLLong - shift left one long from left to result */
6995 /* offl = LSB or MSB16 */
6996 /*-----------------------------------------------------------------*/
6997 static void shiftLLong (operand *left, operand *result, int offr )
7000 int size = AOP_SIZE(result);
7002 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7003 if(size >= LSB+offr){
7004 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7006 pic16_emitcode("add","a,acc");
7007 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7008 size >= MSB16+offr && offr != LSB )
7009 pic16_emitcode("xch","a,%s",
7010 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7012 pic16_aopPut(AOP(result),"a",LSB+offr);
7015 if(size >= MSB16+offr){
7016 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7017 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7020 pic16_emitcode("rlc","a");
7021 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7022 size >= MSB24+offr && offr != LSB)
7023 pic16_emitcode("xch","a,%s",
7024 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7026 pic16_aopPut(AOP(result),"a",MSB16+offr);
7029 if(size >= MSB24+offr){
7030 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7031 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7034 pic16_emitcode("rlc","a");
7035 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7036 size >= MSB32+offr && offr != LSB )
7037 pic16_emitcode("xch","a,%s",
7038 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7040 pic16_aopPut(AOP(result),"a",MSB24+offr);
7043 if(size > MSB32+offr){
7044 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7045 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7048 pic16_emitcode("rlc","a");
7049 pic16_aopPut(AOP(result),"a",MSB32+offr);
7052 pic16_aopPut(AOP(result),zero,LSB);
7055 /*-----------------------------------------------------------------*/
7056 /* genlshFour - shift four byte by a known amount != 0 */
7057 /*-----------------------------------------------------------------*/
7058 static void genlshFour (operand *result, operand *left, int shCount)
7062 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7063 size = AOP_SIZE(result);
7065 /* if shifting more that 3 bytes */
7066 if (shCount >= 24 ) {
7069 /* lowest order of left goes to the highest
7070 order of the destination */
7071 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7073 movLeft2Result(left, LSB, result, MSB32);
7074 pic16_aopPut(AOP(result),zero,LSB);
7075 pic16_aopPut(AOP(result),zero,MSB16);
7076 pic16_aopPut(AOP(result),zero,MSB32);
7080 /* more than two bytes */
7081 else if ( shCount >= 16 ) {
7082 /* lower order two bytes goes to higher order two bytes */
7084 /* if some more remaining */
7086 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7088 movLeft2Result(left, MSB16, result, MSB32);
7089 movLeft2Result(left, LSB, result, MSB24);
7091 pic16_aopPut(AOP(result),zero,MSB16);
7092 pic16_aopPut(AOP(result),zero,LSB);
7096 /* if more than 1 byte */
7097 else if ( shCount >= 8 ) {
7098 /* lower order three bytes goes to higher order three bytes */
7102 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7104 movLeft2Result(left, LSB, result, MSB16);
7106 else{ /* size = 4 */
7108 movLeft2Result(left, MSB24, result, MSB32);
7109 movLeft2Result(left, MSB16, result, MSB24);
7110 movLeft2Result(left, LSB, result, MSB16);
7111 pic16_aopPut(AOP(result),zero,LSB);
7113 else if(shCount == 1)
7114 shiftLLong(left, result, MSB16);
7116 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7117 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7118 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7119 pic16_aopPut(AOP(result),zero,LSB);
7124 /* 1 <= shCount <= 7 */
7125 else if(shCount <= 2){
7126 shiftLLong(left, result, LSB);
7128 shiftLLong(result, result, LSB);
7130 /* 3 <= shCount <= 7, optimize */
7132 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7133 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7134 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7138 /*-----------------------------------------------------------------*/
7139 /* genLeftShiftLiteral - left shifting by known count */
7140 /*-----------------------------------------------------------------*/
7141 static void genLeftShiftLiteral (operand *left,
7146 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7149 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7150 pic16_freeAsmop(right,NULL,ic,TRUE);
7152 pic16_aopOp(left,ic,FALSE);
7153 pic16_aopOp(result,ic,FALSE);
7155 size = getSize(operandType(result));
7158 pic16_emitcode("; shift left ","result %d, left %d",size,
7162 /* I suppose that the left size >= result size */
7165 movLeft2Result(left, size, result, size);
7169 else if(shCount >= (size * 8))
7171 pic16_aopPut(AOP(result),zero,size);
7175 genlshOne (result,left,shCount);
7180 genlshTwo (result,left,shCount);
7184 genlshFour (result,left,shCount);
7188 pic16_freeAsmop(left,NULL,ic,TRUE);
7189 pic16_freeAsmop(result,NULL,ic,TRUE);
7192 /*-----------------------------------------------------------------*
7193 * genMultiAsm - repeat assembly instruction for size of register.
7194 * if endian == 1, then the high byte (i.e base address + size of
7195 * register) is used first else the low byte is used first;
7196 *-----------------------------------------------------------------*/
7197 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7202 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7215 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7220 /*-----------------------------------------------------------------*/
7221 /* genLeftShift - generates code for left shifting */
7222 /*-----------------------------------------------------------------*/
7223 static void genLeftShift (iCode *ic)
7225 operand *left,*right, *result;
7228 symbol *tlbl , *tlbl1;
7231 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7233 right = IC_RIGHT(ic);
7235 result = IC_RESULT(ic);
7237 pic16_aopOp(right,ic,FALSE);
7239 /* if the shift count is known then do it
7240 as efficiently as possible */
7241 if (AOP_TYPE(right) == AOP_LIT) {
7242 genLeftShiftLiteral (left,right,result,ic);
7246 /* shift count is unknown then we have to form
7247 a loop get the loop count in B : Note: we take
7248 only the lower order byte since shifting
7249 more that 32 bits make no sense anyway, ( the
7250 largest size of an object can be only 32 bits ) */
7253 pic16_aopOp(left,ic,FALSE);
7254 pic16_aopOp(result,ic,FALSE);
7256 /* now move the left to the result if they are not the
7258 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7259 AOP_SIZE(result) > 1) {
7261 size = AOP_SIZE(result);
7264 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7265 if (*l == '@' && (IS_AOP_PREG(result))) {
7267 pic16_emitcode("mov","a,%s",l);
7268 pic16_aopPut(AOP(result),"a",offset);
7270 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7271 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7272 //pic16_aopPut(AOP(result),l,offset);
7278 size = AOP_SIZE(result);
7280 /* if it is only one byte then */
7282 if(optimized_for_speed) {
7283 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7284 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7285 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7286 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7287 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7288 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7289 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7290 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7291 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7292 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7293 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7294 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7297 tlbl = newiTempLabel(NULL);
7298 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7299 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7300 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7303 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7304 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7305 pic16_emitpLabel(tlbl->key);
7306 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7307 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7309 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7314 if (pic16_sameRegs(AOP(left),AOP(result))) {
7316 tlbl = newiTempLabel(NULL);
7317 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7318 genMultiAsm(POC_RRCF, result, size,1);
7319 pic16_emitpLabel(tlbl->key);
7320 genMultiAsm(POC_RLCF, result, size,0);
7321 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7323 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7327 //tlbl = newiTempLabel(NULL);
7329 //tlbl1 = newiTempLabel(NULL);
7331 //reAdjustPreg(AOP(result));
7333 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7334 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7335 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7337 //pic16_emitcode("add","a,acc");
7338 //pic16_aopPut(AOP(result),"a",offset++);
7340 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7342 // pic16_emitcode("rlc","a");
7343 // pic16_aopPut(AOP(result),"a",offset++);
7345 //reAdjustPreg(AOP(result));
7347 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7348 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7351 tlbl = newiTempLabel(NULL);
7352 tlbl1= newiTempLabel(NULL);
7354 size = AOP_SIZE(result);
7357 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7359 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7361 /* offset should be 0, 1 or 3 */
7362 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7364 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7366 pic16_emitpcode(POC_MOVWF, pctemp);
7369 pic16_emitpLabel(tlbl->key);
7372 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7374 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7376 pic16_emitpcode(POC_DECFSZ, pctemp);
7377 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7378 pic16_emitpLabel(tlbl1->key);
7380 pic16_popReleaseTempReg(pctemp);
7384 pic16_freeAsmop (right,NULL,ic,TRUE);
7385 pic16_freeAsmop(left,NULL,ic,TRUE);
7386 pic16_freeAsmop(result,NULL,ic,TRUE);
7389 /*-----------------------------------------------------------------*/
7390 /* genrshOne - right shift a one byte quantity by known count */
7391 /*-----------------------------------------------------------------*/
7392 static void genrshOne (operand *result, operand *left,
7393 int shCount, int sign)
7395 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7396 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7399 /*-----------------------------------------------------------------*/
7400 /* genrshTwo - right shift two bytes by known amount != 0 */
7401 /*-----------------------------------------------------------------*/
7402 static void genrshTwo (operand *result,operand *left,
7403 int shCount, int sign)
7405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7406 /* if shCount >= 8 */
7410 shiftR1Left2Result(left, MSB16, result, LSB,
7413 movLeft2Result(left, MSB16, result, LSB);
7415 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7418 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7419 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7423 /* 1 <= shCount <= 7 */
7425 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7428 /*-----------------------------------------------------------------*/
7429 /* shiftRLong - shift right one long from left to result */
7430 /* offl = LSB or MSB16 */
7431 /*-----------------------------------------------------------------*/
7432 static void shiftRLong (operand *left, int offl,
7433 operand *result, int sign)
7435 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7437 pic16_emitcode("clr","c");
7438 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7440 pic16_emitcode("mov","c,acc.7");
7441 pic16_emitcode("rrc","a");
7442 pic16_aopPut(AOP(result),"a",MSB32-offl);
7444 /* add sign of "a" */
7445 pic16_addSign(result, MSB32, sign);
7447 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7448 pic16_emitcode("rrc","a");
7449 pic16_aopPut(AOP(result),"a",MSB24-offl);
7451 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7452 pic16_emitcode("rrc","a");
7453 pic16_aopPut(AOP(result),"a",MSB16-offl);
7456 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7457 pic16_emitcode("rrc","a");
7458 pic16_aopPut(AOP(result),"a",LSB);
7462 /*-----------------------------------------------------------------*/
7463 /* genrshFour - shift four byte by a known amount != 0 */
7464 /*-----------------------------------------------------------------*/
7465 static void genrshFour (operand *result, operand *left,
7466 int shCount, int sign)
7468 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7469 /* if shifting more that 3 bytes */
7470 if(shCount >= 24 ) {
7473 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7475 movLeft2Result(left, MSB32, result, LSB);
7477 pic16_addSign(result, MSB16, sign);
7479 else if(shCount >= 16){
7482 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7484 movLeft2Result(left, MSB24, result, LSB);
7485 movLeft2Result(left, MSB32, result, MSB16);
7487 pic16_addSign(result, MSB24, sign);
7489 else if(shCount >= 8){
7492 shiftRLong(left, MSB16, result, sign);
7493 else if(shCount == 0){
7494 movLeft2Result(left, MSB16, result, LSB);
7495 movLeft2Result(left, MSB24, result, MSB16);
7496 movLeft2Result(left, MSB32, result, MSB24);
7497 pic16_addSign(result, MSB32, sign);
7500 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7501 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7502 /* the last shift is signed */
7503 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7504 pic16_addSign(result, MSB32, sign);
7507 else{ /* 1 <= shCount <= 7 */
7509 shiftRLong(left, LSB, result, sign);
7511 shiftRLong(result, LSB, result, sign);
7514 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7515 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7516 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7521 /*-----------------------------------------------------------------*/
7522 /* genRightShiftLiteral - right shifting by known count */
7523 /*-----------------------------------------------------------------*/
7524 static void genRightShiftLiteral (operand *left,
7530 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7533 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7534 pic16_freeAsmop(right,NULL,ic,TRUE);
7536 pic16_aopOp(left,ic,FALSE);
7537 pic16_aopOp(result,ic,FALSE);
7540 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7544 lsize = pic16_getDataSize(left);
7545 res_size = pic16_getDataSize(result);
7546 /* test the LEFT size !!! */
7548 /* I suppose that the left size >= result size */
7551 movLeft2Result(left, lsize, result, res_size);
7554 else if(shCount >= (lsize * 8)){
7557 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7559 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7560 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7565 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7566 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7567 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7569 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7574 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7581 genrshOne (result,left,shCount,sign);
7585 genrshTwo (result,left,shCount,sign);
7589 genrshFour (result,left,shCount,sign);
7597 pic16_freeAsmop(left,NULL,ic,TRUE);
7598 pic16_freeAsmop(result,NULL,ic,TRUE);
7601 /*-----------------------------------------------------------------*/
7602 /* genSignedRightShift - right shift of signed number */
7603 /*-----------------------------------------------------------------*/
7604 static void genSignedRightShift (iCode *ic)
7606 operand *right, *left, *result;
7609 symbol *tlbl, *tlbl1 ;
7612 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7614 /* we do it the hard way put the shift count in b
7615 and loop thru preserving the sign */
7616 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7618 right = IC_RIGHT(ic);
7620 result = IC_RESULT(ic);
7622 pic16_aopOp(right,ic,FALSE);
7623 pic16_aopOp(left,ic,FALSE);
7624 pic16_aopOp(result,ic,FALSE);
7627 if ( AOP_TYPE(right) == AOP_LIT) {
7628 genRightShiftLiteral (left,right,result,ic,1);
7631 /* shift count is unknown then we have to form
7632 a loop get the loop count in B : Note: we take
7633 only the lower order byte since shifting
7634 more that 32 bits make no sense anyway, ( the
7635 largest size of an object can be only 32 bits ) */
7637 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7638 //pic16_emitcode("inc","b");
7639 //pic16_freeAsmop (right,NULL,ic,TRUE);
7640 //pic16_aopOp(left,ic,FALSE);
7641 //pic16_aopOp(result,ic,FALSE);
7643 /* now move the left to the result if they are not the
7645 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7646 AOP_SIZE(result) > 1) {
7648 size = AOP_SIZE(result);
7652 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7653 if (*l == '@' && IS_AOP_PREG(result)) {
7655 pic16_emitcode("mov","a,%s",l);
7656 pic16_aopPut(AOP(result),"a",offset);
7658 pic16_aopPut(AOP(result),l,offset);
7660 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7661 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7667 /* mov the highest order bit to OVR */
7668 tlbl = newiTempLabel(NULL);
7669 tlbl1= newiTempLabel(NULL);
7671 size = AOP_SIZE(result);
7674 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7676 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7678 /* offset should be 0, 1 or 3 */
7679 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7681 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7683 pic16_emitpcode(POC_MOVWF, pctemp);
7686 pic16_emitpLabel(tlbl->key);
7688 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7689 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7692 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7695 pic16_emitpcode(POC_DECFSZ, pctemp);
7696 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7697 pic16_emitpLabel(tlbl1->key);
7699 pic16_popReleaseTempReg(pctemp);
7701 size = AOP_SIZE(result);
7703 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7704 pic16_emitcode("rlc","a");
7705 pic16_emitcode("mov","ov,c");
7706 /* if it is only one byte then */
7708 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7710 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7711 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7712 pic16_emitcode("mov","c,ov");
7713 pic16_emitcode("rrc","a");
7714 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7715 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7716 pic16_aopPut(AOP(result),"a",0);
7720 reAdjustPreg(AOP(result));
7721 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7722 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7723 pic16_emitcode("mov","c,ov");
7725 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7727 pic16_emitcode("rrc","a");
7728 pic16_aopPut(AOP(result),"a",offset--);
7730 reAdjustPreg(AOP(result));
7731 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7732 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7737 pic16_freeAsmop(left,NULL,ic,TRUE);
7738 pic16_freeAsmop(result,NULL,ic,TRUE);
7739 pic16_freeAsmop(right,NULL,ic,TRUE);
7742 /*-----------------------------------------------------------------*/
7743 /* genRightShift - generate code for right shifting */
7744 /*-----------------------------------------------------------------*/
7745 static void genRightShift (iCode *ic)
7747 operand *right, *left, *result;
7751 symbol *tlbl, *tlbl1 ;
7753 /* if signed then we do it the hard way preserve the
7754 sign bit moving it inwards */
7755 retype = getSpec(operandType(IC_RESULT(ic)));
7756 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7758 if (!SPEC_USIGN(retype)) {
7759 genSignedRightShift (ic);
7763 /* signed & unsigned types are treated the same : i.e. the
7764 signed is NOT propagated inwards : quoting from the
7765 ANSI - standard : "for E1 >> E2, is equivalent to division
7766 by 2**E2 if unsigned or if it has a non-negative value,
7767 otherwise the result is implementation defined ", MY definition
7768 is that the sign does not get propagated */
7770 right = IC_RIGHT(ic);
7772 result = IC_RESULT(ic);
7774 pic16_aopOp(right,ic,FALSE);
7776 /* if the shift count is known then do it
7777 as efficiently as possible */
7778 if (AOP_TYPE(right) == AOP_LIT) {
7779 genRightShiftLiteral (left,right,result,ic, 0);
7783 /* shift count is unknown then we have to form
7784 a loop get the loop count in B : Note: we take
7785 only the lower order byte since shifting
7786 more that 32 bits make no sense anyway, ( the
7787 largest size of an object can be only 32 bits ) */
7789 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7790 pic16_emitcode("inc","b");
7791 pic16_aopOp(left,ic,FALSE);
7792 pic16_aopOp(result,ic,FALSE);
7794 /* now move the left to the result if they are not the
7796 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7797 AOP_SIZE(result) > 1) {
7799 size = AOP_SIZE(result);
7802 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7803 if (*l == '@' && IS_AOP_PREG(result)) {
7805 pic16_emitcode("mov","a,%s",l);
7806 pic16_aopPut(AOP(result),"a",offset);
7808 pic16_aopPut(AOP(result),l,offset);
7813 tlbl = newiTempLabel(NULL);
7814 tlbl1= newiTempLabel(NULL);
7815 size = AOP_SIZE(result);
7818 /* if it is only one byte then */
7821 tlbl = newiTempLabel(NULL);
7822 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7823 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7824 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7827 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7828 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7829 pic16_emitpLabel(tlbl->key);
7830 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7831 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7833 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7838 reAdjustPreg(AOP(result));
7839 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7840 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7843 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7845 pic16_emitcode("rrc","a");
7846 pic16_aopPut(AOP(result),"a",offset--);
7848 reAdjustPreg(AOP(result));
7850 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7851 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7854 pic16_freeAsmop(left,NULL,ic,TRUE);
7855 pic16_freeAsmop (right,NULL,ic,TRUE);
7856 pic16_freeAsmop(result,NULL,ic,TRUE);
7859 /*-----------------------------------------------------------------*/
7860 /* genUnpackBits - generates code for unpacking bits */
7861 /*-----------------------------------------------------------------*/
7862 static void genUnpackBits (operand *result, char *rname, int ptype)
7869 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7870 etype = getSpec(operandType(result));
7872 /* read the first byte */
7877 pic16_emitcode("mov","a,@%s",rname);
7881 pic16_emitcode("movx","a,@%s",rname);
7885 pic16_emitcode("movx","a,@dptr");
7889 pic16_emitcode("clr","a");
7890 pic16_emitcode("movc","a","@a+dptr");
7894 pic16_emitcode("lcall","__gptrget");
7898 /* if we have bitdisplacement then it fits */
7899 /* into this byte completely or if length is */
7900 /* less than a byte */
7901 if ((shCnt = SPEC_BSTR(etype)) ||
7902 (SPEC_BLEN(etype) <= 8)) {
7904 /* shift right acc */
7907 pic16_emitcode("anl","a,#0x%02x",
7908 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7909 pic16_aopPut(AOP(result),"a",offset);
7913 /* bit field did not fit in a byte */
7914 rlen = SPEC_BLEN(etype) - 8;
7915 pic16_aopPut(AOP(result),"a",offset++);
7922 pic16_emitcode("inc","%s",rname);
7923 pic16_emitcode("mov","a,@%s",rname);
7927 pic16_emitcode("inc","%s",rname);
7928 pic16_emitcode("movx","a,@%s",rname);
7932 pic16_emitcode("inc","dptr");
7933 pic16_emitcode("movx","a,@dptr");
7937 pic16_emitcode("clr","a");
7938 pic16_emitcode("inc","dptr");
7939 pic16_emitcode("movc","a","@a+dptr");
7943 pic16_emitcode("inc","dptr");
7944 pic16_emitcode("lcall","__gptrget");
7949 /* if we are done */
7953 pic16_aopPut(AOP(result),"a",offset++);
7958 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7959 pic16_aopPut(AOP(result),"a",offset);
7966 /*-----------------------------------------------------------------*/
7967 /* genDataPointerGet - generates code when ptr offset is known */
7968 /*-----------------------------------------------------------------*/
7969 static void genDataPointerGet (operand *left,
7973 int size , offset = 0;
7976 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7979 /* optimization - most of the time, left and result are the same
7980 * address, but different types. for the pic code, we could omit
7984 pic16_aopOp(result,ic,TRUE);
7986 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7988 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7990 size = AOP_SIZE(result);
7993 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7997 pic16_freeAsmop(left,NULL,ic,TRUE);
7998 pic16_freeAsmop(result,NULL,ic,TRUE);
8001 /*-----------------------------------------------------------------*/
8002 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8003 /*-----------------------------------------------------------------*/
8004 static void genNearPointerGet (operand *left,
8009 //regs *preg = NULL ;
8011 sym_link *rtype, *retype;
8012 sym_link *ltype = operandType(left);
8015 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8017 rtype = operandType(result);
8018 retype= getSpec(rtype);
8020 pic16_aopOp(left,ic,FALSE);
8022 /* if left is rematerialisable and
8023 result is not bit variable type and
8024 the left is pointer to data space i.e
8025 lower 128 bytes of space */
8026 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8027 !IS_BITVAR(retype) &&
8028 DCL_TYPE(ltype) == POINTER) {
8029 //genDataPointerGet (left,result,ic);
8033 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8035 /* if the value is already in a pointer register
8036 then don't need anything more */
8037 if (!AOP_INPREG(AOP(left))) {
8038 /* otherwise get a free pointer register */
8039 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8042 preg = getFreePtr(ic,&aop,FALSE);
8043 pic16_emitcode("mov","%s,%s",
8045 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8046 rname = preg->name ;
8050 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8052 pic16_aopOp (result,ic,FALSE);
8054 /* if bitfield then unpack the bits */
8055 if (IS_BITVAR(retype))
8056 genUnpackBits (result,rname,POINTER);
8058 /* we have can just get the values */
8059 int size = AOP_SIZE(result);
8062 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8064 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8065 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8067 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8068 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8070 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8074 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8076 pic16_emitcode("mov","a,@%s",rname);
8077 pic16_aopPut(AOP(result),"a",offset);
8079 sprintf(buffer,"@%s",rname);
8080 pic16_aopPut(AOP(result),buffer,offset);
8084 pic16_emitcode("inc","%s",rname);
8089 /* now some housekeeping stuff */
8091 /* we had to allocate for this iCode */
8092 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8093 pic16_freeAsmop(NULL,aop,ic,TRUE);
8095 /* we did not allocate which means left
8096 already in a pointer register, then
8097 if size > 0 && this could be used again
8098 we have to point it back to where it
8100 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8101 if (AOP_SIZE(result) > 1 &&
8102 !OP_SYMBOL(left)->remat &&
8103 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8105 int size = AOP_SIZE(result) - 1;
8107 pic16_emitcode("dec","%s",rname);
8112 pic16_freeAsmop(left,NULL,ic,TRUE);
8113 pic16_freeAsmop(result,NULL,ic,TRUE);
8117 /*-----------------------------------------------------------------*/
8118 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8119 /*-----------------------------------------------------------------*/
8120 static void genPagedPointerGet (operand *left,
8127 sym_link *rtype, *retype;
8129 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8131 rtype = operandType(result);
8132 retype= getSpec(rtype);
8134 pic16_aopOp(left,ic,FALSE);
8136 /* if the value is already in a pointer register
8137 then don't need anything more */
8138 if (!AOP_INPREG(AOP(left))) {
8139 /* otherwise get a free pointer register */
8141 preg = getFreePtr(ic,&aop,FALSE);
8142 pic16_emitcode("mov","%s,%s",
8144 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8145 rname = preg->name ;
8147 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8149 pic16_freeAsmop(left,NULL,ic,TRUE);
8150 pic16_aopOp (result,ic,FALSE);
8152 /* if bitfield then unpack the bits */
8153 if (IS_BITVAR(retype))
8154 genUnpackBits (result,rname,PPOINTER);
8156 /* we have can just get the values */
8157 int size = AOP_SIZE(result);
8162 pic16_emitcode("movx","a,@%s",rname);
8163 pic16_aopPut(AOP(result),"a",offset);
8168 pic16_emitcode("inc","%s",rname);
8172 /* now some housekeeping stuff */
8174 /* we had to allocate for this iCode */
8175 pic16_freeAsmop(NULL,aop,ic,TRUE);
8177 /* we did not allocate which means left
8178 already in a pointer register, then
8179 if size > 0 && this could be used again
8180 we have to point it back to where it
8182 if (AOP_SIZE(result) > 1 &&
8183 !OP_SYMBOL(left)->remat &&
8184 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8186 int size = AOP_SIZE(result) - 1;
8188 pic16_emitcode("dec","%s",rname);
8193 pic16_freeAsmop(result,NULL,ic,TRUE);
8198 /*-----------------------------------------------------------------*/
8199 /* genFarPointerGet - gget value from far space */
8200 /*-----------------------------------------------------------------*/
8201 static void genFarPointerGet (operand *left,
8202 operand *result, iCode *ic)
8205 sym_link *retype = getSpec(operandType(result));
8207 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8209 pic16_aopOp(left,ic,FALSE);
8211 /* if the operand is already in dptr
8212 then we do nothing else we move the value to dptr */
8213 if (AOP_TYPE(left) != AOP_STR) {
8214 /* if this is remateriazable */
8215 if (AOP_TYPE(left) == AOP_IMMD)
8216 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8217 else { /* we need to get it byte by byte */
8218 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8219 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8220 if (options.model == MODEL_FLAT24)
8222 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8226 /* so dptr know contains the address */
8227 pic16_freeAsmop(left,NULL,ic,TRUE);
8228 pic16_aopOp(result,ic,FALSE);
8230 /* if bit then unpack */
8231 if (IS_BITVAR(retype))
8232 genUnpackBits(result,"dptr",FPOINTER);
8234 size = AOP_SIZE(result);
8238 pic16_emitcode("movx","a,@dptr");
8239 pic16_aopPut(AOP(result),"a",offset++);
8241 pic16_emitcode("inc","dptr");
8245 pic16_freeAsmop(result,NULL,ic,TRUE);
8248 /*-----------------------------------------------------------------*/
8249 /* genCodePointerGet - get value from code space */
8250 /*-----------------------------------------------------------------*/
8251 static void genCodePointerGet (operand *left,
8252 operand *result, iCode *ic)
8255 sym_link *retype = getSpec(operandType(result));
8257 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8259 pic16_aopOp(left,ic,FALSE);
8261 /* if the operand is already in dptr
8262 then we do nothing else we move the value to dptr */
8263 if (AOP_TYPE(left) != AOP_STR) {
8264 /* if this is remateriazable */
8265 if (AOP_TYPE(left) == AOP_IMMD)
8266 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8267 else { /* we need to get it byte by byte */
8268 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8269 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8270 if (options.model == MODEL_FLAT24)
8272 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8276 /* so dptr know contains the address */
8277 pic16_freeAsmop(left,NULL,ic,TRUE);
8278 pic16_aopOp(result,ic,FALSE);
8280 /* if bit then unpack */
8281 if (IS_BITVAR(retype))
8282 genUnpackBits(result,"dptr",CPOINTER);
8284 size = AOP_SIZE(result);
8288 pic16_emitcode("clr","a");
8289 pic16_emitcode("movc","a,@a+dptr");
8290 pic16_aopPut(AOP(result),"a",offset++);
8292 pic16_emitcode("inc","dptr");
8296 pic16_freeAsmop(result,NULL,ic,TRUE);
8299 /*-----------------------------------------------------------------*/
8300 /* genGenPointerGet - gget value from generic pointer space */
8301 /*-----------------------------------------------------------------*/
8302 static void genGenPointerGet (operand *left,
8303 operand *result, iCode *ic)
8306 sym_link *retype = getSpec(operandType(result));
8308 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8309 pic16_aopOp(left,ic,FALSE);
8310 pic16_aopOp(result,ic,FALSE);
8313 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8315 /* if the operand is already in dptr
8316 then we do nothing else we move the value to dptr */
8317 // if (AOP_TYPE(left) != AOP_STR) {
8318 /* if this is remateriazable */
8319 if (AOP_TYPE(left) == AOP_IMMD) {
8320 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8321 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8323 else { /* we need to get it byte by byte */
8325 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8326 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8328 size = AOP_SIZE(result);
8332 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8333 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8335 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8340 /* so dptr know contains the address */
8342 /* if bit then unpack */
8343 //if (IS_BITVAR(retype))
8344 // genUnpackBits(result,"dptr",GPOINTER);
8347 pic16_freeAsmop(left,NULL,ic,TRUE);
8348 pic16_freeAsmop(result,NULL,ic,TRUE);
8352 /*-----------------------------------------------------------------*/
8353 /* genConstPointerGet - get value from const generic pointer space */
8354 /*-----------------------------------------------------------------*/
8355 static void genConstPointerGet (operand *left,
8356 operand *result, iCode *ic)
8358 //sym_link *retype = getSpec(operandType(result));
8359 symbol *albl = newiTempLabel(NULL);
8360 symbol *blbl = newiTempLabel(NULL);
8363 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8364 pic16_aopOp(left,ic,FALSE);
8365 pic16_aopOp(result,ic,FALSE);
8368 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8370 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8372 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8373 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8374 pic16_emitpLabel(albl->key);
8376 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8378 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8379 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8380 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8381 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8383 pic16_emitpLabel(blbl->key);
8385 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8388 pic16_freeAsmop(left,NULL,ic,TRUE);
8389 pic16_freeAsmop(result,NULL,ic,TRUE);
8392 /*-----------------------------------------------------------------*/
8393 /* genPointerGet - generate code for pointer get */
8394 /*-----------------------------------------------------------------*/
8395 static void genPointerGet (iCode *ic)
8397 operand *left, *result ;
8398 sym_link *type, *etype;
8401 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8404 result = IC_RESULT(ic) ;
8406 /* depending on the type of pointer we need to
8407 move it to the correct pointer register */
8408 type = operandType(left);
8409 etype = getSpec(type);
8411 if (IS_PTR_CONST(type))
8412 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8414 /* if left is of type of pointer then it is simple */
8415 if (IS_PTR(type) && !IS_FUNC(type->next))
8416 p_type = DCL_TYPE(type);
8418 /* we have to go by the storage class */
8419 p_type = PTR_TYPE(SPEC_OCLS(etype));
8421 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8423 if (SPEC_OCLS(etype)->codesp ) {
8424 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8425 //p_type = CPOINTER ;
8428 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8429 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8430 /*p_type = FPOINTER ;*/
8432 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8433 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8434 /* p_type = PPOINTER; */
8436 if (SPEC_OCLS(etype) == idata )
8437 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8438 /* p_type = IPOINTER; */
8440 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8441 /* p_type = POINTER ; */
8444 /* now that we have the pointer type we assign
8445 the pointer values */
8450 genNearPointerGet (left,result,ic);
8454 genPagedPointerGet(left,result,ic);
8458 genFarPointerGet (left,result,ic);
8462 genConstPointerGet (left,result,ic);
8463 //pic16_emitcodePointerGet (left,result,ic);
8467 if (IS_PTR_CONST(type))
8468 genConstPointerGet (left,result,ic);
8470 genGenPointerGet (left,result,ic);
8476 /*-----------------------------------------------------------------*/
8477 /* genPackBits - generates code for packed bit storage */
8478 /*-----------------------------------------------------------------*/
8479 static void genPackBits (sym_link *etype ,
8481 char *rname, int p_type)
8489 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8490 blen = SPEC_BLEN(etype);
8491 bstr = SPEC_BSTR(etype);
8493 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8496 /* if the bit lenth is less than or */
8497 /* it exactly fits a byte then */
8498 if (SPEC_BLEN(etype) <= 8 ) {
8499 shCount = SPEC_BSTR(etype) ;
8501 /* shift left acc */
8504 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8509 pic16_emitcode ("mov","b,a");
8510 pic16_emitcode("mov","a,@%s",rname);
8514 pic16_emitcode ("mov","b,a");
8515 pic16_emitcode("movx","a,@dptr");
8519 pic16_emitcode ("push","b");
8520 pic16_emitcode ("push","acc");
8521 pic16_emitcode ("lcall","__gptrget");
8522 pic16_emitcode ("pop","b");
8526 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8527 ((unsigned char)(0xFF << (blen+bstr)) |
8528 (unsigned char)(0xFF >> (8-bstr)) ) );
8529 pic16_emitcode ("orl","a,b");
8530 if (p_type == GPOINTER)
8531 pic16_emitcode("pop","b");
8537 pic16_emitcode("mov","@%s,a",rname);
8541 pic16_emitcode("movx","@dptr,a");
8545 DEBUGpic16_emitcode(";lcall","__gptrput");
8550 if ( SPEC_BLEN(etype) <= 8 )
8553 pic16_emitcode("inc","%s",rname);
8554 rLen = SPEC_BLEN(etype) ;
8556 /* now generate for lengths greater than one byte */
8559 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8569 pic16_emitcode("mov","@%s,a",rname);
8571 pic16_emitcode("mov","@%s,%s",rname,l);
8576 pic16_emitcode("movx","@dptr,a");
8581 DEBUGpic16_emitcode(";lcall","__gptrput");
8584 pic16_emitcode ("inc","%s",rname);
8589 /* last last was not complete */
8591 /* save the byte & read byte */
8594 pic16_emitcode ("mov","b,a");
8595 pic16_emitcode("mov","a,@%s",rname);
8599 pic16_emitcode ("mov","b,a");
8600 pic16_emitcode("movx","a,@dptr");
8604 pic16_emitcode ("push","b");
8605 pic16_emitcode ("push","acc");
8606 pic16_emitcode ("lcall","__gptrget");
8607 pic16_emitcode ("pop","b");
8611 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8612 pic16_emitcode ("orl","a,b");
8615 if (p_type == GPOINTER)
8616 pic16_emitcode("pop","b");
8621 pic16_emitcode("mov","@%s,a",rname);
8625 pic16_emitcode("movx","@dptr,a");
8629 DEBUGpic16_emitcode(";lcall","__gptrput");
8633 /*-----------------------------------------------------------------*/
8634 /* genDataPointerSet - remat pointer to data space */
8635 /*-----------------------------------------------------------------*/
8636 static void genDataPointerSet(operand *right,
8640 int size, offset = 0 ;
8641 char *l, buffer[256];
8643 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8644 pic16_aopOp(right,ic,FALSE);
8646 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8647 size = AOP_SIZE(right);
8649 if ( AOP_TYPE(result) == AOP_PCODE) {
8650 fprintf(stderr,"genDataPointerSet %s, %d\n",
8651 AOP(result)->aopu.pcop->name,
8652 PCOI(AOP(result)->aopu.pcop)->offset);
8656 // tsd, was l+1 - the underline `_' prefix was being stripped
8659 sprintf(buffer,"(%s + %d)",l,offset);
8660 fprintf(stderr,"oops %s\n",buffer);
8662 sprintf(buffer,"%s",l);
8664 if (AOP_TYPE(right) == AOP_LIT) {
8665 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8666 lit = lit >> (8*offset);
8668 pic16_emitcode("movlw","%d",lit);
8669 pic16_emitcode("movwf","%s",buffer);
8671 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8672 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8673 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8676 pic16_emitcode("clrf","%s",buffer);
8677 //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8678 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8681 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8682 pic16_emitcode("movwf","%s",buffer);
8684 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8685 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8686 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8693 pic16_freeAsmop(right,NULL,ic,TRUE);
8694 pic16_freeAsmop(result,NULL,ic,TRUE);
8697 /*-----------------------------------------------------------------*/
8698 /* genNearPointerSet - pic16_emitcode for near pointer put */
8699 /*-----------------------------------------------------------------*/
8700 static void genNearPointerSet (operand *right,
8707 sym_link *ptype = operandType(result);
8710 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8711 retype= getSpec(operandType(right));
8713 pic16_aopOp(result,ic,FALSE);
8716 /* if the result is rematerializable &
8717 in data space & not a bit variable */
8718 //if (AOP_TYPE(result) == AOP_IMMD &&
8719 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8720 DCL_TYPE(ptype) == POINTER &&
8721 !IS_BITVAR(retype)) {
8722 genDataPointerSet (right,result,ic);
8723 pic16_freeAsmop(result,NULL,ic,TRUE);
8727 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8728 pic16_aopOp(right,ic,FALSE);
8729 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8731 /* if the value is already in a pointer register
8732 then don't need anything more */
8733 if (!AOP_INPREG(AOP(result))) {
8734 /* otherwise get a free pointer register */
8735 //aop = newAsmop(0);
8736 //preg = getFreePtr(ic,&aop,FALSE);
8737 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8738 //pic16_emitcode("mov","%s,%s",
8740 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8741 //rname = preg->name ;
8742 //pic16_emitcode("movwf","fsr0");
8743 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8744 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8745 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8746 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8750 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8753 /* if bitfield then unpack the bits */
8754 if (IS_BITVAR(retype)) {
8755 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8756 "The programmer is obviously confused");
8757 //genPackBits (retype,right,rname,POINTER);
8761 /* we have can just get the values */
8762 int size = AOP_SIZE(right);
8765 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8767 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8770 //pic16_emitcode("mov","@%s,a",rname);
8771 pic16_emitcode("movf","indf0,w ;1");
8774 if (AOP_TYPE(right) == AOP_LIT) {
8775 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8777 pic16_emitcode("movlw","%s",l);
8778 pic16_emitcode("movwf","indf0 ;2");
8780 pic16_emitcode("clrf","indf0");
8782 pic16_emitcode("movf","%s,w",l);
8783 pic16_emitcode("movwf","indf0 ;2");
8785 //pic16_emitcode("mov","@%s,%s",rname,l);
8788 pic16_emitcode("incf","fsr0,f ;3");
8789 //pic16_emitcode("inc","%s",rname);
8794 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8795 /* now some housekeeping stuff */
8797 /* we had to allocate for this iCode */
8798 pic16_freeAsmop(NULL,aop,ic,TRUE);
8800 /* we did not allocate which means left
8801 already in a pointer register, then
8802 if size > 0 && this could be used again
8803 we have to point it back to where it
8805 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8806 if (AOP_SIZE(right) > 1 &&
8807 !OP_SYMBOL(result)->remat &&
8808 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8810 int size = AOP_SIZE(right) - 1;
8812 pic16_emitcode("decf","fsr0,f");
8813 //pic16_emitcode("dec","%s",rname);
8817 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8820 pic16_freeAsmop(right,NULL,ic,TRUE);
8821 pic16_freeAsmop(result,NULL,ic,TRUE);
8824 /*-----------------------------------------------------------------*/
8825 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8826 /*-----------------------------------------------------------------*/
8827 static void genPagedPointerSet (operand *right,
8836 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8838 retype= getSpec(operandType(right));
8840 pic16_aopOp(result,ic,FALSE);
8842 /* if the value is already in a pointer register
8843 then don't need anything more */
8844 if (!AOP_INPREG(AOP(result))) {
8845 /* otherwise get a free pointer register */
8847 preg = getFreePtr(ic,&aop,FALSE);
8848 pic16_emitcode("mov","%s,%s",
8850 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8851 rname = preg->name ;
8853 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8855 pic16_freeAsmop(result,NULL,ic,TRUE);
8856 pic16_aopOp (right,ic,FALSE);
8858 /* if bitfield then unpack the bits */
8859 if (IS_BITVAR(retype))
8860 genPackBits (retype,right,rname,PPOINTER);
8862 /* we have can just get the values */
8863 int size = AOP_SIZE(right);
8867 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8870 pic16_emitcode("movx","@%s,a",rname);
8873 pic16_emitcode("inc","%s",rname);
8879 /* now some housekeeping stuff */
8881 /* we had to allocate for this iCode */
8882 pic16_freeAsmop(NULL,aop,ic,TRUE);
8884 /* we did not allocate which means left
8885 already in a pointer register, then
8886 if size > 0 && this could be used again
8887 we have to point it back to where it
8889 if (AOP_SIZE(right) > 1 &&
8890 !OP_SYMBOL(result)->remat &&
8891 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8893 int size = AOP_SIZE(right) - 1;
8895 pic16_emitcode("dec","%s",rname);
8900 pic16_freeAsmop(right,NULL,ic,TRUE);
8905 /*-----------------------------------------------------------------*/
8906 /* genFarPointerSet - set value from far space */
8907 /*-----------------------------------------------------------------*/
8908 static void genFarPointerSet (operand *right,
8909 operand *result, iCode *ic)
8912 sym_link *retype = getSpec(operandType(right));
8914 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8915 pic16_aopOp(result,ic,FALSE);
8917 /* if the operand is already in dptr
8918 then we do nothing else we move the value to dptr */
8919 if (AOP_TYPE(result) != AOP_STR) {
8920 /* if this is remateriazable */
8921 if (AOP_TYPE(result) == AOP_IMMD)
8922 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8923 else { /* we need to get it byte by byte */
8924 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8925 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8926 if (options.model == MODEL_FLAT24)
8928 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8932 /* so dptr know contains the address */
8933 pic16_freeAsmop(result,NULL,ic,TRUE);
8934 pic16_aopOp(right,ic,FALSE);
8936 /* if bit then unpack */
8937 if (IS_BITVAR(retype))
8938 genPackBits(retype,right,"dptr",FPOINTER);
8940 size = AOP_SIZE(right);
8944 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8946 pic16_emitcode("movx","@dptr,a");
8948 pic16_emitcode("inc","dptr");
8952 pic16_freeAsmop(right,NULL,ic,TRUE);
8955 /*-----------------------------------------------------------------*/
8956 /* genGenPointerSet - set value from generic pointer space */
8957 /*-----------------------------------------------------------------*/
8958 static void genGenPointerSet (operand *right,
8959 operand *result, iCode *ic)
8962 sym_link *retype = getSpec(operandType(right));
8964 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8966 pic16_aopOp(result,ic,FALSE);
8967 pic16_aopOp(right,ic,FALSE);
8968 size = AOP_SIZE(right);
8970 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8972 /* if the operand is already in dptr
8973 then we do nothing else we move the value to dptr */
8974 if (AOP_TYPE(result) != AOP_STR) {
8975 /* if this is remateriazable */
8976 if (AOP_TYPE(result) == AOP_IMMD) {
8977 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8978 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8980 else { /* we need to get it byte by byte */
8981 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8982 size = AOP_SIZE(right);
8985 /* hack hack! see if this the FSR. If so don't load W */
8986 if(AOP_TYPE(right) != AOP_ACC) {
8989 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
8990 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8992 if(AOP_SIZE(result) > 1) {
8993 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
8994 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
8995 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9000 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9002 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9003 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9007 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9008 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9011 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9018 if(aopIdx(AOP(result),0) != 4) {
9020 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9024 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9029 /* so dptr know contains the address */
9032 /* if bit then unpack */
9033 if (IS_BITVAR(retype))
9034 genPackBits(retype,right,"dptr",GPOINTER);
9036 size = AOP_SIZE(right);
9039 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9043 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9044 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9046 if (AOP_TYPE(right) == AOP_LIT)
9047 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9049 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9051 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9058 pic16_freeAsmop(right,NULL,ic,TRUE);
9059 pic16_freeAsmop(result,NULL,ic,TRUE);
9062 /*-----------------------------------------------------------------*/
9063 /* genPointerSet - stores the value into a pointer location */
9064 /*-----------------------------------------------------------------*/
9065 static void genPointerSet (iCode *ic)
9067 operand *right, *result ;
9068 sym_link *type, *etype;
9071 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9073 right = IC_RIGHT(ic);
9074 result = IC_RESULT(ic) ;
9076 /* depending on the type of pointer we need to
9077 move it to the correct pointer register */
9078 type = operandType(result);
9079 etype = getSpec(type);
9080 /* if left is of type of pointer then it is simple */
9081 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9082 p_type = DCL_TYPE(type);
9085 /* we have to go by the storage class */
9086 p_type = PTR_TYPE(SPEC_OCLS(etype));
9088 /* if (SPEC_OCLS(etype)->codesp ) { */
9089 /* p_type = CPOINTER ; */
9092 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9093 /* p_type = FPOINTER ; */
9095 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9096 /* p_type = PPOINTER ; */
9098 /* if (SPEC_OCLS(etype) == idata ) */
9099 /* p_type = IPOINTER ; */
9101 /* p_type = POINTER ; */
9104 /* now that we have the pointer type we assign
9105 the pointer values */
9110 genNearPointerSet (right,result,ic);
9114 genPagedPointerSet (right,result,ic);
9118 genFarPointerSet (right,result,ic);
9122 genGenPointerSet (right,result,ic);
9126 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9127 "genPointerSet: illegal pointer type");
9131 /*-----------------------------------------------------------------*/
9132 /* genIfx - generate code for Ifx statement */
9133 /*-----------------------------------------------------------------*/
9134 static void genIfx (iCode *ic, iCode *popIc)
9136 operand *cond = IC_COND(ic);
9139 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9141 pic16_aopOp(cond,ic,FALSE);
9143 /* get the value into acc */
9144 if (AOP_TYPE(cond) != AOP_CRY)
9145 pic16_toBoolean(cond);
9148 /* the result is now in the accumulator */
9149 pic16_freeAsmop(cond,NULL,ic,TRUE);
9151 /* if there was something to be popped then do it */
9155 /* if the condition is a bit variable */
9156 if (isbit && IS_ITEMP(cond) &&
9158 genIfxJump(ic,SPIL_LOC(cond)->rname);
9159 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9162 if (isbit && !IS_ITEMP(cond))
9163 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9171 /*-----------------------------------------------------------------*/
9172 /* genAddrOf - generates code for address of */
9173 /*-----------------------------------------------------------------*/
9174 static void genAddrOf (iCode *ic)
9176 operand *right, *result, *left;
9179 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9182 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9184 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9185 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9186 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9188 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9190 size = AOP_SIZE(IC_RESULT(ic));
9194 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9195 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9199 pic16_freeAsmop(left,NULL,ic,FALSE);
9200 pic16_freeAsmop(result,NULL,ic,TRUE);
9205 /*-----------------------------------------------------------------*/
9206 /* genFarFarAssign - assignment when both are in far space */
9207 /*-----------------------------------------------------------------*/
9208 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9210 int size = AOP_SIZE(right);
9213 /* first push the right side on to the stack */
9215 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9217 pic16_emitcode ("push","acc");
9220 pic16_freeAsmop(right,NULL,ic,FALSE);
9221 /* now assign DPTR to result */
9222 pic16_aopOp(result,ic,FALSE);
9223 size = AOP_SIZE(result);
9225 pic16_emitcode ("pop","acc");
9226 pic16_aopPut(AOP(result),"a",--offset);
9228 pic16_freeAsmop(result,NULL,ic,FALSE);
9233 /*-----------------------------------------------------------------*/
9234 /* genAssign - generate code for assignment */
9235 /*-----------------------------------------------------------------*/
9236 static void genAssign (iCode *ic)
9238 operand *result, *right;
9239 int size, offset,know_W;
9240 unsigned long lit = 0L;
9242 result = IC_RESULT(ic);
9243 right = IC_RIGHT(ic) ;
9245 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9247 /* if they are the same */
9248 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9251 pic16_aopOp(right,ic,FALSE);
9252 pic16_aopOp(result,ic,TRUE);
9254 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9256 /* if they are the same registers */
9257 if (pic16_sameRegs(AOP(right),AOP(result)))
9260 /* if the result is a bit */
9261 if (AOP_TYPE(result) == AOP_CRY) {
9263 /* if the right size is a literal then
9264 we know what the value is */
9265 if (AOP_TYPE(right) == AOP_LIT) {
9267 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9268 pic16_popGet(AOP(result),0));
9270 if (((int) operandLitValue(right)))
9271 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9272 AOP(result)->aopu.aop_dir,
9273 AOP(result)->aopu.aop_dir);
9275 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9276 AOP(result)->aopu.aop_dir,
9277 AOP(result)->aopu.aop_dir);
9281 /* the right is also a bit variable */
9282 if (AOP_TYPE(right) == AOP_CRY) {
9283 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9284 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9285 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9287 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9288 AOP(result)->aopu.aop_dir,
9289 AOP(result)->aopu.aop_dir);
9290 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9291 AOP(right)->aopu.aop_dir,
9292 AOP(right)->aopu.aop_dir);
9293 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9294 AOP(result)->aopu.aop_dir,
9295 AOP(result)->aopu.aop_dir);
9300 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9301 pic16_toBoolean(right);
9303 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9304 //pic16_aopPut(AOP(result),"a",0);
9308 /* bit variables done */
9310 size = AOP_SIZE(result);
9312 if(AOP_TYPE(right) == AOP_LIT)
9313 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9315 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9316 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9317 if(aopIdx(AOP(result),0) == 4) {
9318 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9319 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9320 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9323 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9328 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9329 if(AOP_TYPE(right) == AOP_LIT) {
9331 if(know_W != (lit&0xff))
9332 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9334 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9336 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9340 } else if (AOP_TYPE(right) == AOP_CRY) {
9341 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9343 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9344 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9347 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9348 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9349 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9357 pic16_freeAsmop (right,NULL,ic,FALSE);
9358 pic16_freeAsmop (result,NULL,ic,TRUE);
9361 /*-----------------------------------------------------------------*/
9362 /* genJumpTab - genrates code for jump table */
9363 /*-----------------------------------------------------------------*/
9364 static void genJumpTab (iCode *ic)
9369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9371 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9372 /* get the condition into accumulator */
9373 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9375 /* multiply by three */
9376 pic16_emitcode("add","a,acc");
9377 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9379 jtab = newiTempLabel(NULL);
9380 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9381 pic16_emitcode("jmp","@a+dptr");
9382 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9384 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9385 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9387 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9388 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9389 pic16_emitpLabel(jtab->key);
9391 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9393 /* now generate the jump labels */
9394 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9395 jtab = setNextItem(IC_JTLABELS(ic))) {
9396 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9397 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9403 /*-----------------------------------------------------------------*/
9404 /* genMixedOperation - gen code for operators between mixed types */
9405 /*-----------------------------------------------------------------*/
9407 TSD - Written for the PIC port - but this unfortunately is buggy.
9408 This routine is good in that it is able to efficiently promote
9409 types to different (larger) sizes. Unfortunately, the temporary
9410 variables that are optimized out by this routine are sometimes
9411 used in other places. So until I know how to really parse the
9412 iCode tree, I'm going to not be using this routine :(.
9414 static int genMixedOperation (iCode *ic)
9417 operand *result = IC_RESULT(ic);
9418 sym_link *ctype = operandType(IC_LEFT(ic));
9419 operand *right = IC_RIGHT(ic);
9425 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9427 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9433 nextright = IC_RIGHT(nextic);
9434 nextleft = IC_LEFT(nextic);
9435 nextresult = IC_RESULT(nextic);
9437 pic16_aopOp(right,ic,FALSE);
9438 pic16_aopOp(result,ic,FALSE);
9439 pic16_aopOp(nextright, nextic, FALSE);
9440 pic16_aopOp(nextleft, nextic, FALSE);
9441 pic16_aopOp(nextresult, nextic, FALSE);
9443 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9449 pic16_emitcode(";remove right +","");
9451 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9457 pic16_emitcode(";remove left +","");
9461 big = AOP_SIZE(nextleft);
9462 small = AOP_SIZE(nextright);
9464 switch(nextic->op) {
9467 pic16_emitcode(";optimize a +","");
9468 /* if unsigned or not an integral type */
9469 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9470 pic16_emitcode(";add a bit to something","");
9473 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9475 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9476 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9477 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9479 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9487 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9488 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9489 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9492 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9494 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9495 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9496 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9497 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9498 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9501 pic16_emitcode("rlf","known_zero,w");
9508 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9509 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9510 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9512 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9522 pic16_freeAsmop(right,NULL,ic,TRUE);
9523 pic16_freeAsmop(result,NULL,ic,TRUE);
9524 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9525 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9527 nextic->generated = 1;
9534 /*-----------------------------------------------------------------*/
9535 /* genCast - gen code for casting */
9536 /*-----------------------------------------------------------------*/
9537 static void genCast (iCode *ic)
9539 operand *result = IC_RESULT(ic);
9540 sym_link *ctype = operandType(IC_LEFT(ic));
9541 sym_link *rtype = operandType(IC_RIGHT(ic));
9542 operand *right = IC_RIGHT(ic);
9545 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9546 /* if they are equivalent then do nothing */
9547 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9550 pic16_aopOp(right,ic,FALSE) ;
9551 pic16_aopOp(result,ic,FALSE);
9553 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9555 /* if the result is a bit */
9556 if (AOP_TYPE(result) == AOP_CRY) {
9557 /* if the right size is a literal then
9558 we know what the value is */
9559 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9560 if (AOP_TYPE(right) == AOP_LIT) {
9562 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9563 pic16_popGet(AOP(result),0));
9565 if (((int) operandLitValue(right)))
9566 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9567 AOP(result)->aopu.aop_dir,
9568 AOP(result)->aopu.aop_dir);
9570 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9571 AOP(result)->aopu.aop_dir,
9572 AOP(result)->aopu.aop_dir);
9577 /* the right is also a bit variable */
9578 if (AOP_TYPE(right) == AOP_CRY) {
9581 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9583 pic16_emitcode("clrc","");
9584 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9585 AOP(right)->aopu.aop_dir,
9586 AOP(right)->aopu.aop_dir);
9587 pic16_aopPut(AOP(result),"c",0);
9592 if (AOP_TYPE(right) == AOP_REG) {
9593 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9594 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9595 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9597 pic16_toBoolean(right);
9598 pic16_aopPut(AOP(result),"a",0);
9602 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9604 size = AOP_SIZE(result);
9606 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9608 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9609 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9610 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9613 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9618 /* if they are the same size : or less */
9619 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9621 /* if they are in the same place */
9622 if (pic16_sameRegs(AOP(right),AOP(result)))
9625 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9626 if (IS_PTR_CONST(rtype))
9627 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9628 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9629 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9631 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9632 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9633 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9634 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9635 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9636 if(AOP_SIZE(result) <2)
9637 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9641 /* if they in different places then copy */
9642 size = AOP_SIZE(result);
9645 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9646 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9648 //pic16_aopPut(AOP(result),
9649 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9659 /* if the result is of type pointer */
9660 if (IS_PTR(ctype)) {
9663 sym_link *type = operandType(right);
9664 sym_link *etype = getSpec(type);
9665 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9667 /* pointer to generic pointer */
9668 if (IS_GENPTR(ctype)) {
9672 p_type = DCL_TYPE(type);
9674 /* we have to go by the storage class */
9675 p_type = PTR_TYPE(SPEC_OCLS(etype));
9677 /* if (SPEC_OCLS(etype)->codesp ) */
9678 /* p_type = CPOINTER ; */
9680 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9681 /* p_type = FPOINTER ; */
9683 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9684 /* p_type = PPOINTER; */
9686 /* if (SPEC_OCLS(etype) == idata ) */
9687 /* p_type = IPOINTER ; */
9689 /* p_type = POINTER ; */
9692 /* the first two bytes are known */
9693 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9694 size = GPTRSIZE - 1;
9697 if(offset < AOP_SIZE(right)) {
9698 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9699 if ((AOP_TYPE(right) == AOP_PCODE) &&
9700 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9701 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9702 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9704 pic16_aopPut(AOP(result),
9705 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9709 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9712 /* the last byte depending on type */
9716 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9719 pic16_emitcode(";BUG!? ","%d",__LINE__);
9723 pic16_emitcode(";BUG!? ","%d",__LINE__);
9727 pic16_emitcode(";BUG!? ","%d",__LINE__);
9732 /* this should never happen */
9733 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9734 "got unknown pointer type");
9737 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9741 /* just copy the pointers */
9742 size = AOP_SIZE(result);
9745 pic16_aopPut(AOP(result),
9746 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9755 /* so we now know that the size of destination is greater
9756 than the size of the source.
9757 Now, if the next iCode is an operator then we might be
9758 able to optimize the operation without performing a cast.
9760 if(genMixedOperation(ic))
9763 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9765 /* we move to result for the size of source */
9766 size = AOP_SIZE(right);
9769 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9770 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9774 /* now depending on the sign of the destination */
9775 size = AOP_SIZE(result) - AOP_SIZE(right);
9776 /* if unsigned or not an integral type */
9777 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9779 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9781 /* we need to extend the sign :{ */
9784 /* Save one instruction of casting char to int */
9785 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9786 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9787 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
9789 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9792 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9794 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9796 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9799 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
9804 pic16_freeAsmop(right,NULL,ic,TRUE);
9805 pic16_freeAsmop(result,NULL,ic,TRUE);
9809 /*-----------------------------------------------------------------*/
9810 /* genDjnz - generate decrement & jump if not zero instrucion */
9811 /*-----------------------------------------------------------------*/
9812 static int genDjnz (iCode *ic, iCode *ifx)
9815 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9820 /* if the if condition has a false label
9821 then we cannot save */
9825 /* if the minus is not of the form
9827 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9828 !IS_OP_LITERAL(IC_RIGHT(ic)))
9831 if (operandLitValue(IC_RIGHT(ic)) != 1)
9834 /* if the size of this greater than one then no
9836 if (getSize(operandType(IC_RESULT(ic))) > 1)
9839 /* otherwise we can save BIG */
9840 lbl = newiTempLabel(NULL);
9841 lbl1= newiTempLabel(NULL);
9843 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9845 if (IS_AOP_PREG(IC_RESULT(ic))) {
9846 pic16_emitcode("dec","%s",
9847 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9848 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9849 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9853 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9854 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9856 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9857 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9860 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9861 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9862 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9863 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9866 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9871 /*-----------------------------------------------------------------*/
9872 /* genReceive - generate code for a receive iCode */
9873 /*-----------------------------------------------------------------*/
9874 static void genReceive (iCode *ic)
9876 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9878 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9879 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9880 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9882 int size = getSize(operandType(IC_RESULT(ic)));
9883 int offset = pic16_fReturnSizePic - size;
9885 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9886 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9889 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9890 size = AOP_SIZE(IC_RESULT(ic));
9893 pic16_emitcode ("pop","acc");
9894 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9899 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9901 assignResultValue(IC_RESULT(ic));
9904 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9907 /*-----------------------------------------------------------------*/
9908 /* genpic16Code - generate code for pic16 based controllers */
9909 /*-----------------------------------------------------------------*/
9911 * At this point, ralloc.c has gone through the iCode and attempted
9912 * to optimize in a way suitable for a PIC. Now we've got to generate
9913 * PIC instructions that correspond to the iCode.
9915 * Once the instructions are generated, we'll pass through both the
9916 * peep hole optimizer and the pCode optimizer.
9917 *-----------------------------------------------------------------*/
9919 void genpic16Code (iCode *lic)
9924 lineHead = lineCurr = NULL;
9926 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9927 pic16_addpBlock(pb);
9929 /* if debug information required */
9930 if (options.debug && currFunc) {
9932 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9934 if (IS_STATIC(currFunc->etype)) {
9935 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9936 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9938 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9939 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
9946 for (ic = lic ; ic ; ic = ic->next ) {
9948 DEBUGpic16_emitcode(";ic","");
9949 if ( cln != ic->lineno ) {
9950 if ( options.debug ) {
9952 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
9953 FileBaseName(ic->filename),ic->lineno,
9954 ic->level,ic->block);
9958 pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9959 pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9960 printCLine(ic->filename, ic->lineno));
9962 pic16_addpCode2pBlock(pb,
9963 pic16_newpCodeCSource(ic->lineno,
9965 printCLine(ic->filename, ic->lineno)));
9969 /* if the result is marked as
9970 spilt and rematerializable or code for
9971 this has already been generated then
9973 if (resultRemat(ic) || ic->generated )
9976 /* depending on the operation */
9995 /* IPOP happens only when trying to restore a
9996 spilt live range, if there is an ifx statement
9997 following this pop then the if statement might
9998 be using some of the registers being popped which
9999 would destroy the contents of the register so
10000 we need to check for this condition and handle it */
10002 ic->next->op == IFX &&
10003 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10004 genIfx (ic->next,ic);
10022 genEndFunction (ic);
10038 pic16_genPlus (ic) ;
10042 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10043 pic16_genMinus (ic);
10059 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10063 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10070 /* note these two are xlated by algebraic equivalence
10071 during parsing SDCC.y */
10072 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10073 "got '>=' or '<=' shouldn't have come here");
10077 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10089 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10093 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10097 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10121 genRightShift (ic);
10124 case GET_VALUE_AT_ADDRESS:
10129 if (POINTER_SET(ic))
10156 addSet(&_G.sendSet,ic);
10165 /* now we are ready to call the
10166 peep hole optimizer */
10167 if (!options.nopeep) {
10168 peepHole (&lineHead);
10170 /* now do the actual printing */
10171 printLine (lineHead,codeOutFile);
10174 DFPRINTF((stderr,"printing pBlock\n\n"));
10175 pic16_printpBlock(stdout,pb);