1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
8 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them. Help stamp out software-hoarding!
29 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
30 Made everything static
31 -------------------------------------------------------------------------*/
37 #include "SDCCglobl.h"
41 #include "SDCCpeeph.h"
47 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
49 void pic16_genMult8X8_8 (operand *, operand *,operand *);
50 pCode *pic16_AssembleLine(char *line);
51 extern void pic16_printpBlock(FILE *of, pBlock *pb);
52 static asmop *newAsmop (short type);
53 static pCodeOp *popRegFromString(char *str, int size, int offset);
54 static void mov2w (asmop *aop, int offset);
55 static int aopIdx (asmop *aop, int offset);
57 static int labelOffset=0;
58 extern int pic16_debug_verbose;
59 static int optimized_for_speed = 0;
64 int options_no_movff = 1;
66 /* max_key keeps track of the largest label number used in
67 a function. This is then used to adjust the label offset
68 for the next function.
71 static int GpsuedoStkPtr=0;
73 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
74 unsigned int pic16aopLiteral (value *val, int offset);
75 const char *pic16_AopType(short type);
76 static iCode *ifxForOp ( operand *op, iCode *ic );
78 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
80 /* this is the down and dirty file with all kinds of
81 kludgy & hacky stuff. This is what it is all about
82 CODE GENERATION for a specific MCU . some of the
83 routines may be reusable, will have to see */
85 static char *zero = "#0x00";
86 static char *one = "#0x01";
87 static char *spname = "sp";
89 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
90 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
91 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
92 static char **fReturn = fReturnpic16;
94 static char *accUse[] = {"a","b"};
96 //static short rbank = -1;
108 /* Resolved ifx structure. This structure stores information
109 about an iCode ifx that makes it easier to generate code.
111 typedef struct resolvedIfx {
112 symbol *lbl; /* pointer to a label */
113 int condition; /* true or false ifx */
114 int generated; /* set true when the code associated with the ifx
118 extern int pic16_ptrRegReq ;
119 extern int pic16_nRegs;
120 extern FILE *codeOutFile;
121 static void saverbank (int, iCode *,bool);
123 static lineNode *lineHead = NULL;
124 static lineNode *lineCurr = NULL;
126 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
127 0xE0, 0xC0, 0x80, 0x00};
128 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
129 0x07, 0x03, 0x01, 0x00};
133 /*-----------------------------------------------------------------*/
134 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
135 /* exponent of 2 is returned, otherwise -1 is */
137 /* note that this is similar to the function `powof2' in SDCCsymt */
141 /*-----------------------------------------------------------------*/
142 static int my_powof2 (unsigned long num)
145 if( (num & (num-1)) == 0) {
158 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
161 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
163 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
164 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
165 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
166 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
167 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
168 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
169 ((result) ? AOP_SIZE(result) : 0));
173 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
176 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
178 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
179 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
180 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
181 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
182 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
183 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
187 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
190 char lb[INITIAL_INLINEASM];
193 if(!pic16_debug_verbose)
200 sprintf(lb,"%s\t",inst);
202 sprintf(lb,"%s",inst);
203 vsprintf(lb+(strlen(lb)),fmt,ap);
207 while (isspace(*lbp)) lbp++;
210 lineCurr = (lineCurr ?
211 connectLine(lineCurr,newLineNode(lb)) :
212 (lineHead = newLineNode(lb)));
213 lineCurr->isInline = _G.inLine;
214 lineCurr->isDebug = _G.debugLine;
216 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
219 // fprintf(stderr, "%s\n", lb);
223 void pic16_emitpLabel(int key)
225 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
228 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
232 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
234 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
236 // fprintf(stderr, "%s\n", pcop->name);
239 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
242 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
246 /*-----------------------------------------------------------------*/
247 /* pic16_emitcode - writes the code into a file : for now it is simple */
248 /*-----------------------------------------------------------------*/
249 void pic16_emitcode (char *inst,char *fmt, ...)
252 char lb[INITIAL_INLINEASM];
259 sprintf(lb,"%s\t",inst);
261 sprintf(lb,"%s",inst);
262 vsprintf(lb+(strlen(lb)),fmt,ap);
266 while (isspace(*lbp)) lbp++;
269 lineCurr = (lineCurr ?
270 connectLine(lineCurr,newLineNode(lb)) :
271 (lineHead = newLineNode(lb)));
272 lineCurr->isInline = _G.inLine;
273 lineCurr->isDebug = _G.debugLine;
275 // VR fprintf(stderr, "lb = <%s>\n", lbp);
277 if(pic16_debug_verbose)
278 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
289 bool r0iu = FALSE , r1iu = FALSE;
290 bool r0ou = FALSE , r1ou = FALSE;
292 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
294 /* the logic: if r0 & r1 used in the instruction
295 then we are in trouble otherwise */
297 /* first check if r0 & r1 are used by this
298 instruction, in which case we are in trouble */
299 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
300 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
305 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
306 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
308 /* if no usage of r0 then return it */
309 if (!r0iu && !r0ou) {
310 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
311 (*aopp)->type = AOP_R0;
313 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
316 /* if no usage of r1 then return it */
317 if (!r1iu && !r1ou) {
318 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
319 (*aopp)->type = AOP_R1;
321 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
324 /* now we know they both have usage */
325 /* if r0 not used in this instruction */
327 /* push it if not already pushed */
329 //pic16_emitcode ("push","%s",
330 // pic16_regWithIdx(R0_IDX)->dname);
334 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
335 (*aopp)->type = AOP_R0;
337 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
340 /* if r1 not used then */
343 /* push it if not already pushed */
345 //pic16_emitcode ("push","%s",
346 // pic16_regWithIdx(R1_IDX)->dname);
350 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
351 (*aopp)->type = AOP_R1;
352 return pic16_regWithIdx(R1_IDX);
356 /* I said end of world but not quite end of world yet */
357 /* if this is a result then we can push it on the stack*/
359 (*aopp)->type = AOP_STK;
363 /* other wise this is true end of the world */
364 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
365 "getFreePtr should never reach here");
369 /*-----------------------------------------------------------------*/
370 /* newAsmop - creates a new asmOp */
371 /*-----------------------------------------------------------------*/
372 static asmop *newAsmop (short type)
376 aop = Safe_calloc(1,sizeof(asmop));
381 static void genSetDPTR(int n)
385 pic16_emitcode(";", "Select standard DPTR");
386 pic16_emitcode("mov", "dps, #0x00");
390 pic16_emitcode(";", "Select alternate DPTR");
391 pic16_emitcode("mov", "dps, #0x01");
395 /*-----------------------------------------------------------------*/
396 /* resolveIfx - converts an iCode ifx into a form more useful for */
397 /* generating code */
398 /*-----------------------------------------------------------------*/
399 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
404 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
406 resIfx->condition = 1; /* assume that the ifx is true */
407 resIfx->generated = 0; /* indicate that the ifx has not been used */
410 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
412 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
413 __FUNCTION__,__LINE__,resIfx->lbl->key);
417 resIfx->lbl = IC_TRUE(ifx);
419 resIfx->lbl = IC_FALSE(ifx);
420 resIfx->condition = 0;
424 DEBUGpic16_emitcode("; ***","ifx true is non-null");
426 DEBUGpic16_emitcode("; ***","ifx false is non-null");
430 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
433 /*-----------------------------------------------------------------*/
434 /* pointerCode - returns the code for a pointer type */
435 /*-----------------------------------------------------------------*/
436 static int pointerCode (sym_link *etype)
439 return PTR_TYPE(SPEC_OCLS(etype));
443 /*-----------------------------------------------------------------*/
444 /* aopForSym - for a true symbol */
445 /*-----------------------------------------------------------------*/
446 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
449 memmap *space= SPEC_OCLS(sym->etype);
451 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
452 /* if already has one */
454 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
458 /* assign depending on the storage class */
459 /* if it is on the stack or indirectly addressable */
460 /* space we need to assign either r0 or r1 to it */
461 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
462 sym->aop = aop = newAsmop(0);
463 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
464 aop->size = getSize(sym->type);
466 /* now assign the address of the variable to
467 the pointer register */
468 if (aop->type != AOP_STK) {
472 pic16_emitcode("push","acc");
474 pic16_emitcode("mov","a,_bp");
475 pic16_emitcode("add","a,#0x%02x",
477 ((char)(sym->stack - _G.nRegsSaved )) :
478 ((char)sym->stack)) & 0xff);
479 pic16_emitcode("mov","%s,a",
480 aop->aopu.aop_ptr->name);
483 pic16_emitcode("pop","acc");
485 pic16_emitcode("mov","%s,#%s",
486 aop->aopu.aop_ptr->name,
488 aop->paged = space->paged;
490 aop->aopu.aop_stk = sym->stack;
494 if (sym->onStack && options.stack10bit)
496 /* It's on the 10 bit stack, which is located in
500 //DEBUGpic16_emitcode(";","%d",__LINE__);
503 pic16_emitcode("push","acc");
505 pic16_emitcode("mov","a,_bp");
506 pic16_emitcode("add","a,#0x%02x",
508 ((char)(sym->stack - _G.nRegsSaved )) :
509 ((char)sym->stack)) & 0xff);
512 pic16_emitcode ("mov","dpx1,#0x40");
513 pic16_emitcode ("mov","dph1,#0x00");
514 pic16_emitcode ("mov","dpl1, a");
518 pic16_emitcode("pop","acc");
520 sym->aop = aop = newAsmop(AOP_DPTR2);
521 aop->size = getSize(sym->type);
525 //DEBUGpic16_emitcode(";","%d",__LINE__);
526 /* if in bit space */
527 if (IN_BITSPACE(space)) {
528 sym->aop = aop = newAsmop (AOP_CRY);
529 aop->aopu.aop_dir = sym->rname ;
530 aop->size = getSize(sym->type);
531 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
534 /* if it is in direct space */
535 if (IN_DIRSPACE(space)) {
536 sym->aop = aop = newAsmop (AOP_DIR);
537 aop->aopu.aop_dir = sym->rname ;
538 aop->size = getSize(sym->type);
539 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
543 /* special case for a function */
544 if (IS_FUNC(sym->type)) {
545 sym->aop = aop = newAsmop(AOP_IMMD);
546 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
547 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
548 strcpy(aop->aopu.aop_immd,sym->rname);
549 aop->size = FPTRSIZE;
550 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
555 /* only remaining is far space */
556 /* in which case DPTR gets the address */
557 sym->aop = aop = newAsmop(AOP_PCODE);
559 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
560 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
561 PCOI(aop->aopu.pcop)->index = 0;
563 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
564 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
566 pic16_allocDirReg (IC_LEFT(ic));
568 aop->size = FPTRSIZE;
570 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
571 sym->aop = aop = newAsmop(AOP_DPTR);
572 pic16_emitcode ("mov","dptr,#%s", sym->rname);
573 aop->size = getSize(sym->type);
575 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
578 /* if it is in code space */
579 if (IN_CODESPACE(space))
585 /*-----------------------------------------------------------------*/
586 /* aopForRemat - rematerialzes an object */
587 /*-----------------------------------------------------------------*/
588 static asmop *aopForRemat (operand *op) // x symbol *sym)
590 symbol *sym = OP_SYMBOL(op);
592 asmop *aop = newAsmop(AOP_PCODE);
596 ic = sym->rematiCode;
598 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
599 if(IS_OP_POINTER(op)) {
600 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
604 val += (int) operandLitValue(IC_RIGHT(ic));
605 } else if (ic->op == '-') {
606 val -= (int) operandLitValue(IC_RIGHT(ic));
610 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
613 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
614 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
615 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
616 PCOI(aop->aopu.pcop)->index = val;
618 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
619 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
620 val, IS_PTR_CONST(operandType(op)));
622 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
624 pic16_allocDirReg (IC_LEFT(ic));
629 static int aopIdx (asmop *aop, int offset)
634 if(aop->type != AOP_REG)
637 return aop->aopu.aop_reg[offset]->rIdx;
640 /*-----------------------------------------------------------------*/
641 /* regsInCommon - two operands have some registers in common */
642 /*-----------------------------------------------------------------*/
643 static bool regsInCommon (operand *op1, operand *op2)
648 /* if they have registers in common */
649 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
652 sym1 = OP_SYMBOL(op1);
653 sym2 = OP_SYMBOL(op2);
655 if (sym1->nRegs == 0 || sym2->nRegs == 0)
658 for (i = 0 ; i < sym1->nRegs ; i++) {
663 for (j = 0 ; j < sym2->nRegs ;j++ ) {
667 if (sym2->regs[j] == sym1->regs[i])
675 /*-----------------------------------------------------------------*/
676 /* operandsEqu - equivalent */
677 /*-----------------------------------------------------------------*/
678 static bool operandsEqu ( operand *op1, operand *op2)
682 /* if they not symbols */
683 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
686 sym1 = OP_SYMBOL(op1);
687 sym2 = OP_SYMBOL(op2);
689 /* if both are itemps & one is spilt
690 and the other is not then false */
691 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
692 sym1->isspilt != sym2->isspilt )
695 /* if they are the same */
699 if (strcmp(sym1->rname,sym2->rname) == 0)
703 /* if left is a tmp & right is not */
707 (sym1->usl.spillLoc == sym2))
714 (sym2->usl.spillLoc == sym1))
720 /*-----------------------------------------------------------------*/
721 /* pic16_sameRegs - two asmops have the same registers */
722 /*-----------------------------------------------------------------*/
723 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
730 if (aop1->type != AOP_REG ||
731 aop2->type != AOP_REG )
734 if (aop1->size != aop2->size )
737 for (i = 0 ; i < aop1->size ; i++ )
738 if (aop1->aopu.aop_reg[i] !=
739 aop2->aopu.aop_reg[i] )
745 /*-----------------------------------------------------------------*/
746 /* pic16_aopOp - allocates an asmop for an operand : */
747 /*-----------------------------------------------------------------*/
748 void pic16_aopOp (operand *op, iCode *ic, bool result)
757 DEBUGpic16_emitcode(";","%d",__LINE__);
758 /* if this a literal */
759 if (IS_OP_LITERAL(op)) {
760 op->aop = aop = newAsmop(AOP_LIT);
761 aop->aopu.aop_lit = op->operand.valOperand;
762 aop->size = getSize(operandType(op));
767 sym_link *type = operandType(op);
768 if(IS_PTR_CONST(type))
769 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
772 /* if already has a asmop then continue */
776 /* if the underlying symbol has a aop */
777 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
778 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
779 op->aop = OP_SYMBOL(op)->aop;
783 /* if this is a true symbol */
784 if (IS_TRUE_SYMOP(op)) {
785 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
786 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
790 /* this is a temporary : this has
796 e) can be a return use only */
800 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
801 /* if the type is a conditional */
802 if (sym->regType == REG_CND) {
803 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
808 /* if it is spilt then two situations
810 b) has a spill location */
811 if (sym->isspilt || sym->nRegs == 0) {
813 DEBUGpic16_emitcode(";","%d",__LINE__);
814 /* rematerialize it NOW */
817 sym->aop = op->aop = aop =
819 aop->size = getSize(sym->type);
820 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
826 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
827 aop->size = getSize(sym->type);
828 for ( i = 0 ; i < 2 ; i++ )
829 aop->aopu.aop_str[i] = accUse[i];
830 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
836 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
837 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
838 //pic16_allocDirReg (IC_LEFT(ic));
839 aop->size = getSize(sym->type);
844 aop = op->aop = sym->aop = newAsmop(AOP_STR);
845 aop->size = getSize(sym->type);
846 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
847 aop->aopu.aop_str[i] = fReturn[i];
849 DEBUGpic16_emitcode(";","%d",__LINE__);
853 /* else spill location */
854 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
855 /* force a new aop if sizes differ */
856 sym->usl.spillLoc->aop = NULL;
858 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
859 __FUNCTION__,__LINE__,
860 sym->usl.spillLoc->rname,
861 sym->rname, sym->usl.spillLoc->offset);
863 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
864 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
865 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
867 sym->usl.spillLoc->offset);
868 aop->size = getSize(sym->type);
874 sym_link *type = operandType(op);
875 if(IS_PTR_CONST(type))
876 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
879 /* must be in a register */
880 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
881 sym->aop = op->aop = aop = newAsmop(AOP_REG);
882 aop->size = sym->nRegs;
883 for ( i = 0 ; i < sym->nRegs ;i++)
884 aop->aopu.aop_reg[i] = sym->regs[i];
887 /*-----------------------------------------------------------------*/
888 /* pic16_freeAsmop - free up the asmop given to an operand */
889 /*----------------------------------------------------------------*/
890 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
907 /* depending on the asmop type only three cases need work AOP_RO
908 , AOP_R1 && AOP_STK */
914 pic16_emitcode ("pop","ar0");
918 bitVectUnSetBit(ic->rUsed,R0_IDX);
924 pic16_emitcode ("pop","ar1");
928 bitVectUnSetBit(ic->rUsed,R1_IDX);
934 int stk = aop->aopu.aop_stk + aop->size;
935 bitVectUnSetBit(ic->rUsed,R0_IDX);
936 bitVectUnSetBit(ic->rUsed,R1_IDX);
938 getFreePtr(ic,&aop,FALSE);
940 if (options.stack10bit)
942 /* I'm not sure what to do here yet... */
945 "*** Warning: probably generating bad code for "
946 "10 bit stack mode.\n");
950 pic16_emitcode ("mov","a,_bp");
951 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
952 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
954 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
958 pic16_emitcode("pop","acc");
959 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
961 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
964 pic16_freeAsmop(op,NULL,ic,TRUE);
966 pic16_emitcode("pop","ar0");
971 pic16_emitcode("pop","ar1");
979 /* all other cases just dealloc */
983 OP_SYMBOL(op)->aop = NULL;
984 /* if the symbol has a spill */
986 SPIL_LOC(op)->aop = NULL;
991 /*-----------------------------------------------------------------*/
992 /* pic16_aopGet - for fetching value of the aop */
993 /*-----------------------------------------------------------------*/
994 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
999 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1000 /* offset is greater than
1002 if (offset > (aop->size - 1) &&
1003 aop->type != AOP_LIT)
1006 /* depending on type */
1007 switch (aop->type) {
1011 DEBUGpic16_emitcode(";","%d",__LINE__);
1012 /* if we need to increment it */
1013 while (offset > aop->coff) {
1014 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1018 while (offset < aop->coff) {
1019 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1023 aop->coff = offset ;
1025 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1026 return (dname ? "acc" : "a");
1028 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1029 rs = Safe_calloc(1,strlen(s)+1);
1035 DEBUGpic16_emitcode(";","%d",__LINE__);
1036 if (aop->type == AOP_DPTR2)
1041 while (offset > aop->coff) {
1042 pic16_emitcode ("inc","dptr");
1046 while (offset < aop->coff) {
1047 pic16_emitcode("lcall","__decdptr");
1053 pic16_emitcode("clr","a");
1054 pic16_emitcode("movc","a,@a+dptr");
1057 pic16_emitcode("movx","a,@dptr");
1060 if (aop->type == AOP_DPTR2)
1065 return (dname ? "acc" : "a");
1070 sprintf (s,"%s",aop->aopu.aop_immd);
1073 sprintf(s,"(%s >> %d)",
1078 aop->aopu.aop_immd);
1079 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1080 rs = Safe_calloc(1,strlen(s)+1);
1086 sprintf(s,"(%s + %d)",
1089 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1091 sprintf(s,"%s",aop->aopu.aop_dir);
1092 rs = Safe_calloc(1,strlen(s)+1);
1098 // return aop->aopu.aop_reg[offset]->dname;
1100 return aop->aopu.aop_reg[offset]->name;
1103 //pic16_emitcode(";","%d",__LINE__);
1104 return aop->aopu.aop_dir;
1107 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1108 return "AOP_accumulator_bug";
1111 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1112 rs = Safe_calloc(1,strlen(s)+1);
1117 aop->coff = offset ;
1118 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1121 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1123 return aop->aopu.aop_str[offset];
1127 pCodeOp *pcop = aop->aopu.pcop;
1128 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1130 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1131 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1132 sprintf(s,"%s", pcop->name);
1134 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1137 rs = Safe_calloc(1,strlen(s)+1);
1143 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1144 "aopget got unsupported aop->type");
1149 /*-----------------------------------------------------------------*/
1150 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1151 /*-----------------------------------------------------------------*/
1152 pCodeOp *pic16_popGetTempReg(void)
1157 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1158 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1159 PCOR(pcop)->r->wasUsed=1;
1160 PCOR(pcop)->r->isFree=0;
1166 /*-----------------------------------------------------------------*/
1167 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1168 /*-----------------------------------------------------------------*/
1169 void pic16_popReleaseTempReg(pCodeOp *pcop)
1172 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1173 PCOR(pcop)->r->isFree = 1;
1176 /*-----------------------------------------------------------------*/
1177 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1178 /*-----------------------------------------------------------------*/
1179 pCodeOp *pic16_popGetLabel(unsigned int key)
1182 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1187 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1190 /*-----------------------------------------------------------------*/
1191 /* pic16_popCopyReg - copy a pcode operator */
1192 /*-----------------------------------------------------------------*/
1193 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1197 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1198 pcor->pcop.type = pc->pcop.type;
1200 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1201 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1203 pcor->pcop.name = NULL;
1206 pcor->rIdx = pc->rIdx;
1209 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1213 /*-----------------------------------------------------------------*/
1214 /* pic16_popGet - asm operator to pcode operator conversion */
1215 /*-----------------------------------------------------------------*/
1216 pCodeOp *pic16_popGetLit(unsigned int lit)
1219 return pic16_newpCodeOpLit(lit);
1223 /*-----------------------------------------------------------------*/
1224 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1229 return pic16_newpCodeOpImmd(name, offset,index, 0);
1233 /*-----------------------------------------------------------------*/
1234 /* pic16_popGet - asm operator to pcode operator conversion */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *pic16_popGetWithString(char *str)
1242 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1246 pcop = pic16_newpCodeOp(str,PO_STR);
1251 /*-----------------------------------------------------------------*/
1252 /* popRegFromString - */
1253 /*-----------------------------------------------------------------*/
1254 static pCodeOp *popRegFromString(char *str, int size, int offset)
1257 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1258 pcop->type = PO_DIR;
1260 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1261 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1266 pcop->name = Safe_calloc(1,strlen(str)+1);
1267 strcpy(pcop->name,str);
1269 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1271 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1272 if(PCOR(pcop)->r == NULL) {
1273 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1276 //fprintf(stderr, "allocating new register -> %s\n", str);
1278 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1280 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1282 PCOR(pcop)->instance = offset;
1287 static pCodeOp *popRegFromIdx(int rIdx)
1291 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1292 __FUNCTION__,__LINE__,rIdx);
1294 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1296 PCOR(pcop)->rIdx = rIdx;
1297 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1298 PCOR(pcop)->r->isFree = 0;
1299 PCOR(pcop)->r->wasUsed = 1;
1301 pcop->type = PCOR(pcop)->r->pc_type;
1307 /*---------------------------------------------------------------------------------*/
1308 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1310 /*---------------------------------------------------------------------------------*/
1311 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1316 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1317 temp = pic16_popGet(aop_dst, offset);
1318 pcop2->pcop2 = temp;
1324 /*-----------------------------------------------------------------*/
1325 /* pic16_popGet - asm operator to pcode operator conversion */
1326 /*-----------------------------------------------------------------*/
1327 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1329 //char *s = buffer ;
1334 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1335 /* offset is greater than
1338 if (offset > (aop->size - 1) &&
1339 aop->type != AOP_LIT)
1340 return NULL; //zero;
1342 /* depending on type */
1343 switch (aop->type) {
1350 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1354 DEBUGpic16_emitcode(";","%d",__LINE__);
1355 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1358 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1361 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1362 pcop->type = PO_DIR;
1366 sprintf(s,"(%s + %d)",
1370 sprintf(s,"%s",aop->aopu.aop_dir);
1371 pcop->name = Safe_calloc(1,strlen(s)+1);
1372 strcpy(pcop->name,s);
1374 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1375 strcpy(pcop->name,aop->aopu.aop_dir);
1376 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1377 if(PCOR(pcop)->r == NULL) {
1378 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1379 PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1380 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1382 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1384 PCOR(pcop)->instance = offset;
1391 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1393 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1394 PCOR(pcop)->rIdx = rIdx;
1395 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1396 PCOR(pcop)->r->wasUsed=1;
1397 PCOR(pcop)->r->isFree=0;
1399 PCOR(pcop)->instance = offset;
1400 pcop->type = PCOR(pcop)->r->pc_type;
1401 //rs = aop->aopu.aop_reg[offset]->name;
1402 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1407 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1408 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1409 //if(PCOR(pcop)->r == NULL)
1410 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1414 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1417 DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1418 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1420 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1421 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1422 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1423 pcop->type = PCOR(pcop)->r->pc_type;
1424 pcop->name = PCOR(pcop)->r->name;
1430 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1432 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1433 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1434 PCOI(pcop)->offset = offset;
1438 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1439 "pic16_popGet got unsupported aop->type");
1442 /*-----------------------------------------------------------------*/
1443 /* pic16_aopPut - puts a string for a aop */
1444 /*-----------------------------------------------------------------*/
1445 void pic16_aopPut (asmop *aop, char *s, int offset)
1450 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1452 if (aop->size && offset > ( aop->size - 1)) {
1453 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1454 "pic16_aopPut got offset > aop->size");
1458 /* will assign value to value */
1459 /* depending on where it is ofcourse */
1460 switch (aop->type) {
1463 sprintf(d,"(%s + %d)",
1464 aop->aopu.aop_dir,offset);
1465 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1468 sprintf(d,"%s",aop->aopu.aop_dir);
1471 DEBUGpic16_emitcode(";","%d",__LINE__);
1473 pic16_emitcode("movf","%s,w",s);
1474 pic16_emitcode("movwf","%s",d);
1477 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1478 if(offset >= aop->size) {
1479 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1482 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1485 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1492 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1493 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1496 strcmp(s,"r0") == 0 ||
1497 strcmp(s,"r1") == 0 ||
1498 strcmp(s,"r2") == 0 ||
1499 strcmp(s,"r3") == 0 ||
1500 strcmp(s,"r4") == 0 ||
1501 strcmp(s,"r5") == 0 ||
1502 strcmp(s,"r6") == 0 ||
1503 strcmp(s,"r7") == 0 )
1504 pic16_emitcode("mov","%s,%s ; %d",
1505 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1509 if(strcmp(s,"W")==0 )
1510 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1512 pic16_emitcode("movwf","%s",
1513 aop->aopu.aop_reg[offset]->name);
1515 if(strcmp(s,zero)==0) {
1516 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1518 } else if(strcmp(s,"W")==0) {
1519 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1520 pcop->type = PO_GPR_REGISTER;
1522 PCOR(pcop)->rIdx = -1;
1523 PCOR(pcop)->r = NULL;
1525 DEBUGpic16_emitcode(";","%d",__LINE__);
1526 pcop->name = Safe_strdup(s);
1527 pic16_emitpcode(POC_MOVFW,pcop);
1528 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1529 } else if(strcmp(s,one)==0) {
1530 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1531 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1533 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1541 if (aop->type == AOP_DPTR2)
1547 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1548 "pic16_aopPut writting to code space");
1552 while (offset > aop->coff) {
1554 pic16_emitcode ("inc","dptr");
1557 while (offset < aop->coff) {
1559 pic16_emitcode("lcall","__decdptr");
1564 /* if not in accumulater */
1567 pic16_emitcode ("movx","@dptr,a");
1569 if (aop->type == AOP_DPTR2)
1577 while (offset > aop->coff) {
1579 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1581 while (offset < aop->coff) {
1583 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1589 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1594 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1596 if (strcmp(s,"r0") == 0 ||
1597 strcmp(s,"r1") == 0 ||
1598 strcmp(s,"r2") == 0 ||
1599 strcmp(s,"r3") == 0 ||
1600 strcmp(s,"r4") == 0 ||
1601 strcmp(s,"r5") == 0 ||
1602 strcmp(s,"r6") == 0 ||
1603 strcmp(s,"r7") == 0 ) {
1605 sprintf(buffer,"a%s",s);
1606 pic16_emitcode("mov","@%s,%s",
1607 aop->aopu.aop_ptr->name,buffer);
1609 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1614 if (strcmp(s,"a") == 0)
1615 pic16_emitcode("push","acc");
1617 pic16_emitcode("push","%s",s);
1622 /* if bit variable */
1623 if (!aop->aopu.aop_dir) {
1624 pic16_emitcode("clr","a");
1625 pic16_emitcode("rlc","a");
1628 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1631 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1634 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1636 lbl = newiTempLabel(NULL);
1638 if (strcmp(s,"a")) {
1641 pic16_emitcode("clr","c");
1642 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1643 pic16_emitcode("cpl","c");
1644 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1645 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1652 if (strcmp(aop->aopu.aop_str[offset],s))
1653 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1658 if (!offset && (strcmp(s,"acc") == 0))
1661 if (strcmp(aop->aopu.aop_str[offset],s))
1662 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1666 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1667 "pic16_aopPut got unsupported aop->type");
1673 /*-----------------------------------------------------------------*/
1674 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1675 /*-----------------------------------------------------------------*/
1676 static void mov2w (asmop *aop, int offset)
1682 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1684 if ( aop->type == AOP_PCODE ||
1685 aop->type == AOP_LIT )
1686 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1688 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1692 /*-----------------------------------------------------------------*/
1693 /* reAdjustPreg - points a register back to where it should */
1694 /*-----------------------------------------------------------------*/
1695 static void reAdjustPreg (asmop *aop)
1699 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1701 if ((size = aop->size) <= 1)
1704 switch (aop->type) {
1708 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1712 if (aop->type == AOP_DPTR2)
1718 pic16_emitcode("lcall","__decdptr");
1721 if (aop->type == AOP_DPTR2)
1731 /*-----------------------------------------------------------------*/
1732 /* genNotFloat - generates not for float operations */
1733 /*-----------------------------------------------------------------*/
1734 static void genNotFloat (operand *op, operand *res)
1740 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1741 /* we will put 127 in the first byte of
1743 pic16_aopPut(AOP(res),"#127",0);
1744 size = AOP_SIZE(op) - 1;
1747 l = pic16_aopGet(op->aop,offset++,FALSE,FALSE);
1751 pic16_emitcode("orl","a,%s",
1752 pic16_aopGet(op->aop,
1753 offset++,FALSE,FALSE));
1755 tlbl = newiTempLabel(NULL);
1757 tlbl = newiTempLabel(NULL);
1758 pic16_aopPut(res->aop,one,1);
1759 pic16_emitcode("jz","%05d_DS_",(tlbl->key+100));
1760 pic16_aopPut(res->aop,zero,1);
1761 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
1763 size = res->aop->size - 2;
1765 /* put zeros in the rest */
1767 pic16_aopPut(res->aop,zero,offset++);
1771 /*-----------------------------------------------------------------*/
1772 /* opIsGptr: returns non-zero if the passed operand is */
1773 /* a generic pointer type. */
1774 /*-----------------------------------------------------------------*/
1775 static int opIsGptr(operand *op)
1777 sym_link *type = operandType(op);
1779 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1780 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1788 /*-----------------------------------------------------------------*/
1789 /* pic16_getDataSize - get the operand data size */
1790 /*-----------------------------------------------------------------*/
1791 int pic16_getDataSize(operand *op)
1793 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1796 return AOP_SIZE(op);
1798 // tsd- in the pic port, the genptr size is 1, so this code here
1799 // fails. ( in the 8051 port, the size was 4).
1802 size = AOP_SIZE(op);
1803 if (size == GPTRSIZE)
1805 sym_link *type = operandType(op);
1806 if (IS_GENPTR(type))
1808 /* generic pointer; arithmetic operations
1809 * should ignore the high byte (pointer type).
1812 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1819 /*-----------------------------------------------------------------*/
1820 /* pic16_outAcc - output Acc */
1821 /*-----------------------------------------------------------------*/
1822 void pic16_outAcc(operand *result)
1825 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1826 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1829 size = pic16_getDataSize(result);
1831 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1834 /* unsigned or positive */
1836 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1841 /*-----------------------------------------------------------------*/
1842 /* pic16_outBitC - output a bit C */
1843 /*-----------------------------------------------------------------*/
1844 void pic16_outBitC(operand *result)
1847 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1848 /* if the result is bit */
1849 if (AOP_TYPE(result) == AOP_CRY)
1850 pic16_aopPut(AOP(result),"c",0);
1852 pic16_emitcode("clr","a ; %d", __LINE__);
1853 pic16_emitcode("rlc","a");
1854 pic16_outAcc(result);
1858 /*-----------------------------------------------------------------*/
1859 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1860 /*-----------------------------------------------------------------*/
1861 void pic16_toBoolean(operand *oper)
1863 int size = AOP_SIZE(oper) - 1;
1866 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1868 if ( AOP_TYPE(oper) != AOP_ACC) {
1869 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1872 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1877 /*-----------------------------------------------------------------*/
1878 /* genNot - generate code for ! operation */
1879 /*-----------------------------------------------------------------*/
1880 static void genNot (iCode *ic)
1883 sym_link *optype = operandType(IC_LEFT(ic));
1886 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1887 /* assign asmOps to operand & result */
1888 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1889 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1891 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1892 /* if in bit space then a special case */
1893 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1894 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1895 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1896 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1898 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1899 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1900 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1905 /* if type float then do float */
1906 if (IS_FLOAT(optype)) {
1907 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1911 size = AOP_SIZE(IC_RESULT(ic));
1913 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1914 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1915 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1918 pic16_toBoolean(IC_LEFT(ic));
1920 tlbl = newiTempLabel(NULL);
1921 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1922 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1923 pic16_outBitC(IC_RESULT(ic));
1926 /* release the aops */
1927 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1928 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1932 /*-----------------------------------------------------------------*/
1933 /* genCpl - generate code for complement */
1934 /*-----------------------------------------------------------------*/
1935 static void genCpl (iCode *ic)
1941 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1942 /* assign asmOps to operand & result */
1943 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1944 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1946 /* if both are in bit space then
1948 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1949 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1951 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1952 pic16_emitcode("cpl","c");
1953 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1957 size = AOP_SIZE(IC_RESULT(ic));
1960 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1962 pic16_emitcode("cpl","a");
1963 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1965 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1966 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
1968 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1969 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1977 /* release the aops */
1978 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1979 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1982 /*-----------------------------------------------------------------*/
1983 /* genUminusFloat - unary minus for floating points */
1984 /*-----------------------------------------------------------------*/
1985 static void genUminusFloat(operand *op,operand *result)
1987 int size ,offset =0 ;
1990 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1991 /* for this we just need to flip the
1992 first it then copy the rest in place */
1993 size = AOP_SIZE(op) - 1;
1994 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1998 pic16_emitcode("cpl","acc.7");
1999 pic16_aopPut(AOP(result),"a",3);
2002 pic16_aopPut(AOP(result),
2003 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2009 /*-----------------------------------------------------------------*/
2010 /* genUminus - unary minus code generation */
2011 /*-----------------------------------------------------------------*/
2012 static void genUminus (iCode *ic)
2015 sym_link *optype, *rtype;
2018 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2020 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2021 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2023 /* if both in bit space then special
2025 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2026 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2028 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2029 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2030 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2035 optype = operandType(IC_LEFT(ic));
2036 rtype = operandType(IC_RESULT(ic));
2038 /* if float then do float stuff */
2039 if (IS_FLOAT(optype)) {
2040 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2044 /* otherwise subtract from zero by taking the 2's complement */
2045 size = AOP_SIZE(IC_LEFT(ic));
2047 for(i=0; i<size; i++) {
2048 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2049 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2051 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2052 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2056 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2057 for(i=1; i<size; i++) {
2059 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2063 /* release the aops */
2064 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2065 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2068 /*-----------------------------------------------------------------*/
2069 /* saveRegisters - will look for a call and save the registers */
2070 /*-----------------------------------------------------------------*/
2071 static void saveRegisters(iCode *lic)
2078 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2080 for (ic = lic ; ic ; ic = ic->next)
2081 if (ic->op == CALL || ic->op == PCALL)
2085 fprintf(stderr,"found parameter push with no function call\n");
2089 /* if the registers have been saved already then
2091 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2094 /* find the registers in use at this time
2095 and push them away to safety */
2096 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2100 if (options.useXstack) {
2101 if (bitVectBitValue(rsave,R0_IDX))
2102 pic16_emitcode("mov","b,r0");
2103 pic16_emitcode("mov","r0,%s",spname);
2104 for (i = 0 ; i < pic16_nRegs ; i++) {
2105 if (bitVectBitValue(rsave,i)) {
2107 pic16_emitcode("mov","a,b");
2109 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2110 pic16_emitcode("movx","@r0,a");
2111 pic16_emitcode("inc","r0");
2114 pic16_emitcode("mov","%s,r0",spname);
2115 if (bitVectBitValue(rsave,R0_IDX))
2116 pic16_emitcode("mov","r0,b");
2118 //for (i = 0 ; i < pic16_nRegs ; i++) {
2119 // if (bitVectBitValue(rsave,i))
2120 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2123 dtype = operandType(IC_LEFT(ic));
2124 if (currFunc && dtype &&
2125 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2126 IFFUNC_ISISR(currFunc->type) &&
2129 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2132 /*-----------------------------------------------------------------*/
2133 /* unsaveRegisters - pop the pushed registers */
2134 /*-----------------------------------------------------------------*/
2135 static void unsaveRegisters (iCode *ic)
2140 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2141 /* find the registers in use at this time
2142 and push them away to safety */
2143 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2146 if (options.useXstack) {
2147 pic16_emitcode("mov","r0,%s",spname);
2148 for (i = pic16_nRegs ; i >= 0 ; i--) {
2149 if (bitVectBitValue(rsave,i)) {
2150 pic16_emitcode("dec","r0");
2151 pic16_emitcode("movx","a,@r0");
2153 pic16_emitcode("mov","b,a");
2155 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2159 pic16_emitcode("mov","%s,r0",spname);
2160 if (bitVectBitValue(rsave,R0_IDX))
2161 pic16_emitcode("mov","r0,b");
2163 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2164 // if (bitVectBitValue(rsave,i))
2165 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2171 /*-----------------------------------------------------------------*/
2173 /*-----------------------------------------------------------------*/
2174 static void pushSide(operand * oper, int size)
2178 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2180 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2181 if (AOP_TYPE(oper) != AOP_REG &&
2182 AOP_TYPE(oper) != AOP_DIR &&
2184 pic16_emitcode("mov","a,%s",l);
2185 pic16_emitcode("push","acc");
2187 pic16_emitcode("push","%s",l);
2192 /*-----------------------------------------------------------------*/
2193 /* assignResultValue - */
2194 /*-----------------------------------------------------------------*/
2195 static void assignResultValue(operand * oper)
2197 int size = AOP_SIZE(oper);
2199 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2201 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2203 if(!GpsuedoStkPtr) {
2204 /* The last byte in the assignment is in W */
2206 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2211 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2213 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2218 /*-----------------------------------------------------------------*/
2219 /* genIpush - genrate code for pushing this gets a little complex */
2220 /*-----------------------------------------------------------------*/
2221 static void genIpush (iCode *ic)
2224 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2226 int size, offset = 0 ;
2230 /* if this is not a parm push : ie. it is spill push
2231 and spill push is always done on the local stack */
2232 if (!ic->parmPush) {
2234 /* and the item is spilt then do nothing */
2235 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2238 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2239 size = AOP_SIZE(IC_LEFT(ic));
2240 /* push it on the stack */
2242 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2247 pic16_emitcode("push","%s",l);
2252 /* this is a paramter push: in this case we call
2253 the routine to find the call and save those
2254 registers that need to be saved */
2257 /* then do the push */
2258 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2261 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2262 size = AOP_SIZE(IC_LEFT(ic));
2265 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2266 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2267 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2269 pic16_emitcode("mov","a,%s",l);
2270 pic16_emitcode("push","acc");
2272 pic16_emitcode("push","%s",l);
2275 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2279 /*-----------------------------------------------------------------*/
2280 /* genIpop - recover the registers: can happen only for spilling */
2281 /*-----------------------------------------------------------------*/
2282 static void genIpop (iCode *ic)
2284 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2289 /* if the temp was not pushed then */
2290 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2293 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2294 size = AOP_SIZE(IC_LEFT(ic));
2297 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2300 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2304 /*-----------------------------------------------------------------*/
2305 /* unsaverbank - restores the resgister bank from stack */
2306 /*-----------------------------------------------------------------*/
2307 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2309 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2315 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2317 if (options.useXstack) {
2319 r = getFreePtr(ic,&aop,FALSE);
2322 pic16_emitcode("mov","%s,_spx",r->name);
2323 pic16_emitcode("movx","a,@%s",r->name);
2324 pic16_emitcode("mov","psw,a");
2325 pic16_emitcode("dec","%s",r->name);
2328 pic16_emitcode ("pop","psw");
2331 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2332 if (options.useXstack) {
2333 pic16_emitcode("movx","a,@%s",r->name);
2334 //pic16_emitcode("mov","(%s+%d),a",
2335 // regspic16[i].base,8*bank+regspic16[i].offset);
2336 pic16_emitcode("dec","%s",r->name);
2339 pic16_emitcode("pop",""); //"(%s+%d)",
2340 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2343 if (options.useXstack) {
2345 pic16_emitcode("mov","_spx,%s",r->name);
2346 pic16_freeAsmop(NULL,aop,ic,TRUE);
2352 /*-----------------------------------------------------------------*/
2353 /* saverbank - saves an entire register bank on the stack */
2354 /*-----------------------------------------------------------------*/
2355 static void saverbank (int bank, iCode *ic, bool pushPsw)
2357 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2363 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2364 if (options.useXstack) {
2367 r = getFreePtr(ic,&aop,FALSE);
2368 pic16_emitcode("mov","%s,_spx",r->name);
2372 for (i = 0 ; i < pic16_nRegs ;i++) {
2373 if (options.useXstack) {
2374 pic16_emitcode("inc","%s",r->name);
2375 //pic16_emitcode("mov","a,(%s+%d)",
2376 // regspic16[i].base,8*bank+regspic16[i].offset);
2377 pic16_emitcode("movx","@%s,a",r->name);
2379 pic16_emitcode("push","");// "(%s+%d)",
2380 //regspic16[i].base,8*bank+regspic16[i].offset);
2384 if (options.useXstack) {
2385 pic16_emitcode("mov","a,psw");
2386 pic16_emitcode("movx","@%s,a",r->name);
2387 pic16_emitcode("inc","%s",r->name);
2388 pic16_emitcode("mov","_spx,%s",r->name);
2389 pic16_freeAsmop (NULL,aop,ic,TRUE);
2392 pic16_emitcode("push","psw");
2394 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2400 /*-----------------------------------------------------------------*/
2401 /* genCall - generates a call statement */
2402 /*-----------------------------------------------------------------*/
2403 static void genCall (iCode *ic)
2407 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2409 /* if caller saves & we have not saved then */
2413 /* if we are calling a function that is not using
2414 the same register bank then we need to save the
2415 destination registers on the stack */
2416 dtype = operandType(IC_LEFT(ic));
2417 if (currFunc && dtype &&
2418 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2419 IFFUNC_ISISR(currFunc->type) &&
2422 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2424 /* if send set is not empty the assign */
2427 /* For the Pic port, there is no data stack.
2428 * So parameters passed to functions are stored
2429 * in registers. (The pCode optimizer will get
2430 * rid of most of these :).
2432 int psuedoStkPtr=-1;
2433 int firstTimeThruLoop = 1;
2435 _G.sendSet = reverseSet(_G.sendSet);
2437 /* First figure how many parameters are getting passed */
2438 for (sic = setFirstItem(_G.sendSet) ; sic ;
2439 sic = setNextItem(_G.sendSet)) {
2441 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2442 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2443 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2446 for (sic = setFirstItem(_G.sendSet) ; sic ;
2447 sic = setNextItem(_G.sendSet)) {
2448 int size, offset = 0;
2450 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2451 size = AOP_SIZE(IC_LEFT(sic));
2454 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2455 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2457 if(!firstTimeThruLoop) {
2458 /* If this is not the first time we've been through the loop
2459 * then we need to save the parameter in a temporary
2460 * register. The last byte of the last parameter is
2462 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2465 firstTimeThruLoop=0;
2467 //if (strcmp(l,fReturn[offset])) {
2468 mov2w (AOP(IC_LEFT(sic)), offset);
2470 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2471 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2472 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2474 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2479 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2484 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2485 OP_SYMBOL(IC_LEFT(ic))->rname :
2486 OP_SYMBOL(IC_LEFT(ic))->name));
2489 /* if we need assign a result value */
2490 if ((IS_ITEMP(IC_RESULT(ic)) &&
2491 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2492 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2493 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2496 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2499 assignResultValue(IC_RESULT(ic));
2501 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2502 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2504 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2507 /* adjust the stack for parameters if
2509 if (ic->parmBytes) {
2511 if (ic->parmBytes > 3) {
2512 pic16_emitcode("mov","a,%s",spname);
2513 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2514 pic16_emitcode("mov","%s,a",spname);
2516 for ( i = 0 ; i < ic->parmBytes ;i++)
2517 pic16_emitcode("dec","%s",spname);
2521 /* if register bank was saved then pop them */
2523 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2525 /* if we hade saved some registers then unsave them */
2526 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2527 unsaveRegisters (ic);
2532 /*-----------------------------------------------------------------*/
2533 /* genPcall - generates a call by pointer statement */
2534 /*-----------------------------------------------------------------*/
2535 static void genPcall (iCode *ic)
2538 symbol *rlbl = newiTempLabel(NULL);
2541 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2542 /* if caller saves & we have not saved then */
2546 /* if we are calling a function that is not using
2547 the same register bank then we need to save the
2548 destination registers on the stack */
2549 dtype = operandType(IC_LEFT(ic));
2550 if (currFunc && dtype &&
2551 IFFUNC_ISISR(currFunc->type) &&
2552 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2553 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2556 /* push the return address on to the stack */
2557 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2558 pic16_emitcode("push","acc");
2559 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2560 pic16_emitcode("push","acc");
2562 if (options.model == MODEL_FLAT24)
2564 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2565 pic16_emitcode("push","acc");
2568 /* now push the calling address */
2569 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2571 pushSide(IC_LEFT(ic), FPTRSIZE);
2573 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2575 /* if send set is not empty the assign */
2579 for (sic = setFirstItem(_G.sendSet) ; sic ;
2580 sic = setNextItem(_G.sendSet)) {
2581 int size, offset = 0;
2582 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2583 size = AOP_SIZE(IC_LEFT(sic));
2585 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2587 if (strcmp(l,fReturn[offset]))
2588 pic16_emitcode("mov","%s,%s",
2593 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2598 pic16_emitcode("ret","");
2599 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2602 /* if we need assign a result value */
2603 if ((IS_ITEMP(IC_RESULT(ic)) &&
2604 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2605 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2606 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2609 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2612 assignResultValue(IC_RESULT(ic));
2614 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2617 /* adjust the stack for parameters if
2619 if (ic->parmBytes) {
2621 if (ic->parmBytes > 3) {
2622 pic16_emitcode("mov","a,%s",spname);
2623 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2624 pic16_emitcode("mov","%s,a",spname);
2626 for ( i = 0 ; i < ic->parmBytes ;i++)
2627 pic16_emitcode("dec","%s",spname);
2631 /* if register bank was saved then unsave them */
2632 if (currFunc && dtype &&
2633 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2634 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2636 /* if we hade saved some registers then
2639 unsaveRegisters (ic);
2643 /*-----------------------------------------------------------------*/
2644 /* resultRemat - result is rematerializable */
2645 /*-----------------------------------------------------------------*/
2646 static int resultRemat (iCode *ic)
2648 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2649 if (SKIP_IC(ic) || ic->op == IFX)
2652 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2653 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2654 if (sym->remat && !POINTER_SET(ic))
2661 #if defined(__BORLANDC__) || defined(_MSC_VER)
2662 #define STRCASECMP stricmp
2664 #define STRCASECMP strcasecmp
2668 /*-----------------------------------------------------------------*/
2669 /* inExcludeList - return 1 if the string is in exclude Reg list */
2670 /*-----------------------------------------------------------------*/
2671 static bool inExcludeList(char *s)
2673 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2676 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2677 if (options.excludeRegs[i] &&
2678 STRCASECMP(options.excludeRegs[i],"none") == 0)
2681 for ( i = 0 ; options.excludeRegs[i]; i++) {
2682 if (options.excludeRegs[i] &&
2683 STRCASECMP(s,options.excludeRegs[i]) == 0)
2690 /*-----------------------------------------------------------------*/
2691 /* genFunction - generated code for function entry */
2692 /*-----------------------------------------------------------------*/
2693 static void genFunction (iCode *ic)
2698 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2700 labelOffset += (max_key+4);
2704 /* create the function header */
2705 pic16_emitcode(";","-----------------------------------------");
2706 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2707 pic16_emitcode(";","-----------------------------------------");
2709 pic16_emitcode("","%s:",sym->rname);
2710 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2712 ftype = operandType(IC_LEFT(ic));
2714 /* if critical function then turn interrupts off */
2715 if (IFFUNC_ISCRITICAL(ftype))
2716 pic16_emitcode("clr","ea");
2718 /* here we need to generate the equates for the
2719 register bank if required */
2721 if (FUNC_REGBANK(ftype) != rbank) {
2724 rbank = FUNC_REGBANK(ftype);
2725 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2726 if (strcmp(regspic16[i].base,"0") == 0)
2727 pic16_emitcode("","%s = 0x%02x",
2729 8*rbank+regspic16[i].offset);
2731 pic16_emitcode ("","%s = %s + 0x%02x",
2734 8*rbank+regspic16[i].offset);
2739 /* if this is an interrupt service routine then
2740 save acc, b, dpl, dph */
2741 if (IFFUNC_ISISR(sym->type)) {
2744 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2746 /* what is the reason of having these 3 NOPS? VR - 030701 */
2747 pic16_emitpcodeNULLop(POC_NOP);
2748 pic16_emitpcodeNULLop(POC_NOP);
2749 pic16_emitpcodeNULLop(POC_NOP);
2752 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2753 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2754 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2755 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2757 pic16_pBlockConvert2ISR(pb);
2759 if (!inExcludeList("acc"))
2760 pic16_emitcode ("push","acc");
2761 if (!inExcludeList("b"))
2762 pic16_emitcode ("push","b");
2763 if (!inExcludeList("dpl"))
2764 pic16_emitcode ("push","dpl");
2765 if (!inExcludeList("dph"))
2766 pic16_emitcode ("push","dph");
2767 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2769 pic16_emitcode ("push", "dpx");
2770 /* Make sure we're using standard DPTR */
2771 pic16_emitcode ("push", "dps");
2772 pic16_emitcode ("mov", "dps, #0x00");
2773 if (options.stack10bit)
2775 /* This ISR could conceivably use DPTR2. Better save it. */
2776 pic16_emitcode ("push", "dpl1");
2777 pic16_emitcode ("push", "dph1");
2778 pic16_emitcode ("push", "dpx1");
2781 /* if this isr has no bank i.e. is going to
2782 run with bank 0 , then we need to save more
2784 if (!FUNC_REGBANK(sym->type)) {
2786 /* if this function does not call any other
2787 function then we can be economical and
2788 save only those registers that are used */
2789 if (! IFFUNC_HASFCALL(sym->type)) {
2792 /* if any registers used */
2793 if (sym->regsUsed) {
2794 /* save the registers used */
2795 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2796 if (bitVectBitValue(sym->regsUsed,i) ||
2797 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2798 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2803 /* this function has a function call cannot
2804 determines register usage so we will have the
2806 saverbank(0,ic,FALSE);
2811 /* if callee-save to be used for this function
2812 then save the registers being used in this function */
2813 if (IFFUNC_CALLEESAVES(sym->type)) {
2816 /* if any registers used */
2817 if (sym->regsUsed) {
2818 /* save the registers used */
2819 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2820 if (bitVectBitValue(sym->regsUsed,i) ||
2821 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2822 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2830 /* set the register bank to the desired value */
2831 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2832 pic16_emitcode("push","psw");
2833 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2836 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2838 if (options.useXstack) {
2839 pic16_emitcode("mov","r0,%s",spname);
2840 pic16_emitcode("mov","a,_bp");
2841 pic16_emitcode("movx","@r0,a");
2842 pic16_emitcode("inc","%s",spname);
2846 /* set up the stack */
2847 pic16_emitcode ("push","_bp"); /* save the callers stack */
2849 pic16_emitcode ("mov","_bp,%s",spname);
2852 /* adjust the stack for the function */
2857 werror(W_STACK_OVERFLOW,sym->name);
2859 if (i > 3 && sym->recvSize < 4) {
2861 pic16_emitcode ("mov","a,sp");
2862 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2863 pic16_emitcode ("mov","sp,a");
2868 pic16_emitcode("inc","sp");
2873 pic16_emitcode ("mov","a,_spx");
2874 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2875 pic16_emitcode ("mov","_spx,a");
2880 /*-----------------------------------------------------------------*/
2881 /* genEndFunction - generates epilogue for functions */
2882 /*-----------------------------------------------------------------*/
2883 static void genEndFunction (iCode *ic)
2885 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2887 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2889 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2891 pic16_emitcode ("mov","%s,_bp",spname);
2894 /* if use external stack but some variables were
2895 added to the local stack then decrement the
2897 if (options.useXstack && sym->stack) {
2898 pic16_emitcode("mov","a,sp");
2899 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2900 pic16_emitcode("mov","sp,a");
2904 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2905 if (options.useXstack) {
2906 pic16_emitcode("mov","r0,%s",spname);
2907 pic16_emitcode("movx","a,@r0");
2908 pic16_emitcode("mov","_bp,a");
2909 pic16_emitcode("dec","%s",spname);
2913 pic16_emitcode ("pop","_bp");
2917 /* restore the register bank */
2918 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2919 pic16_emitcode ("pop","psw");
2921 if (IFFUNC_ISISR(sym->type)) {
2923 /* now we need to restore the registers */
2924 /* if this isr has no bank i.e. is going to
2925 run with bank 0 , then we need to save more
2927 if (!FUNC_REGBANK(sym->type)) {
2929 /* if this function does not call any other
2930 function then we can be economical and
2931 save only those registers that are used */
2932 if (! IFFUNC_HASFCALL(sym->type)) {
2935 /* if any registers used */
2936 if (sym->regsUsed) {
2937 /* save the registers used */
2938 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2939 if (bitVectBitValue(sym->regsUsed,i) ||
2940 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2941 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2946 /* this function has a function call cannot
2947 determines register usage so we will have the
2949 unsaverbank(0,ic,FALSE);
2953 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2955 if (options.stack10bit)
2957 pic16_emitcode ("pop", "dpx1");
2958 pic16_emitcode ("pop", "dph1");
2959 pic16_emitcode ("pop", "dpl1");
2961 pic16_emitcode ("pop", "dps");
2962 pic16_emitcode ("pop", "dpx");
2964 if (!inExcludeList("dph"))
2965 pic16_emitcode ("pop","dph");
2966 if (!inExcludeList("dpl"))
2967 pic16_emitcode ("pop","dpl");
2968 if (!inExcludeList("b"))
2969 pic16_emitcode ("pop","b");
2970 if (!inExcludeList("acc"))
2971 pic16_emitcode ("pop","acc");
2973 if (IFFUNC_ISCRITICAL(sym->type))
2974 pic16_emitcode("setb","ea");
2977 /* if debug then send end of function */
2978 /* if (options.debug && currFunc) { */
2981 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2982 FileBaseName(ic->filename),currFunc->lastLine,
2983 ic->level,ic->block);
2984 if (IS_STATIC(currFunc->etype))
2985 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2987 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2991 // pic16_emitcode ("reti","");
2993 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2994 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2995 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
2996 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
2997 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
3000 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
3003 pic16_emitpcodeNULLop(POC_RETFIE);
3007 if (IFFUNC_ISCRITICAL(sym->type))
3008 pic16_emitcode("setb","ea");
3010 if (IFFUNC_CALLEESAVES(sym->type)) {
3013 /* if any registers used */
3014 if (sym->regsUsed) {
3015 /* save the registers used */
3016 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3017 if (bitVectBitValue(sym->regsUsed,i) ||
3018 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3019 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
3025 /* if debug then send end of function */
3028 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3029 FileBaseName(ic->filename),currFunc->lastLine,
3030 ic->level,ic->block);
3031 if (IS_STATIC(currFunc->etype))
3032 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3034 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3038 pic16_emitcode ("return","");
3039 pic16_emitpcodeNULLop(POC_RETURN);
3041 /* Mark the end of a function */
3042 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3047 /*-----------------------------------------------------------------*/
3048 /* genRet - generate code for return statement */
3049 /*-----------------------------------------------------------------*/
3050 static void genRet (iCode *ic)
3052 int size,offset = 0 , pushed = 0;
3054 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3055 /* if we have no return value then
3056 just generate the "ret" */
3060 /* we have something to return then
3061 move the return value into place */
3062 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3063 size = AOP_SIZE(IC_LEFT(ic));
3067 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3069 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3071 pic16_emitcode("push","%s",l);
3074 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3076 if (strcmp(fReturn[offset],l)) {
3077 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3078 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3079 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3081 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3084 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3094 if (strcmp(fReturn[pushed],"a"))
3095 pic16_emitcode("pop",fReturn[pushed]);
3097 pic16_emitcode("pop","acc");
3100 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3103 /* generate a jump to the return label
3104 if the next is not the return statement */
3105 if (!(ic->next && ic->next->op == LABEL &&
3106 IC_LABEL(ic->next) == returnLabel)) {
3108 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3109 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3114 /*-----------------------------------------------------------------*/
3115 /* genLabel - generates a label */
3116 /*-----------------------------------------------------------------*/
3117 static void genLabel (iCode *ic)
3119 /* special case never generate */
3120 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3121 if (IC_LABEL(ic) == entryLabel)
3124 pic16_emitpLabel(IC_LABEL(ic)->key);
3125 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3128 /*-----------------------------------------------------------------*/
3129 /* genGoto - generates a goto */
3130 /*-----------------------------------------------------------------*/
3132 static void genGoto (iCode *ic)
3134 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3135 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3139 /*-----------------------------------------------------------------*/
3140 /* genMultbits :- multiplication of bits */
3141 /*-----------------------------------------------------------------*/
3142 static void genMultbits (operand *left,
3146 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3148 if(!pic16_sameRegs(AOP(result),AOP(right)))
3149 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3151 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3152 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3153 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3158 /*-----------------------------------------------------------------*/
3159 /* genMultOneByte : 8 bit multiplication & division */
3160 /*-----------------------------------------------------------------*/
3161 static void genMultOneByte (operand *left,
3165 sym_link *opetype = operandType(result);
3170 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3171 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3172 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3174 /* (if two literals, the value is computed before) */
3175 /* if one literal, literal on the right */
3176 if (AOP_TYPE(left) == AOP_LIT){
3182 size = AOP_SIZE(result);
3185 if (AOP_TYPE(right) == AOP_LIT){
3186 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3187 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3188 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3189 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3190 pic16_emitcode("call","genMultLit");
3192 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3193 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3194 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3195 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3196 pic16_emitcode("call","pic16_genMult8X8_8");
3199 pic16_genMult8X8_8 (left, right,result);
3202 /* signed or unsigned */
3203 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3204 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3206 //pic16_emitcode("mul","ab");
3207 /* if result size = 1, mul signed = mul unsigned */
3208 //pic16_aopPut(AOP(result),"a",0);
3210 } else { // (size > 1)
3212 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3213 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3214 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3215 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3217 if (SPEC_USIGN(opetype)){
3218 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3219 pic16_genUMult8X8_16 (left, right, result, NULL);
3222 /* for filling the MSBs */
3223 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3224 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3228 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3230 pic16_emitcode("mov","a,b");
3232 /* adjust the MSB if left or right neg */
3234 /* if one literal */
3235 if (AOP_TYPE(right) == AOP_LIT){
3236 pic16_emitcode("multiply ","right is a lit");
3237 /* AND literal negative */
3238 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3239 /* adjust MSB (c==0 after mul) */
3240 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3244 pic16_genSMult8X8_16 (left, right, result, NULL);
3248 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3250 pic16_emitcode("rlc","a");
3251 pic16_emitcode("subb","a,acc");
3259 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3260 //pic16_aopPut(AOP(result),"a",offset++);
3264 /*-----------------------------------------------------------------*/
3265 /* genMult - generates code for multiplication */
3266 /*-----------------------------------------------------------------*/
3267 static void genMult (iCode *ic)
3269 operand *left = IC_LEFT(ic);
3270 operand *right = IC_RIGHT(ic);
3271 operand *result= IC_RESULT(ic);
3273 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3274 /* assign the amsops */
3275 pic16_aopOp (left,ic,FALSE);
3276 pic16_aopOp (right,ic,FALSE);
3277 pic16_aopOp (result,ic,TRUE);
3279 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3281 /* special cases first */
3283 if (AOP_TYPE(left) == AOP_CRY &&
3284 AOP_TYPE(right)== AOP_CRY) {
3285 genMultbits(left,right,result);
3289 /* if both are of size == 1 */
3290 if (AOP_SIZE(left) == 1 &&
3291 AOP_SIZE(right) == 1 ) {
3292 genMultOneByte(left,right,result);
3296 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3298 /* should have been converted to function call */
3302 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3303 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3304 pic16_freeAsmop(result,NULL,ic,TRUE);
3307 /*-----------------------------------------------------------------*/
3308 /* genDivbits :- division of bits */
3309 /*-----------------------------------------------------------------*/
3310 static void genDivbits (operand *left,
3317 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3318 /* the result must be bit */
3319 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3320 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3324 pic16_emitcode("div","ab");
3325 pic16_emitcode("rrc","a");
3326 pic16_aopPut(AOP(result),"c",0);
3329 /*-----------------------------------------------------------------*/
3330 /* genDivOneByte : 8 bit division */
3331 /*-----------------------------------------------------------------*/
3332 static void genDivOneByte (operand *left,
3336 sym_link *opetype = operandType(result);
3341 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3342 size = AOP_SIZE(result) - 1;
3344 /* signed or unsigned */
3345 if (SPEC_USIGN(opetype)) {
3346 /* unsigned is easy */
3347 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3348 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3350 pic16_emitcode("div","ab");
3351 pic16_aopPut(AOP(result),"a",0);
3353 pic16_aopPut(AOP(result),zero,offset++);
3357 /* signed is a little bit more difficult */
3359 /* save the signs of the operands */
3360 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3362 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3363 pic16_emitcode("push","acc"); /* save it on the stack */
3365 /* now sign adjust for both left & right */
3366 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3368 lbl = newiTempLabel(NULL);
3369 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3370 pic16_emitcode("cpl","a");
3371 pic16_emitcode("inc","a");
3372 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3373 pic16_emitcode("mov","b,a");
3375 /* sign adjust left side */
3376 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3379 lbl = newiTempLabel(NULL);
3380 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3381 pic16_emitcode("cpl","a");
3382 pic16_emitcode("inc","a");
3383 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3385 /* now the division */
3386 pic16_emitcode("div","ab");
3387 /* we are interested in the lower order
3389 pic16_emitcode("mov","b,a");
3390 lbl = newiTempLabel(NULL);
3391 pic16_emitcode("pop","acc");
3392 /* if there was an over flow we don't
3393 adjust the sign of the result */
3394 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3395 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3397 pic16_emitcode("clr","a");
3398 pic16_emitcode("subb","a,b");
3399 pic16_emitcode("mov","b,a");
3400 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3402 /* now we are done */
3403 pic16_aopPut(AOP(result),"b",0);
3405 pic16_emitcode("mov","c,b.7");
3406 pic16_emitcode("subb","a,acc");
3409 pic16_aopPut(AOP(result),"a",offset++);
3413 /*-----------------------------------------------------------------*/
3414 /* genDiv - generates code for division */
3415 /*-----------------------------------------------------------------*/
3416 static void genDiv (iCode *ic)
3418 operand *left = IC_LEFT(ic);
3419 operand *right = IC_RIGHT(ic);
3420 operand *result= IC_RESULT(ic);
3422 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3423 /* assign the amsops */
3424 pic16_aopOp (left,ic,FALSE);
3425 pic16_aopOp (right,ic,FALSE);
3426 pic16_aopOp (result,ic,TRUE);
3428 /* special cases first */
3430 if (AOP_TYPE(left) == AOP_CRY &&
3431 AOP_TYPE(right)== AOP_CRY) {
3432 genDivbits(left,right,result);
3436 /* if both are of size == 1 */
3437 if (AOP_SIZE(left) == 1 &&
3438 AOP_SIZE(right) == 1 ) {
3439 genDivOneByte(left,right,result);
3443 /* should have been converted to function call */
3446 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3447 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3448 pic16_freeAsmop(result,NULL,ic,TRUE);
3451 /*-----------------------------------------------------------------*/
3452 /* genModbits :- modulus of bits */
3453 /*-----------------------------------------------------------------*/
3454 static void genModbits (operand *left,
3461 /* the result must be bit */
3462 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3463 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3467 pic16_emitcode("div","ab");
3468 pic16_emitcode("mov","a,b");
3469 pic16_emitcode("rrc","a");
3470 pic16_aopPut(AOP(result),"c",0);
3473 /*-----------------------------------------------------------------*/
3474 /* genModOneByte : 8 bit modulus */
3475 /*-----------------------------------------------------------------*/
3476 static void genModOneByte (operand *left,
3480 sym_link *opetype = operandType(result);
3484 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3485 /* signed or unsigned */
3486 if (SPEC_USIGN(opetype)) {
3487 /* unsigned is easy */
3488 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3489 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3491 pic16_emitcode("div","ab");
3492 pic16_aopPut(AOP(result),"b",0);
3496 /* signed is a little bit more difficult */
3498 /* save the signs of the operands */
3499 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3502 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3503 pic16_emitcode("push","acc"); /* save it on the stack */
3505 /* now sign adjust for both left & right */
3506 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3509 lbl = newiTempLabel(NULL);
3510 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3511 pic16_emitcode("cpl","a");
3512 pic16_emitcode("inc","a");
3513 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3514 pic16_emitcode("mov","b,a");
3516 /* sign adjust left side */
3517 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3520 lbl = newiTempLabel(NULL);
3521 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3522 pic16_emitcode("cpl","a");
3523 pic16_emitcode("inc","a");
3524 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3526 /* now the multiplication */
3527 pic16_emitcode("div","ab");
3528 /* we are interested in the lower order
3530 lbl = newiTempLabel(NULL);
3531 pic16_emitcode("pop","acc");
3532 /* if there was an over flow we don't
3533 adjust the sign of the result */
3534 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3535 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3537 pic16_emitcode("clr","a");
3538 pic16_emitcode("subb","a,b");
3539 pic16_emitcode("mov","b,a");
3540 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3542 /* now we are done */
3543 pic16_aopPut(AOP(result),"b",0);
3547 /*-----------------------------------------------------------------*/
3548 /* genMod - generates code for division */
3549 /*-----------------------------------------------------------------*/
3550 static void genMod (iCode *ic)
3552 operand *left = IC_LEFT(ic);
3553 operand *right = IC_RIGHT(ic);
3554 operand *result= IC_RESULT(ic);
3556 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3557 /* assign the amsops */
3558 pic16_aopOp (left,ic,FALSE);
3559 pic16_aopOp (right,ic,FALSE);
3560 pic16_aopOp (result,ic,TRUE);
3562 /* special cases first */
3564 if (AOP_TYPE(left) == AOP_CRY &&
3565 AOP_TYPE(right)== AOP_CRY) {
3566 genModbits(left,right,result);
3570 /* if both are of size == 1 */
3571 if (AOP_SIZE(left) == 1 &&
3572 AOP_SIZE(right) == 1 ) {
3573 genModOneByte(left,right,result);
3577 /* should have been converted to function call */
3581 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3582 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3583 pic16_freeAsmop(result,NULL,ic,TRUE);
3586 /*-----------------------------------------------------------------*/
3587 /* genIfxJump :- will create a jump depending on the ifx */
3588 /*-----------------------------------------------------------------*/
3590 note: May need to add parameter to indicate when a variable is in bit space.
3592 static void genIfxJump (iCode *ic, char *jval)
3595 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3596 /* if true label then we jump if condition
3598 if ( IC_TRUE(ic) ) {
3600 if(strcmp(jval,"a") == 0)
3602 else if (strcmp(jval,"c") == 0)
3605 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3606 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3609 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3610 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3614 /* false label is present */
3615 if(strcmp(jval,"a") == 0)
3617 else if (strcmp(jval,"c") == 0)
3620 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3621 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3624 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3625 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3630 /* mark the icode as generated */
3634 /*-----------------------------------------------------------------*/
3636 /*-----------------------------------------------------------------*/
3637 static void genSkip(iCode *ifx,int status_bit)
3642 if ( IC_TRUE(ifx) ) {
3643 switch(status_bit) {
3658 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3659 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3663 switch(status_bit) {
3677 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3678 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3684 /*-----------------------------------------------------------------*/
3686 /*-----------------------------------------------------------------*/
3687 static void genSkipc(resolvedIfx *rifx)
3697 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3698 rifx->generated = 1;
3701 /*-----------------------------------------------------------------*/
3703 /*-----------------------------------------------------------------*/
3704 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3709 if( (rifx->condition ^ invert_condition) & 1)
3714 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3715 rifx->generated = 1;
3718 /*-----------------------------------------------------------------*/
3720 /*-----------------------------------------------------------------*/
3721 static void genSkipz(iCode *ifx, int condition)
3732 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3734 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3737 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3739 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3742 /*-----------------------------------------------------------------*/
3744 /*-----------------------------------------------------------------*/
3745 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3751 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3753 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3756 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3757 rifx->generated = 1;
3761 /*-----------------------------------------------------------------*/
3762 /* genChkZeroes :- greater or less than comparison */
3763 /* For each byte in a literal that is zero, inclusive or the */
3764 /* the corresponding byte in the operand with W */
3765 /* returns true if any of the bytes are zero */
3766 /*-----------------------------------------------------------------*/
3767 static int genChkZeroes(operand *op, int lit, int size)
3774 i = (lit >> (size*8)) & 0xff;
3778 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3780 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3789 /*-----------------------------------------------------------------*/
3790 /* genCmp :- greater or less than comparison */
3791 /*-----------------------------------------------------------------*/
3792 static void genCmp (operand *left,operand *right,
3793 operand *result, iCode *ifx, int sign)
3795 int size; //, offset = 0 ;
3796 unsigned long lit = 0L,i = 0;
3797 resolvedIfx rFalseIfx;
3798 // resolvedIfx rTrueIfx;
3800 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3803 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3804 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3808 resolveIfx(&rFalseIfx,ifx);
3809 truelbl = newiTempLabel(NULL);
3810 size = max(AOP_SIZE(left),AOP_SIZE(right));
3812 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3816 /* if literal is on the right then swap with left */
3817 if ((AOP_TYPE(right) == AOP_LIT)) {
3818 operand *tmp = right ;
3819 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3820 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3823 lit = (lit - 1) & mask;
3826 rFalseIfx.condition ^= 1;
3829 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3830 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3834 //if(IC_TRUE(ifx) == NULL)
3835 /* if left & right are bit variables */
3836 if (AOP_TYPE(left) == AOP_CRY &&
3837 AOP_TYPE(right) == AOP_CRY ) {
3838 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3839 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3841 /* subtract right from left if at the
3842 end the carry flag is set then we know that
3843 left is greater than right */
3847 symbol *lbl = newiTempLabel(NULL);
3850 if(AOP_TYPE(right) == AOP_LIT) {
3852 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3854 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3861 genSkipCond(&rFalseIfx,left,size-1,7);
3863 /* no need to compare to 0...*/
3864 /* NOTE: this is a de-generate compare that most certainly
3865 * creates some dead code. */
3866 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3868 if(ifx) ifx->generated = 1;
3875 //i = (lit >> (size*8)) & 0xff;
3876 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3878 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3880 i = ((0-lit) & 0xff);
3883 /* lit is 0x7f, all signed chars are less than
3884 * this except for 0x7f itself */
3885 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3886 genSkipz2(&rFalseIfx,0);
3888 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3889 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3890 genSkipc(&rFalseIfx);
3895 genSkipz2(&rFalseIfx,1);
3897 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3898 genSkipc(&rFalseIfx);
3902 if(ifx) ifx->generated = 1;
3906 /* chars are out of the way. now do ints and longs */
3909 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3916 genSkipCond(&rFalseIfx,left,size,7);
3917 if(ifx) ifx->generated = 1;
3922 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3924 //rFalseIfx.condition ^= 1;
3925 //genSkipCond(&rFalseIfx,left,size,7);
3926 //rFalseIfx.condition ^= 1;
3928 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3929 if(rFalseIfx.condition)
3930 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3932 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3934 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3935 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3936 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3939 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3941 if(rFalseIfx.condition) {
3943 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3949 genSkipc(&rFalseIfx);
3950 pic16_emitpLabel(truelbl->key);
3951 if(ifx) ifx->generated = 1;
3958 if( (lit & 0xff) == 0) {
3959 /* lower byte is zero */
3960 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3961 i = ((lit >> 8) & 0xff) ^0x80;
3962 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3963 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3964 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3965 genSkipc(&rFalseIfx);
3968 if(ifx) ifx->generated = 1;
3973 /* Special cases for signed longs */
3974 if( (lit & 0xffffff) == 0) {
3975 /* lower byte is zero */
3976 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3977 i = ((lit >> 8*3) & 0xff) ^0x80;
3978 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3979 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3980 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3981 genSkipc(&rFalseIfx);
3984 if(ifx) ifx->generated = 1;
3992 if(lit & (0x80 << (size*8))) {
3993 /* lit is negative */
3994 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3996 //genSkipCond(&rFalseIfx,left,size,7);
3998 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4000 if(rFalseIfx.condition)
4001 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4003 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4007 /* lit is positive */
4008 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
4009 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
4010 if(rFalseIfx.condition)
4011 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4013 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4018 This works, but is only good for ints.
4019 It also requires a "known zero" register.
4020 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4021 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4022 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4023 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4024 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4025 genSkipc(&rFalseIfx);
4027 pic16_emitpLabel(truelbl->key);
4028 if(ifx) ifx->generated = 1;
4032 /* There are no more special cases, so perform a general compare */
4034 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4035 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4039 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4041 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4043 //rFalseIfx.condition ^= 1;
4044 genSkipc(&rFalseIfx);
4046 pic16_emitpLabel(truelbl->key);
4048 if(ifx) ifx->generated = 1;
4055 /* sign is out of the way. So now do an unsigned compare */
4056 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4059 /* General case - compare to an unsigned literal on the right.*/
4061 i = (lit >> (size*8)) & 0xff;
4062 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4063 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4065 i = (lit >> (size*8)) & 0xff;
4068 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4070 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4072 /* this byte of the lit is zero,
4073 *if it's not the last then OR in the variable */
4075 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4080 pic16_emitpLabel(lbl->key);
4081 //if(emitFinalCheck)
4082 genSkipc(&rFalseIfx);
4084 pic16_emitpLabel(truelbl->key);
4086 if(ifx) ifx->generated = 1;
4093 if(AOP_TYPE(left) == AOP_LIT) {
4094 //symbol *lbl = newiTempLabel(NULL);
4096 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4099 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4102 if((lit == 0) && (sign == 0)){
4105 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4107 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4109 genSkipz2(&rFalseIfx,0);
4110 if(ifx) ifx->generated = 1;
4117 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4118 /* degenerate compare can never be true */
4119 if(rFalseIfx.condition == 0)
4120 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4122 if(ifx) ifx->generated = 1;
4127 /* signed comparisons to a literal byte */
4129 int lp1 = (lit+1) & 0xff;
4131 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4134 rFalseIfx.condition ^= 1;
4135 genSkipCond(&rFalseIfx,right,0,7);
4138 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4139 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4140 genSkipz2(&rFalseIfx,1);
4143 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4144 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4145 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4146 rFalseIfx.condition ^= 1;
4147 genSkipc(&rFalseIfx);
4151 /* unsigned comparisons to a literal byte */
4153 switch(lit & 0xff ) {
4155 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4156 genSkipz2(&rFalseIfx,0);
4159 rFalseIfx.condition ^= 1;
4160 genSkipCond(&rFalseIfx,right,0,7);
4164 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4165 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4166 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4167 rFalseIfx.condition ^= 1;
4168 if (AOP_TYPE(result) == AOP_CRY)
4169 genSkipc(&rFalseIfx);
4171 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4172 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4178 if(ifx) ifx->generated = 1;
4184 /* Size is greater than 1 */
4192 /* this means lit = 0xffffffff, or -1 */
4195 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4196 rFalseIfx.condition ^= 1;
4197 genSkipCond(&rFalseIfx,right,size,7);
4198 if(ifx) ifx->generated = 1;
4205 if(rFalseIfx.condition) {
4206 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4207 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4210 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4212 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4216 if(rFalseIfx.condition) {
4217 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4218 pic16_emitpLabel(truelbl->key);
4220 rFalseIfx.condition ^= 1;
4221 genSkipCond(&rFalseIfx,right,s,7);
4224 if(ifx) ifx->generated = 1;
4228 if((size == 1) && (0 == (lp1&0xff))) {
4229 /* lower byte of signed word is zero */
4230 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4231 i = ((lp1 >> 8) & 0xff) ^0x80;
4232 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4233 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4234 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4235 rFalseIfx.condition ^= 1;
4236 genSkipc(&rFalseIfx);
4239 if(ifx) ifx->generated = 1;
4243 if(lit & (0x80 << (size*8))) {
4244 /* Lit is less than zero */
4245 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4246 //rFalseIfx.condition ^= 1;
4247 //genSkipCond(&rFalseIfx,left,size,7);
4248 //rFalseIfx.condition ^= 1;
4249 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4250 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4252 if(rFalseIfx.condition)
4253 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4255 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4259 /* Lit is greater than or equal to zero */
4260 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4261 //rFalseIfx.condition ^= 1;
4262 //genSkipCond(&rFalseIfx,right,size,7);
4263 //rFalseIfx.condition ^= 1;
4265 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4266 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4268 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4269 if(rFalseIfx.condition)
4270 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4272 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4277 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4278 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4282 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4284 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4286 rFalseIfx.condition ^= 1;
4287 //rFalseIfx.condition = 1;
4288 genSkipc(&rFalseIfx);
4290 pic16_emitpLabel(truelbl->key);
4292 if(ifx) ifx->generated = 1;
4297 /* compare word or long to an unsigned literal on the right.*/
4302 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4305 break; /* handled above */
4308 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4310 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4311 genSkipz2(&rFalseIfx,0);
4315 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4317 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4320 if(rFalseIfx.condition)
4321 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4323 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4326 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4327 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4329 rFalseIfx.condition ^= 1;
4330 genSkipc(&rFalseIfx);
4333 pic16_emitpLabel(truelbl->key);
4335 if(ifx) ifx->generated = 1;
4341 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4342 i = (lit >> (size*8)) & 0xff;
4344 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4345 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4348 i = (lit >> (size*8)) & 0xff;
4351 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4353 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4355 /* this byte of the lit is zero,
4356 *if it's not the last then OR in the variable */
4358 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4363 pic16_emitpLabel(lbl->key);
4365 rFalseIfx.condition ^= 1;
4366 genSkipc(&rFalseIfx);
4370 pic16_emitpLabel(truelbl->key);
4371 if(ifx) ifx->generated = 1;
4375 /* Compare two variables */
4377 DEBUGpic16_emitcode(";sign","%d",sign);
4381 /* Sigh. thus sucks... */
4383 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4384 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4385 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4386 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4387 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4388 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4390 /* Signed char comparison */
4391 /* Special thanks to Nikolai Golovchenko for this snippet */
4392 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4393 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4394 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4395 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4396 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4397 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4399 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4400 genSkipc(&rFalseIfx);
4402 if(ifx) ifx->generated = 1;
4408 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4409 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4413 /* The rest of the bytes of a multi-byte compare */
4417 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4420 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4421 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4426 pic16_emitpLabel(lbl->key);
4428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4429 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4430 (AOP_TYPE(result) == AOP_REG)) {
4431 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4432 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4434 genSkipc(&rFalseIfx);
4436 //genSkipc(&rFalseIfx);
4437 if(ifx) ifx->generated = 1;
4444 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4445 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4446 pic16_outBitC(result);
4448 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4449 /* if the result is used in the next
4450 ifx conditional branch then generate
4451 code a little differently */
4453 genIfxJump (ifx,"c");
4455 pic16_outBitC(result);
4456 /* leave the result in acc */
4461 /*-----------------------------------------------------------------*/
4462 /* genCmpGt :- greater than comparison */
4463 /*-----------------------------------------------------------------*/
4464 static void genCmpGt (iCode *ic, iCode *ifx)
4466 operand *left, *right, *result;
4467 sym_link *letype , *retype;
4470 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4472 right= IC_RIGHT(ic);
4473 result = IC_RESULT(ic);
4475 letype = getSpec(operandType(left));
4476 retype =getSpec(operandType(right));
4477 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4478 /* assign the amsops */
4479 pic16_aopOp (left,ic,FALSE);
4480 pic16_aopOp (right,ic,FALSE);
4481 pic16_aopOp (result,ic,TRUE);
4483 genCmp(right, left, result, ifx, sign);
4485 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4486 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4487 pic16_freeAsmop(result,NULL,ic,TRUE);
4490 /*-----------------------------------------------------------------*/
4491 /* genCmpLt - less than comparisons */
4492 /*-----------------------------------------------------------------*/
4493 static void genCmpLt (iCode *ic, iCode *ifx)
4495 operand *left, *right, *result;
4496 sym_link *letype , *retype;
4499 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4501 right= IC_RIGHT(ic);
4502 result = IC_RESULT(ic);
4504 letype = getSpec(operandType(left));
4505 retype =getSpec(operandType(right));
4506 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4508 /* assign the amsops */
4509 pic16_aopOp (left,ic,FALSE);
4510 pic16_aopOp (right,ic,FALSE);
4511 pic16_aopOp (result,ic,TRUE);
4513 genCmp(left, right, result, ifx, sign);
4515 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4516 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4517 pic16_freeAsmop(result,NULL,ic,TRUE);
4520 /*-----------------------------------------------------------------*/
4521 /* genc16bit2lit - compare a 16 bit value to a literal */
4522 /*-----------------------------------------------------------------*/
4523 static void genc16bit2lit(operand *op, int lit, int offset)
4527 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4528 if( (lit&0xff) == 0)
4533 switch( BYTEofLONG(lit,i)) {
4535 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4538 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4541 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4544 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4545 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4550 switch( BYTEofLONG(lit,i)) {
4552 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4556 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4560 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4563 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4565 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4571 /*-----------------------------------------------------------------*/
4572 /* gencjneshort - compare and jump if not equal */
4573 /*-----------------------------------------------------------------*/
4574 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4576 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4578 int res_offset = 0; /* the result may be a different size then left or right */
4579 int res_size = AOP_SIZE(result);
4583 unsigned long lit = 0L;
4584 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4585 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4587 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4588 resolveIfx(&rIfx,ifx);
4589 lbl = newiTempLabel(NULL);
4592 /* if the left side is a literal or
4593 if the right is in a pointer register and left
4595 if ((AOP_TYPE(left) == AOP_LIT) ||
4596 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4601 if(AOP_TYPE(right) == AOP_LIT)
4602 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4604 /* if the right side is a literal then anything goes */
4605 if (AOP_TYPE(right) == AOP_LIT &&
4606 AOP_TYPE(left) != AOP_DIR ) {
4609 genc16bit2lit(left, lit, 0);
4611 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4616 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4617 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4619 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4623 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4625 if(res_offset < res_size-1)
4633 /* if the right side is in a register or in direct space or
4634 if the left is a pointer register & right is not */
4635 else if (AOP_TYPE(right) == AOP_REG ||
4636 AOP_TYPE(right) == AOP_DIR ||
4637 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4638 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4639 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4640 int lbl_key = lbl->key;
4643 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4644 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4646 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4647 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4648 __FUNCTION__,__LINE__);
4652 /* switch(size) { */
4654 /* genc16bit2lit(left, lit, 0); */
4656 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4661 if((AOP_TYPE(left) == AOP_DIR) &&
4662 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4664 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4665 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4667 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4669 switch (lit & 0xff) {
4671 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4674 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4675 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4676 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4680 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4681 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4682 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4683 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4687 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4688 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4693 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4696 if(AOP_TYPE(result) == AOP_CRY) {
4697 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4702 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4704 /* fix me. probably need to check result size too */
4705 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4710 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4711 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4718 if(res_offset < res_size-1)
4723 } else if(AOP_TYPE(right) == AOP_REG &&
4724 AOP_TYPE(left) != AOP_DIR){
4727 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4728 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4729 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4734 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4736 if(res_offset < res_size-1)
4741 /* right is a pointer reg need both a & b */
4743 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4745 pic16_emitcode("mov","b,%s",l);
4746 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4747 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4752 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4754 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4756 pic16_emitpLabel(lbl->key);
4758 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4765 /*-----------------------------------------------------------------*/
4766 /* gencjne - compare and jump if not equal */
4767 /*-----------------------------------------------------------------*/
4768 static void gencjne(operand *left, operand *right, iCode *ifx)
4770 symbol *tlbl = newiTempLabel(NULL);
4772 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4773 gencjneshort(left, right, lbl);
4775 pic16_emitcode("mov","a,%s",one);
4776 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4777 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4778 pic16_emitcode("clr","a");
4779 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4781 pic16_emitpLabel(lbl->key);
4782 pic16_emitpLabel(tlbl->key);
4787 /*-----------------------------------------------------------------*/
4788 /* genCmpEq - generates code for equal to */
4789 /*-----------------------------------------------------------------*/
4790 static void genCmpEq (iCode *ic, iCode *ifx)
4792 operand *left, *right, *result;
4793 unsigned long lit = 0L;
4796 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4799 DEBUGpic16_emitcode ("; ifx is non-null","");
4801 DEBUGpic16_emitcode ("; ifx is null","");
4803 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4804 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4805 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4807 size = max(AOP_SIZE(left),AOP_SIZE(right));
4809 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4811 /* if literal, literal on the right or
4812 if the right is in a pointer register and left
4814 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4815 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4816 operand *tmp = right ;
4822 if(ifx && !AOP_SIZE(result)){
4824 /* if they are both bit variables */
4825 if (AOP_TYPE(left) == AOP_CRY &&
4826 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4827 if(AOP_TYPE(right) == AOP_LIT){
4828 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4830 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4831 pic16_emitcode("cpl","c");
4832 } else if(lit == 1L) {
4833 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4835 pic16_emitcode("clr","c");
4837 /* AOP_TYPE(right) == AOP_CRY */
4839 symbol *lbl = newiTempLabel(NULL);
4840 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4841 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4842 pic16_emitcode("cpl","c");
4843 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4845 /* if true label then we jump if condition
4847 tlbl = newiTempLabel(NULL);
4848 if ( IC_TRUE(ifx) ) {
4849 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4850 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4852 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4853 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4855 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4858 /* left and right are both bit variables, result is carry */
4861 resolveIfx(&rIfx,ifx);
4863 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4864 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4865 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4866 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4871 /* They're not both bit variables. Is the right a literal? */
4872 if(AOP_TYPE(right) == AOP_LIT) {
4873 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4878 switch(lit & 0xff) {
4880 if ( IC_TRUE(ifx) ) {
4881 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4883 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4885 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4886 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4890 if ( IC_TRUE(ifx) ) {
4891 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4893 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4895 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4896 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4900 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4902 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4907 /* end of size == 1 */
4911 genc16bit2lit(left,lit,offset);
4914 /* end of size == 2 */
4919 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4920 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4921 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4922 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4926 /* search for patterns that can be optimized */
4928 genc16bit2lit(left,lit,0);
4931 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4933 genc16bit2lit(left,lit,2);
4935 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4936 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4949 } else if(AOP_TYPE(right) == AOP_CRY ) {
4950 /* we know the left is not a bit, but that the right is */
4951 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4952 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4953 pic16_popGet(AOP(right),offset));
4954 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4956 /* if the two are equal, then W will be 0 and the Z bit is set
4957 * we could test Z now, or go ahead and check the high order bytes if
4958 * the variable we're comparing is larger than a byte. */
4961 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4963 if ( IC_TRUE(ifx) ) {
4965 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4966 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4969 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4970 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4974 /* They're both variables that are larger than bits */
4977 tlbl = newiTempLabel(NULL);
4980 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4981 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4983 if ( IC_TRUE(ifx) ) {
4986 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4987 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4990 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4991 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4995 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4996 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
5000 if(s>1 && IC_TRUE(ifx)) {
5001 pic16_emitpLabel(tlbl->key);
5002 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
5006 /* mark the icode as generated */
5011 /* if they are both bit variables */
5012 if (AOP_TYPE(left) == AOP_CRY &&
5013 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5014 if(AOP_TYPE(right) == AOP_LIT){
5015 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5017 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5018 pic16_emitcode("cpl","c");
5019 } else if(lit == 1L) {
5020 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5022 pic16_emitcode("clr","c");
5024 /* AOP_TYPE(right) == AOP_CRY */
5026 symbol *lbl = newiTempLabel(NULL);
5027 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5028 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5029 pic16_emitcode("cpl","c");
5030 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5033 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5034 pic16_outBitC(result);
5038 genIfxJump (ifx,"c");
5041 /* if the result is used in an arithmetic operation
5042 then put the result in place */
5043 pic16_outBitC(result);
5046 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5047 gencjne(left,right,result,ifx);
5050 gencjne(left,right,newiTempLabel(NULL));
5052 if(IC_TRUE(ifx)->key)
5053 gencjne(left,right,IC_TRUE(ifx)->key);
5055 gencjne(left,right,IC_FALSE(ifx)->key);
5059 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5060 pic16_aopPut(AOP(result),"a",0);
5065 genIfxJump (ifx,"a");
5069 /* if the result is used in an arithmetic operation
5070 then put the result in place */
5072 if (AOP_TYPE(result) != AOP_CRY)
5073 pic16_outAcc(result);
5075 /* leave the result in acc */
5079 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5080 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5081 pic16_freeAsmop(result,NULL,ic,TRUE);
5084 /*-----------------------------------------------------------------*/
5085 /* ifxForOp - returns the icode containing the ifx for operand */
5086 /*-----------------------------------------------------------------*/
5087 static iCode *ifxForOp ( operand *op, iCode *ic )
5089 /* if true symbol then needs to be assigned */
5090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5091 if (IS_TRUE_SYMOP(op))
5094 /* if this has register type condition and
5095 the next instruction is ifx with the same operand
5096 and live to of the operand is upto the ifx only then */
5098 ic->next->op == IFX &&
5099 IC_COND(ic->next)->key == op->key &&
5100 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5104 ic->next->op == IFX &&
5105 IC_COND(ic->next)->key == op->key) {
5106 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5110 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5112 ic->next->op == IFX)
5113 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5116 ic->next->op == IFX &&
5117 IC_COND(ic->next)->key == op->key) {
5118 DEBUGpic16_emitcode ("; "," key is okay");
5119 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5120 OP_SYMBOL(op)->liveTo,
5127 /*-----------------------------------------------------------------*/
5128 /* genAndOp - for && operation */
5129 /*-----------------------------------------------------------------*/
5130 static void genAndOp (iCode *ic)
5132 operand *left,*right, *result;
5135 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5136 /* note here that && operations that are in an
5137 if statement are taken away by backPatchLabels
5138 only those used in arthmetic operations remain */
5139 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5140 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5141 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5143 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5145 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5146 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5147 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5149 /* if both are bit variables */
5150 /* if (AOP_TYPE(left) == AOP_CRY && */
5151 /* AOP_TYPE(right) == AOP_CRY ) { */
5152 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5153 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5154 /* pic16_outBitC(result); */
5156 /* tlbl = newiTempLabel(NULL); */
5157 /* pic16_toBoolean(left); */
5158 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5159 /* pic16_toBoolean(right); */
5160 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5161 /* pic16_outBitAcc(result); */
5164 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5165 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5166 pic16_freeAsmop(result,NULL,ic,TRUE);
5170 /*-----------------------------------------------------------------*/
5171 /* genOrOp - for || operation */
5172 /*-----------------------------------------------------------------*/
5175 modified this code, but it doesn't appear to ever get called
5178 static void genOrOp (iCode *ic)
5180 operand *left,*right, *result;
5183 /* note here that || operations that are in an
5184 if statement are taken away by backPatchLabels
5185 only those used in arthmetic operations remain */
5186 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5187 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5188 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5189 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5191 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5193 /* if both are bit variables */
5194 if (AOP_TYPE(left) == AOP_CRY &&
5195 AOP_TYPE(right) == AOP_CRY ) {
5196 pic16_emitcode("clrc","");
5197 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5198 AOP(left)->aopu.aop_dir,
5199 AOP(left)->aopu.aop_dir);
5200 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5201 AOP(right)->aopu.aop_dir,
5202 AOP(right)->aopu.aop_dir);
5203 pic16_emitcode("setc","");
5206 tlbl = newiTempLabel(NULL);
5207 pic16_toBoolean(left);
5209 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5210 pic16_toBoolean(right);
5211 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5213 pic16_outBitAcc(result);
5216 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5217 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5218 pic16_freeAsmop(result,NULL,ic,TRUE);
5221 /*-----------------------------------------------------------------*/
5222 /* isLiteralBit - test if lit == 2^n */
5223 /*-----------------------------------------------------------------*/
5224 static int isLiteralBit(unsigned long lit)
5226 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5227 0x100L,0x200L,0x400L,0x800L,
5228 0x1000L,0x2000L,0x4000L,0x8000L,
5229 0x10000L,0x20000L,0x40000L,0x80000L,
5230 0x100000L,0x200000L,0x400000L,0x800000L,
5231 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5232 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5235 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5236 for(idx = 0; idx < 32; idx++)
5242 /*-----------------------------------------------------------------*/
5243 /* continueIfTrue - */
5244 /*-----------------------------------------------------------------*/
5245 static void continueIfTrue (iCode *ic)
5247 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5249 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5253 /*-----------------------------------------------------------------*/
5255 /*-----------------------------------------------------------------*/
5256 static void jumpIfTrue (iCode *ic)
5258 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5260 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5264 /*-----------------------------------------------------------------*/
5265 /* jmpTrueOrFalse - */
5266 /*-----------------------------------------------------------------*/
5267 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5269 // ugly but optimized by peephole
5270 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5272 symbol *nlbl = newiTempLabel(NULL);
5273 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5274 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5275 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5276 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5279 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5280 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5285 /*-----------------------------------------------------------------*/
5286 /* genAnd - code for and */
5287 /*-----------------------------------------------------------------*/
5288 static void genAnd (iCode *ic, iCode *ifx)
5290 operand *left, *right, *result;
5292 unsigned long lit = 0L;
5297 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5298 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5299 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5300 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5302 resolveIfx(&rIfx,ifx);
5304 /* if left is a literal & right is not then exchange them */
5305 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5306 AOP_NEEDSACC(left)) {
5307 operand *tmp = right ;
5312 /* if result = right then exchange them */
5313 if(pic16_sameRegs(AOP(result),AOP(right))){
5314 operand *tmp = right ;
5319 /* if right is bit then exchange them */
5320 if (AOP_TYPE(right) == AOP_CRY &&
5321 AOP_TYPE(left) != AOP_CRY){
5322 operand *tmp = right ;
5326 if(AOP_TYPE(right) == AOP_LIT)
5327 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5329 size = AOP_SIZE(result);
5331 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5334 // result = bit & yy;
5335 if (AOP_TYPE(left) == AOP_CRY){
5336 // c = bit & literal;
5337 if(AOP_TYPE(right) == AOP_LIT){
5339 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5342 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5345 if(size && (AOP_TYPE(result) == AOP_CRY)){
5346 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5349 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5353 pic16_emitcode("clr","c");
5356 if (AOP_TYPE(right) == AOP_CRY){
5358 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5359 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5362 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5364 pic16_emitcode("rrc","a");
5365 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5371 pic16_outBitC(result);
5373 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5374 genIfxJump(ifx, "c");
5378 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5379 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5380 if((AOP_TYPE(right) == AOP_LIT) &&
5381 (AOP_TYPE(result) == AOP_CRY) &&
5382 (AOP_TYPE(left) != AOP_CRY)){
5383 int posbit = isLiteralBit(lit);
5387 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5390 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5396 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5397 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5399 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5400 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5403 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5404 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5405 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5412 symbol *tlbl = newiTempLabel(NULL);
5413 int sizel = AOP_SIZE(left);
5415 pic16_emitcode("setb","c");
5417 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5418 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5420 if((posbit = isLiteralBit(bytelit)) != 0)
5421 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5423 if(bytelit != 0x0FFL)
5424 pic16_emitcode("anl","a,%s",
5425 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5426 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5431 // bit = left & literal
5433 pic16_emitcode("clr","c");
5434 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5436 // if(left & literal)
5439 jmpTrueOrFalse(ifx, tlbl);
5443 pic16_outBitC(result);
5447 /* if left is same as result */
5448 if(pic16_sameRegs(AOP(result),AOP(left))){
5450 for(;size--; offset++,lit>>=8) {
5451 if(AOP_TYPE(right) == AOP_LIT){
5452 switch(lit & 0xff) {
5454 /* and'ing with 0 has clears the result */
5455 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5456 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5459 /* and'ing with 0xff is a nop when the result and left are the same */
5464 int p = my_powof2( (~lit) & 0xff );
5466 /* only one bit is set in the literal, so use a bcf instruction */
5467 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5468 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5471 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5472 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5473 if(know_W != (lit&0xff))
5474 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5476 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5481 if (AOP_TYPE(left) == AOP_ACC) {
5482 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5484 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5485 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5492 // left & result in different registers
5493 if(AOP_TYPE(result) == AOP_CRY){
5495 // if(size), result in bit
5496 // if(!size && ifx), conditional oper: if(left & right)
5497 symbol *tlbl = newiTempLabel(NULL);
5498 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5500 pic16_emitcode("setb","c");
5502 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5503 pic16_emitcode("anl","a,%s",
5504 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5505 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5510 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5511 pic16_outBitC(result);
5513 jmpTrueOrFalse(ifx, tlbl);
5515 for(;(size--);offset++) {
5517 // result = left & right
5518 if(AOP_TYPE(right) == AOP_LIT){
5519 int t = (lit >> (offset*8)) & 0x0FFL;
5522 pic16_emitcode("clrf","%s",
5523 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5524 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5527 pic16_emitcode("movf","%s,w",
5528 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5529 pic16_emitcode("movwf","%s",
5530 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5531 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5532 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5535 pic16_emitcode("movlw","0x%x",t);
5536 pic16_emitcode("andwf","%s,w",
5537 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5538 pic16_emitcode("movwf","%s",
5539 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5541 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5542 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5543 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5548 if (AOP_TYPE(left) == AOP_ACC) {
5549 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5550 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5552 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5553 pic16_emitcode("andwf","%s,w",
5554 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5555 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5556 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5558 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5559 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5565 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5566 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5567 pic16_freeAsmop(result,NULL,ic,TRUE);
5570 /*-----------------------------------------------------------------*/
5571 /* genOr - code for or */
5572 /*-----------------------------------------------------------------*/
5573 static void genOr (iCode *ic, iCode *ifx)
5575 operand *left, *right, *result;
5577 unsigned long lit = 0L;
5579 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5581 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5582 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5583 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5585 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5587 /* if left is a literal & right is not then exchange them */
5588 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5589 AOP_NEEDSACC(left)) {
5590 operand *tmp = right ;
5595 /* if result = right then exchange them */
5596 if(pic16_sameRegs(AOP(result),AOP(right))){
5597 operand *tmp = right ;
5602 /* if right is bit then exchange them */
5603 if (AOP_TYPE(right) == AOP_CRY &&
5604 AOP_TYPE(left) != AOP_CRY){
5605 operand *tmp = right ;
5610 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5612 if(AOP_TYPE(right) == AOP_LIT)
5613 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5615 size = AOP_SIZE(result);
5619 if (AOP_TYPE(left) == AOP_CRY){
5620 if(AOP_TYPE(right) == AOP_LIT){
5621 // c = bit & literal;
5623 // lit != 0 => result = 1
5624 if(AOP_TYPE(result) == AOP_CRY){
5626 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5627 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5628 // AOP(result)->aopu.aop_dir,
5629 // AOP(result)->aopu.aop_dir);
5631 continueIfTrue(ifx);
5635 // lit == 0 => result = left
5636 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5638 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5641 if (AOP_TYPE(right) == AOP_CRY){
5642 if(pic16_sameRegs(AOP(result),AOP(left))){
5644 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5645 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5646 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5648 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5649 AOP(result)->aopu.aop_dir,
5650 AOP(result)->aopu.aop_dir);
5651 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5652 AOP(right)->aopu.aop_dir,
5653 AOP(right)->aopu.aop_dir);
5654 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5655 AOP(result)->aopu.aop_dir,
5656 AOP(result)->aopu.aop_dir);
5658 if( AOP_TYPE(result) == AOP_ACC) {
5659 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5660 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5661 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5662 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5666 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5667 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5668 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5669 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5671 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5672 AOP(result)->aopu.aop_dir,
5673 AOP(result)->aopu.aop_dir);
5674 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5675 AOP(right)->aopu.aop_dir,
5676 AOP(right)->aopu.aop_dir);
5677 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5678 AOP(left)->aopu.aop_dir,
5679 AOP(left)->aopu.aop_dir);
5680 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5681 AOP(result)->aopu.aop_dir,
5682 AOP(result)->aopu.aop_dir);
5687 symbol *tlbl = newiTempLabel(NULL);
5688 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5691 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5692 if( AOP_TYPE(right) == AOP_ACC) {
5693 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5695 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5696 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5701 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5702 pic16_emitcode(";XXX setb","c");
5703 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5704 AOP(left)->aopu.aop_dir,tlbl->key+100);
5705 pic16_toBoolean(right);
5706 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5707 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5708 jmpTrueOrFalse(ifx, tlbl);
5712 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5719 pic16_outBitC(result);
5721 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5722 genIfxJump(ifx, "c");
5726 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5727 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5728 if((AOP_TYPE(right) == AOP_LIT) &&
5729 (AOP_TYPE(result) == AOP_CRY) &&
5730 (AOP_TYPE(left) != AOP_CRY)){
5732 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5735 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5737 continueIfTrue(ifx);
5740 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5741 // lit = 0, result = boolean(left)
5743 pic16_emitcode(";XXX setb","c");
5744 pic16_toBoolean(right);
5746 symbol *tlbl = newiTempLabel(NULL);
5747 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5749 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5751 genIfxJump (ifx,"a");
5755 pic16_outBitC(result);
5759 /* if left is same as result */
5760 if(pic16_sameRegs(AOP(result),AOP(left))){
5762 for(;size--; offset++,lit>>=8) {
5763 if(AOP_TYPE(right) == AOP_LIT){
5764 if((lit & 0xff) == 0)
5765 /* or'ing with 0 has no effect */
5768 int p = my_powof2(lit & 0xff);
5770 /* only one bit is set in the literal, so use a bsf instruction */
5771 pic16_emitpcode(POC_BSF,
5772 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5774 if(know_W != (lit & 0xff))
5775 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5776 know_W = lit & 0xff;
5777 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5782 if (AOP_TYPE(left) == AOP_ACC) {
5783 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5784 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5786 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5787 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5789 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5790 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5796 // left & result in different registers
5797 if(AOP_TYPE(result) == AOP_CRY){
5799 // if(size), result in bit
5800 // if(!size && ifx), conditional oper: if(left | right)
5801 symbol *tlbl = newiTempLabel(NULL);
5802 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5803 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5807 pic16_emitcode(";XXX setb","c");
5809 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5810 pic16_emitcode(";XXX orl","a,%s",
5811 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5812 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5817 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5818 pic16_outBitC(result);
5820 jmpTrueOrFalse(ifx, tlbl);
5821 } else for(;(size--);offset++){
5823 // result = left & right
5824 if(AOP_TYPE(right) == AOP_LIT){
5825 int t = (lit >> (offset*8)) & 0x0FFL;
5828 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5829 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5831 pic16_emitcode("movf","%s,w",
5832 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5833 pic16_emitcode("movwf","%s",
5834 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5837 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5838 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5839 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5841 pic16_emitcode("movlw","0x%x",t);
5842 pic16_emitcode("iorwf","%s,w",
5843 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5844 pic16_emitcode("movwf","%s",
5845 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5851 // faster than result <- left, anl result,right
5852 // and better if result is SFR
5853 if (AOP_TYPE(left) == AOP_ACC) {
5854 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5855 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5857 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5858 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5860 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5861 pic16_emitcode("iorwf","%s,w",
5862 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5864 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5865 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5870 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5871 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5872 pic16_freeAsmop(result,NULL,ic,TRUE);
5875 /*-----------------------------------------------------------------*/
5876 /* genXor - code for xclusive or */
5877 /*-----------------------------------------------------------------*/
5878 static void genXor (iCode *ic, iCode *ifx)
5880 operand *left, *right, *result;
5882 unsigned long lit = 0L;
5884 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5886 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5887 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5888 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5890 /* if left is a literal & right is not ||
5891 if left needs acc & right does not */
5892 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5893 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5894 operand *tmp = right ;
5899 /* if result = right then exchange them */
5900 if(pic16_sameRegs(AOP(result),AOP(right))){
5901 operand *tmp = right ;
5906 /* if right is bit then exchange them */
5907 if (AOP_TYPE(right) == AOP_CRY &&
5908 AOP_TYPE(left) != AOP_CRY){
5909 operand *tmp = right ;
5913 if(AOP_TYPE(right) == AOP_LIT)
5914 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5916 size = AOP_SIZE(result);
5920 if (AOP_TYPE(left) == AOP_CRY){
5921 if(AOP_TYPE(right) == AOP_LIT){
5922 // c = bit & literal;
5924 // lit>>1 != 0 => result = 1
5925 if(AOP_TYPE(result) == AOP_CRY){
5927 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
5928 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5930 continueIfTrue(ifx);
5933 pic16_emitcode("setb","c");
5937 // lit == 0, result = left
5938 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5940 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5942 // lit == 1, result = not(left)
5943 if(size && pic16_sameRegs(AOP(result),AOP(left))){
5944 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
5945 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
5946 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5949 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5950 pic16_emitcode("cpl","c");
5957 symbol *tlbl = newiTempLabel(NULL);
5958 if (AOP_TYPE(right) == AOP_CRY){
5960 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5963 int sizer = AOP_SIZE(right);
5965 // if val>>1 != 0, result = 1
5966 pic16_emitcode("setb","c");
5968 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5970 // test the msb of the lsb
5971 pic16_emitcode("anl","a,#0xfe");
5972 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5976 pic16_emitcode("rrc","a");
5978 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5979 pic16_emitcode("cpl","c");
5980 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5985 pic16_outBitC(result);
5987 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5988 genIfxJump(ifx, "c");
5992 if(pic16_sameRegs(AOP(result),AOP(left))){
5993 /* if left is same as result */
5994 for(;size--; offset++) {
5995 if(AOP_TYPE(right) == AOP_LIT){
5996 int t = (lit >> (offset*8)) & 0x0FFL;
6000 if (IS_AOP_PREG(left)) {
6001 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6002 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6003 pic16_aopPut(AOP(result),"a",offset);
6005 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6006 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6007 pic16_emitcode("xrl","%s,%s",
6008 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
6009 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6012 if (AOP_TYPE(left) == AOP_ACC)
6013 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6015 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6016 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6018 if (IS_AOP_PREG(left)) {
6019 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6020 pic16_aopPut(AOP(result),"a",offset);
6022 pic16_emitcode("xrl","%s,a",
6023 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6029 // left & result in different registers
6030 if(AOP_TYPE(result) == AOP_CRY){
6032 // if(size), result in bit
6033 // if(!size && ifx), conditional oper: if(left ^ right)
6034 symbol *tlbl = newiTempLabel(NULL);
6035 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6037 pic16_emitcode("setb","c");
6039 if((AOP_TYPE(right) == AOP_LIT) &&
6040 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6041 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6043 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6044 pic16_emitcode("xrl","a,%s",
6045 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6047 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6052 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6053 pic16_outBitC(result);
6055 jmpTrueOrFalse(ifx, tlbl);
6056 } else for(;(size--);offset++){
6058 // result = left & right
6059 if(AOP_TYPE(right) == AOP_LIT){
6060 int t = (lit >> (offset*8)) & 0x0FFL;
6063 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6064 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6065 pic16_emitcode("movf","%s,w",
6066 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6067 pic16_emitcode("movwf","%s",
6068 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6071 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6072 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6073 pic16_emitcode("comf","%s,w",
6074 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6075 pic16_emitcode("movwf","%s",
6076 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6079 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6080 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6081 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6082 pic16_emitcode("movlw","0x%x",t);
6083 pic16_emitcode("xorwf","%s,w",
6084 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6085 pic16_emitcode("movwf","%s",
6086 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6092 // faster than result <- left, anl result,right
6093 // and better if result is SFR
6094 if (AOP_TYPE(left) == AOP_ACC) {
6095 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6096 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6098 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6099 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6100 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6101 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6103 if ( AOP_TYPE(result) != AOP_ACC){
6104 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6105 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6111 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6112 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6113 pic16_freeAsmop(result,NULL,ic,TRUE);
6116 /*-----------------------------------------------------------------*/
6117 /* genInline - write the inline code out */
6118 /*-----------------------------------------------------------------*/
6119 static void genInline (iCode *ic)
6121 char *buffer, *bp, *bp1;
6123 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6125 _G.inLine += (!options.asmpeep);
6127 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6128 strcpy(buffer,IC_INLINE(ic));
6130 /* emit each line as a code */
6136 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6143 pic16_emitcode(bp1,"");
6149 if ((bp1 != bp) && *bp1)
6150 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6154 _G.inLine -= (!options.asmpeep);
6157 /*-----------------------------------------------------------------*/
6158 /* genRRC - rotate right with carry */
6159 /*-----------------------------------------------------------------*/
6160 static void genRRC (iCode *ic)
6162 operand *left , *result ;
6163 int size, offset = 0, same;
6165 /* rotate right with carry */
6167 result=IC_RESULT(ic);
6168 pic16_aopOp (left,ic,FALSE);
6169 pic16_aopOp (result,ic,FALSE);
6171 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6173 same = pic16_sameRegs(AOP(result),AOP(left));
6175 size = AOP_SIZE(result);
6177 /* get the lsb and put it into the carry */
6178 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6185 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6187 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6188 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6194 pic16_freeAsmop(left,NULL,ic,TRUE);
6195 pic16_freeAsmop(result,NULL,ic,TRUE);
6198 /*-----------------------------------------------------------------*/
6199 /* genRLC - generate code for rotate left with carry */
6200 /*-----------------------------------------------------------------*/
6201 static void genRLC (iCode *ic)
6203 operand *left , *result ;
6204 int size, offset = 0;
6207 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6208 /* rotate right with carry */
6210 result=IC_RESULT(ic);
6211 pic16_aopOp (left,ic,FALSE);
6212 pic16_aopOp (result,ic,FALSE);
6214 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6216 same = pic16_sameRegs(AOP(result),AOP(left));
6218 /* move it to the result */
6219 size = AOP_SIZE(result);
6221 /* get the msb and put it into the carry */
6222 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6229 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6231 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6232 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6239 pic16_freeAsmop(left,NULL,ic,TRUE);
6240 pic16_freeAsmop(result,NULL,ic,TRUE);
6243 /*-----------------------------------------------------------------*/
6244 /* genGetHbit - generates code get highest order bit */
6245 /*-----------------------------------------------------------------*/
6246 static void genGetHbit (iCode *ic)
6248 operand *left, *result;
6250 result=IC_RESULT(ic);
6251 pic16_aopOp (left,ic,FALSE);
6252 pic16_aopOp (result,ic,FALSE);
6254 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6255 /* get the highest order byte into a */
6256 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6257 if(AOP_TYPE(result) == AOP_CRY){
6258 pic16_emitcode("rlc","a");
6259 pic16_outBitC(result);
6262 pic16_emitcode("rl","a");
6263 pic16_emitcode("anl","a,#0x01");
6264 pic16_outAcc(result);
6268 pic16_freeAsmop(left,NULL,ic,TRUE);
6269 pic16_freeAsmop(result,NULL,ic,TRUE);
6272 /*-----------------------------------------------------------------*/
6273 /* AccRol - rotate left accumulator by known count */
6274 /*-----------------------------------------------------------------*/
6275 static void AccRol (int shCount)
6277 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6278 shCount &= 0x0007; // shCount : 0..7
6283 pic16_emitcode("rl","a");
6286 pic16_emitcode("rl","a");
6287 pic16_emitcode("rl","a");
6290 pic16_emitcode("swap","a");
6291 pic16_emitcode("rr","a");
6294 pic16_emitcode("swap","a");
6297 pic16_emitcode("swap","a");
6298 pic16_emitcode("rl","a");
6301 pic16_emitcode("rr","a");
6302 pic16_emitcode("rr","a");
6305 pic16_emitcode("rr","a");
6310 /*-----------------------------------------------------------------*/
6311 /* AccLsh - left shift accumulator by known count */
6312 /*-----------------------------------------------------------------*/
6313 static void AccLsh (int shCount)
6315 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6318 pic16_emitcode("add","a,acc");
6321 pic16_emitcode("add","a,acc");
6322 pic16_emitcode("add","a,acc");
6324 /* rotate left accumulator */
6326 /* and kill the lower order bits */
6327 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6332 /*-----------------------------------------------------------------*/
6333 /* AccRsh - right shift accumulator by known count */
6334 /*-----------------------------------------------------------------*/
6335 static void AccRsh (int shCount)
6337 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6341 pic16_emitcode("rrc","a");
6343 /* rotate right accumulator */
6344 AccRol(8 - shCount);
6345 /* and kill the higher order bits */
6346 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6352 /*-----------------------------------------------------------------*/
6353 /* AccSRsh - signed right shift accumulator by known count */
6354 /*-----------------------------------------------------------------*/
6355 static void AccSRsh (int shCount)
6358 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6361 pic16_emitcode("mov","c,acc.7");
6362 pic16_emitcode("rrc","a");
6363 } else if(shCount == 2){
6364 pic16_emitcode("mov","c,acc.7");
6365 pic16_emitcode("rrc","a");
6366 pic16_emitcode("mov","c,acc.7");
6367 pic16_emitcode("rrc","a");
6369 tlbl = newiTempLabel(NULL);
6370 /* rotate right accumulator */
6371 AccRol(8 - shCount);
6372 /* and kill the higher order bits */
6373 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6374 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6375 pic16_emitcode("orl","a,#0x%02x",
6376 (unsigned char)~SRMask[shCount]);
6377 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6382 /*-----------------------------------------------------------------*/
6383 /* shiftR1Left2Result - shift right one byte from left to result */
6384 /*-----------------------------------------------------------------*/
6385 static void shiftR1Left2ResultSigned (operand *left, int offl,
6386 operand *result, int offr,
6391 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6393 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6397 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6399 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6401 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6402 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6408 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6410 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6412 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6413 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6415 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6416 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6422 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6424 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6425 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6428 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6429 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6430 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6432 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6433 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6435 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6439 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6440 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6441 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6442 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6443 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6447 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6449 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6450 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6452 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6453 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6454 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6455 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6456 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6461 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6462 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6463 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6464 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6465 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6466 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6468 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6469 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6470 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6471 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6472 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6478 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6479 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6480 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6481 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6483 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6484 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6485 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6493 /*-----------------------------------------------------------------*/
6494 /* shiftR1Left2Result - shift right one byte from left to result */
6495 /*-----------------------------------------------------------------*/
6496 static void shiftR1Left2Result (operand *left, int offl,
6497 operand *result, int offr,
6498 int shCount, int sign)
6502 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6504 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6506 /* Copy the msb into the carry if signed. */
6508 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6518 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6520 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6521 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6527 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6529 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6530 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6533 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6538 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6540 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6541 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6544 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6545 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6546 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6547 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6551 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6552 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6553 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6557 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6558 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6559 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6561 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6566 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6567 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6568 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6569 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6570 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6575 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6576 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6577 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6586 /*-----------------------------------------------------------------*/
6587 /* shiftL1Left2Result - shift left one byte from left to result */
6588 /*-----------------------------------------------------------------*/
6589 static void shiftL1Left2Result (operand *left, int offl,
6590 operand *result, int offr, int shCount)
6595 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6597 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6598 DEBUGpic16_emitcode ("; ***","same = %d",same);
6599 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6601 /* shift left accumulator */
6602 //AccLsh(shCount); // don't comment out just yet...
6603 // pic16_aopPut(AOP(result),"a",offr);
6607 /* Shift left 1 bit position */
6608 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6610 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6612 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6613 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6617 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6618 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6619 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6620 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6623 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6624 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6625 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6626 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6627 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6630 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6631 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6632 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6635 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6636 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6637 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6638 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6641 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6642 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6643 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6644 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6645 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6648 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6649 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6650 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6654 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6659 /*-----------------------------------------------------------------*/
6660 /* movLeft2Result - move byte from left to result */
6661 /*-----------------------------------------------------------------*/
6662 static void movLeft2Result (operand *left, int offl,
6663 operand *result, int offr)
6666 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6667 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6668 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6670 if (*l == '@' && (IS_AOP_PREG(result))) {
6671 pic16_emitcode("mov","a,%s",l);
6672 pic16_aopPut(AOP(result),"a",offr);
6674 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6675 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6680 /*-----------------------------------------------------------------*/
6681 /* shiftL2Left2Result - shift left two bytes from left to result */
6682 /*-----------------------------------------------------------------*/
6683 static void shiftL2Left2Result (operand *left, int offl,
6684 operand *result, int offr, int shCount)
6688 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6690 if(pic16_sameRegs(AOP(result), AOP(left))) {
6698 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6699 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6700 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6704 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6705 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6711 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6712 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6713 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6714 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6715 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6716 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6717 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6719 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6720 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6724 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6725 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6726 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6727 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6728 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6729 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6730 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6731 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6732 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6733 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6736 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6737 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6738 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6739 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6740 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6750 /* note, use a mov/add for the shift since the mov has a
6751 chance of getting optimized out */
6752 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6753 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6754 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6755 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6756 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6760 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6761 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6767 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6768 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6769 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6770 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6771 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6772 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6773 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6774 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6778 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6779 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6783 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6784 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6785 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6786 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6788 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6789 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6790 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6791 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6792 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6793 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6794 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6795 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6798 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6799 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6800 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6801 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6802 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6807 /*-----------------------------------------------------------------*/
6808 /* shiftR2Left2Result - shift right two bytes from left to result */
6809 /*-----------------------------------------------------------------*/
6810 static void shiftR2Left2Result (operand *left, int offl,
6811 operand *result, int offr,
6812 int shCount, int sign)
6816 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6817 same = pic16_sameRegs(AOP(result), AOP(left));
6819 if(same && ((offl + MSB16) == offr)){
6821 /* don't crash result[offr] */
6822 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6823 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6826 movLeft2Result(left,offl, result, offr);
6827 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6830 /* a:x >> shCount (x = lsb(result))*/
6833 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6835 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6844 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6849 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6850 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6852 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6853 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6854 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6855 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6860 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6863 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6864 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6871 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6872 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6873 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6875 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6876 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6877 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6878 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6880 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6881 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6882 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6884 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6885 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6886 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6887 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6888 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6892 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6893 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6897 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6898 pic16_emitpcode(POC_BTFSC,
6899 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6900 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6908 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6909 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6911 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6912 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6913 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6914 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6916 pic16_emitpcode(POC_BTFSC,
6917 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6918 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6920 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6921 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6922 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6923 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6925 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6926 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6927 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6928 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6929 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6930 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6931 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6932 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6934 pic16_emitpcode(POC_BTFSC,
6935 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6936 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6938 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6939 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6946 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6947 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6948 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6949 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6952 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6954 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6959 /*-----------------------------------------------------------------*/
6960 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6961 /*-----------------------------------------------------------------*/
6962 static void shiftLLeftOrResult (operand *left, int offl,
6963 operand *result, int offr, int shCount)
6965 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6966 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6967 /* shift left accumulator */
6969 /* or with result */
6970 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6971 /* back to result */
6972 pic16_aopPut(AOP(result),"a",offr);
6975 /*-----------------------------------------------------------------*/
6976 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6977 /*-----------------------------------------------------------------*/
6978 static void shiftRLeftOrResult (operand *left, int offl,
6979 operand *result, int offr, int shCount)
6981 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6982 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6983 /* shift right accumulator */
6985 /* or with result */
6986 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6987 /* back to result */
6988 pic16_aopPut(AOP(result),"a",offr);
6991 /*-----------------------------------------------------------------*/
6992 /* genlshOne - left shift a one byte quantity by known count */
6993 /*-----------------------------------------------------------------*/
6994 static void genlshOne (operand *result, operand *left, int shCount)
6996 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6997 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7000 /*-----------------------------------------------------------------*/
7001 /* genlshTwo - left shift two bytes by known amount != 0 */
7002 /*-----------------------------------------------------------------*/
7003 static void genlshTwo (operand *result,operand *left, int shCount)
7007 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7008 size = pic16_getDataSize(result);
7010 /* if shCount >= 8 */
7016 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7018 movLeft2Result(left, LSB, result, MSB16);
7020 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7023 /* 1 <= shCount <= 7 */
7026 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7028 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7032 /*-----------------------------------------------------------------*/
7033 /* shiftLLong - shift left one long from left to result */
7034 /* offl = LSB or MSB16 */
7035 /*-----------------------------------------------------------------*/
7036 static void shiftLLong (operand *left, operand *result, int offr )
7039 int size = AOP_SIZE(result);
7041 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7042 if(size >= LSB+offr){
7043 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7045 pic16_emitcode("add","a,acc");
7046 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7047 size >= MSB16+offr && offr != LSB )
7048 pic16_emitcode("xch","a,%s",
7049 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7051 pic16_aopPut(AOP(result),"a",LSB+offr);
7054 if(size >= MSB16+offr){
7055 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7056 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7059 pic16_emitcode("rlc","a");
7060 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7061 size >= MSB24+offr && offr != LSB)
7062 pic16_emitcode("xch","a,%s",
7063 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7065 pic16_aopPut(AOP(result),"a",MSB16+offr);
7068 if(size >= MSB24+offr){
7069 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7070 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7073 pic16_emitcode("rlc","a");
7074 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7075 size >= MSB32+offr && offr != LSB )
7076 pic16_emitcode("xch","a,%s",
7077 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7079 pic16_aopPut(AOP(result),"a",MSB24+offr);
7082 if(size > MSB32+offr){
7083 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7084 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7087 pic16_emitcode("rlc","a");
7088 pic16_aopPut(AOP(result),"a",MSB32+offr);
7091 pic16_aopPut(AOP(result),zero,LSB);
7094 /*-----------------------------------------------------------------*/
7095 /* genlshFour - shift four byte by a known amount != 0 */
7096 /*-----------------------------------------------------------------*/
7097 static void genlshFour (operand *result, operand *left, int shCount)
7101 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7102 size = AOP_SIZE(result);
7104 /* if shifting more that 3 bytes */
7105 if (shCount >= 24 ) {
7108 /* lowest order of left goes to the highest
7109 order of the destination */
7110 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7112 movLeft2Result(left, LSB, result, MSB32);
7113 pic16_aopPut(AOP(result),zero,LSB);
7114 pic16_aopPut(AOP(result),zero,MSB16);
7115 pic16_aopPut(AOP(result),zero,MSB32);
7119 /* more than two bytes */
7120 else if ( shCount >= 16 ) {
7121 /* lower order two bytes goes to higher order two bytes */
7123 /* if some more remaining */
7125 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7127 movLeft2Result(left, MSB16, result, MSB32);
7128 movLeft2Result(left, LSB, result, MSB24);
7130 pic16_aopPut(AOP(result),zero,MSB16);
7131 pic16_aopPut(AOP(result),zero,LSB);
7135 /* if more than 1 byte */
7136 else if ( shCount >= 8 ) {
7137 /* lower order three bytes goes to higher order three bytes */
7141 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7143 movLeft2Result(left, LSB, result, MSB16);
7145 else{ /* size = 4 */
7147 movLeft2Result(left, MSB24, result, MSB32);
7148 movLeft2Result(left, MSB16, result, MSB24);
7149 movLeft2Result(left, LSB, result, MSB16);
7150 pic16_aopPut(AOP(result),zero,LSB);
7152 else if(shCount == 1)
7153 shiftLLong(left, result, MSB16);
7155 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7156 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7157 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7158 pic16_aopPut(AOP(result),zero,LSB);
7163 /* 1 <= shCount <= 7 */
7164 else if(shCount <= 2){
7165 shiftLLong(left, result, LSB);
7167 shiftLLong(result, result, LSB);
7169 /* 3 <= shCount <= 7, optimize */
7171 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7172 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7173 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7177 /*-----------------------------------------------------------------*/
7178 /* genLeftShiftLiteral - left shifting by known count */
7179 /*-----------------------------------------------------------------*/
7180 static void genLeftShiftLiteral (operand *left,
7185 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7188 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7189 pic16_freeAsmop(right,NULL,ic,TRUE);
7191 pic16_aopOp(left,ic,FALSE);
7192 pic16_aopOp(result,ic,FALSE);
7194 size = getSize(operandType(result));
7197 pic16_emitcode("; shift left ","result %d, left %d",size,
7201 /* I suppose that the left size >= result size */
7204 movLeft2Result(left, size, result, size);
7208 else if(shCount >= (size * 8))
7210 pic16_aopPut(AOP(result),zero,size);
7214 genlshOne (result,left,shCount);
7219 genlshTwo (result,left,shCount);
7223 genlshFour (result,left,shCount);
7227 pic16_freeAsmop(left,NULL,ic,TRUE);
7228 pic16_freeAsmop(result,NULL,ic,TRUE);
7231 /*-----------------------------------------------------------------*
7232 * genMultiAsm - repeat assembly instruction for size of register.
7233 * if endian == 1, then the high byte (i.e base address + size of
7234 * register) is used first else the low byte is used first;
7235 *-----------------------------------------------------------------*/
7236 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7241 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7254 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7259 /*-----------------------------------------------------------------*/
7260 /* genLeftShift - generates code for left shifting */
7261 /*-----------------------------------------------------------------*/
7262 static void genLeftShift (iCode *ic)
7264 operand *left,*right, *result;
7267 symbol *tlbl , *tlbl1;
7270 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7272 right = IC_RIGHT(ic);
7274 result = IC_RESULT(ic);
7276 pic16_aopOp(right,ic,FALSE);
7278 /* if the shift count is known then do it
7279 as efficiently as possible */
7280 if (AOP_TYPE(right) == AOP_LIT) {
7281 genLeftShiftLiteral (left,right,result,ic);
7285 /* shift count is unknown then we have to form
7286 a loop get the loop count in B : Note: we take
7287 only the lower order byte since shifting
7288 more that 32 bits make no sense anyway, ( the
7289 largest size of an object can be only 32 bits ) */
7292 pic16_aopOp(left,ic,FALSE);
7293 pic16_aopOp(result,ic,FALSE);
7295 /* now move the left to the result if they are not the
7297 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7298 AOP_SIZE(result) > 1) {
7300 size = AOP_SIZE(result);
7303 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7304 if (*l == '@' && (IS_AOP_PREG(result))) {
7306 pic16_emitcode("mov","a,%s",l);
7307 pic16_aopPut(AOP(result),"a",offset);
7309 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7310 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7311 //pic16_aopPut(AOP(result),l,offset);
7317 size = AOP_SIZE(result);
7319 /* if it is only one byte then */
7321 if(optimized_for_speed) {
7322 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7323 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7324 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7325 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7326 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7327 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7328 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7329 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7330 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7331 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7332 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7333 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7336 tlbl = newiTempLabel(NULL);
7337 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7338 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7339 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7342 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7343 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7344 pic16_emitpLabel(tlbl->key);
7345 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7346 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7348 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7353 if (pic16_sameRegs(AOP(left),AOP(result))) {
7355 tlbl = newiTempLabel(NULL);
7356 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7357 genMultiAsm(POC_RRCF, result, size,1);
7358 pic16_emitpLabel(tlbl->key);
7359 genMultiAsm(POC_RLCF, result, size,0);
7360 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7362 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7366 //tlbl = newiTempLabel(NULL);
7368 //tlbl1 = newiTempLabel(NULL);
7370 //reAdjustPreg(AOP(result));
7372 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7373 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7374 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7376 //pic16_emitcode("add","a,acc");
7377 //pic16_aopPut(AOP(result),"a",offset++);
7379 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7381 // pic16_emitcode("rlc","a");
7382 // pic16_aopPut(AOP(result),"a",offset++);
7384 //reAdjustPreg(AOP(result));
7386 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7387 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7390 tlbl = newiTempLabel(NULL);
7391 tlbl1= newiTempLabel(NULL);
7393 size = AOP_SIZE(result);
7396 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7398 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7400 /* offset should be 0, 1 or 3 */
7401 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7403 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7405 pic16_emitpcode(POC_MOVWF, pctemp);
7408 pic16_emitpLabel(tlbl->key);
7411 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7413 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7415 pic16_emitpcode(POC_DECFSZ, pctemp);
7416 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7417 pic16_emitpLabel(tlbl1->key);
7419 pic16_popReleaseTempReg(pctemp);
7423 pic16_freeAsmop (right,NULL,ic,TRUE);
7424 pic16_freeAsmop(left,NULL,ic,TRUE);
7425 pic16_freeAsmop(result,NULL,ic,TRUE);
7428 /*-----------------------------------------------------------------*/
7429 /* genrshOne - right shift a one byte quantity by known count */
7430 /*-----------------------------------------------------------------*/
7431 static void genrshOne (operand *result, operand *left,
7432 int shCount, int sign)
7434 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7435 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7438 /*-----------------------------------------------------------------*/
7439 /* genrshTwo - right shift two bytes by known amount != 0 */
7440 /*-----------------------------------------------------------------*/
7441 static void genrshTwo (operand *result,operand *left,
7442 int shCount, int sign)
7444 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7445 /* if shCount >= 8 */
7449 shiftR1Left2Result(left, MSB16, result, LSB,
7452 movLeft2Result(left, MSB16, result, LSB);
7454 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7457 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7458 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7462 /* 1 <= shCount <= 7 */
7464 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7467 /*-----------------------------------------------------------------*/
7468 /* shiftRLong - shift right one long from left to result */
7469 /* offl = LSB or MSB16 */
7470 /*-----------------------------------------------------------------*/
7471 static void shiftRLong (operand *left, int offl,
7472 operand *result, int sign)
7474 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7476 pic16_emitcode("clr","c");
7477 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7479 pic16_emitcode("mov","c,acc.7");
7480 pic16_emitcode("rrc","a");
7481 pic16_aopPut(AOP(result),"a",MSB32-offl);
7483 /* add sign of "a" */
7484 pic16_addSign(result, MSB32, sign);
7486 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7487 pic16_emitcode("rrc","a");
7488 pic16_aopPut(AOP(result),"a",MSB24-offl);
7490 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7491 pic16_emitcode("rrc","a");
7492 pic16_aopPut(AOP(result),"a",MSB16-offl);
7495 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7496 pic16_emitcode("rrc","a");
7497 pic16_aopPut(AOP(result),"a",LSB);
7501 /*-----------------------------------------------------------------*/
7502 /* genrshFour - shift four byte by a known amount != 0 */
7503 /*-----------------------------------------------------------------*/
7504 static void genrshFour (operand *result, operand *left,
7505 int shCount, int sign)
7507 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7508 /* if shifting more that 3 bytes */
7509 if(shCount >= 24 ) {
7512 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7514 movLeft2Result(left, MSB32, result, LSB);
7516 pic16_addSign(result, MSB16, sign);
7518 else if(shCount >= 16){
7521 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7523 movLeft2Result(left, MSB24, result, LSB);
7524 movLeft2Result(left, MSB32, result, MSB16);
7526 pic16_addSign(result, MSB24, sign);
7528 else if(shCount >= 8){
7531 shiftRLong(left, MSB16, result, sign);
7532 else if(shCount == 0){
7533 movLeft2Result(left, MSB16, result, LSB);
7534 movLeft2Result(left, MSB24, result, MSB16);
7535 movLeft2Result(left, MSB32, result, MSB24);
7536 pic16_addSign(result, MSB32, sign);
7539 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7540 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7541 /* the last shift is signed */
7542 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7543 pic16_addSign(result, MSB32, sign);
7546 else{ /* 1 <= shCount <= 7 */
7548 shiftRLong(left, LSB, result, sign);
7550 shiftRLong(result, LSB, result, sign);
7553 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7554 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7555 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7560 /*-----------------------------------------------------------------*/
7561 /* genRightShiftLiteral - right shifting by known count */
7562 /*-----------------------------------------------------------------*/
7563 static void genRightShiftLiteral (operand *left,
7569 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7572 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7573 pic16_freeAsmop(right,NULL,ic,TRUE);
7575 pic16_aopOp(left,ic,FALSE);
7576 pic16_aopOp(result,ic,FALSE);
7579 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7583 lsize = pic16_getDataSize(left);
7584 res_size = pic16_getDataSize(result);
7585 /* test the LEFT size !!! */
7587 /* I suppose that the left size >= result size */
7590 movLeft2Result(left, lsize, result, res_size);
7593 else if(shCount >= (lsize * 8)){
7596 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7598 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7599 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7604 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7605 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7606 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7608 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7613 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7620 genrshOne (result,left,shCount,sign);
7624 genrshTwo (result,left,shCount,sign);
7628 genrshFour (result,left,shCount,sign);
7636 pic16_freeAsmop(left,NULL,ic,TRUE);
7637 pic16_freeAsmop(result,NULL,ic,TRUE);
7640 /*-----------------------------------------------------------------*/
7641 /* genSignedRightShift - right shift of signed number */
7642 /*-----------------------------------------------------------------*/
7643 static void genSignedRightShift (iCode *ic)
7645 operand *right, *left, *result;
7648 symbol *tlbl, *tlbl1 ;
7651 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7653 /* we do it the hard way put the shift count in b
7654 and loop thru preserving the sign */
7655 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7657 right = IC_RIGHT(ic);
7659 result = IC_RESULT(ic);
7661 pic16_aopOp(right,ic,FALSE);
7662 pic16_aopOp(left,ic,FALSE);
7663 pic16_aopOp(result,ic,FALSE);
7666 if ( AOP_TYPE(right) == AOP_LIT) {
7667 genRightShiftLiteral (left,right,result,ic,1);
7670 /* shift count is unknown then we have to form
7671 a loop get the loop count in B : Note: we take
7672 only the lower order byte since shifting
7673 more that 32 bits make no sense anyway, ( the
7674 largest size of an object can be only 32 bits ) */
7676 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7677 //pic16_emitcode("inc","b");
7678 //pic16_freeAsmop (right,NULL,ic,TRUE);
7679 //pic16_aopOp(left,ic,FALSE);
7680 //pic16_aopOp(result,ic,FALSE);
7682 /* now move the left to the result if they are not the
7684 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7685 AOP_SIZE(result) > 1) {
7687 size = AOP_SIZE(result);
7691 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7692 if (*l == '@' && IS_AOP_PREG(result)) {
7694 pic16_emitcode("mov","a,%s",l);
7695 pic16_aopPut(AOP(result),"a",offset);
7697 pic16_aopPut(AOP(result),l,offset);
7699 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7700 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7706 /* mov the highest order bit to OVR */
7707 tlbl = newiTempLabel(NULL);
7708 tlbl1= newiTempLabel(NULL);
7710 size = AOP_SIZE(result);
7713 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7715 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7717 /* offset should be 0, 1 or 3 */
7718 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7720 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7722 pic16_emitpcode(POC_MOVWF, pctemp);
7725 pic16_emitpLabel(tlbl->key);
7727 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7728 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7731 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7734 pic16_emitpcode(POC_DECFSZ, pctemp);
7735 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7736 pic16_emitpLabel(tlbl1->key);
7738 pic16_popReleaseTempReg(pctemp);
7740 size = AOP_SIZE(result);
7742 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7743 pic16_emitcode("rlc","a");
7744 pic16_emitcode("mov","ov,c");
7745 /* if it is only one byte then */
7747 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7749 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7750 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7751 pic16_emitcode("mov","c,ov");
7752 pic16_emitcode("rrc","a");
7753 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7754 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7755 pic16_aopPut(AOP(result),"a",0);
7759 reAdjustPreg(AOP(result));
7760 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7761 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7762 pic16_emitcode("mov","c,ov");
7764 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7766 pic16_emitcode("rrc","a");
7767 pic16_aopPut(AOP(result),"a",offset--);
7769 reAdjustPreg(AOP(result));
7770 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7771 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7776 pic16_freeAsmop(left,NULL,ic,TRUE);
7777 pic16_freeAsmop(result,NULL,ic,TRUE);
7778 pic16_freeAsmop(right,NULL,ic,TRUE);
7781 /*-----------------------------------------------------------------*/
7782 /* genRightShift - generate code for right shifting */
7783 /*-----------------------------------------------------------------*/
7784 static void genRightShift (iCode *ic)
7786 operand *right, *left, *result;
7790 symbol *tlbl, *tlbl1 ;
7792 /* if signed then we do it the hard way preserve the
7793 sign bit moving it inwards */
7794 retype = getSpec(operandType(IC_RESULT(ic)));
7795 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7797 if (!SPEC_USIGN(retype)) {
7798 genSignedRightShift (ic);
7802 /* signed & unsigned types are treated the same : i.e. the
7803 signed is NOT propagated inwards : quoting from the
7804 ANSI - standard : "for E1 >> E2, is equivalent to division
7805 by 2**E2 if unsigned or if it has a non-negative value,
7806 otherwise the result is implementation defined ", MY definition
7807 is that the sign does not get propagated */
7809 right = IC_RIGHT(ic);
7811 result = IC_RESULT(ic);
7813 pic16_aopOp(right,ic,FALSE);
7815 /* if the shift count is known then do it
7816 as efficiently as possible */
7817 if (AOP_TYPE(right) == AOP_LIT) {
7818 genRightShiftLiteral (left,right,result,ic, 0);
7822 /* shift count is unknown then we have to form
7823 a loop get the loop count in B : Note: we take
7824 only the lower order byte since shifting
7825 more that 32 bits make no sense anyway, ( the
7826 largest size of an object can be only 32 bits ) */
7828 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7829 pic16_emitcode("inc","b");
7830 pic16_aopOp(left,ic,FALSE);
7831 pic16_aopOp(result,ic,FALSE);
7833 /* now move the left to the result if they are not the
7835 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7836 AOP_SIZE(result) > 1) {
7838 size = AOP_SIZE(result);
7841 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7842 if (*l == '@' && IS_AOP_PREG(result)) {
7844 pic16_emitcode("mov","a,%s",l);
7845 pic16_aopPut(AOP(result),"a",offset);
7847 pic16_aopPut(AOP(result),l,offset);
7852 tlbl = newiTempLabel(NULL);
7853 tlbl1= newiTempLabel(NULL);
7854 size = AOP_SIZE(result);
7857 /* if it is only one byte then */
7860 tlbl = newiTempLabel(NULL);
7861 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7862 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7863 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7866 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7867 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7868 pic16_emitpLabel(tlbl->key);
7869 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7870 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7872 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7877 reAdjustPreg(AOP(result));
7878 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7879 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7882 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7884 pic16_emitcode("rrc","a");
7885 pic16_aopPut(AOP(result),"a",offset--);
7887 reAdjustPreg(AOP(result));
7889 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7890 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7893 pic16_freeAsmop(left,NULL,ic,TRUE);
7894 pic16_freeAsmop (right,NULL,ic,TRUE);
7895 pic16_freeAsmop(result,NULL,ic,TRUE);
7898 /*-----------------------------------------------------------------*/
7899 /* genUnpackBits - generates code for unpacking bits */
7900 /*-----------------------------------------------------------------*/
7901 static void genUnpackBits (operand *result, char *rname, int ptype)
7908 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7909 etype = getSpec(operandType(result));
7911 /* read the first byte */
7916 pic16_emitcode("mov","a,@%s",rname);
7920 pic16_emitcode("movx","a,@%s",rname);
7924 pic16_emitcode("movx","a,@dptr");
7928 pic16_emitcode("clr","a");
7929 pic16_emitcode("movc","a","@a+dptr");
7933 pic16_emitcode("lcall","__gptrget");
7937 /* if we have bitdisplacement then it fits */
7938 /* into this byte completely or if length is */
7939 /* less than a byte */
7940 if ((shCnt = SPEC_BSTR(etype)) ||
7941 (SPEC_BLEN(etype) <= 8)) {
7943 /* shift right acc */
7946 pic16_emitcode("anl","a,#0x%02x",
7947 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7948 pic16_aopPut(AOP(result),"a",offset);
7952 /* bit field did not fit in a byte */
7953 rlen = SPEC_BLEN(etype) - 8;
7954 pic16_aopPut(AOP(result),"a",offset++);
7961 pic16_emitcode("inc","%s",rname);
7962 pic16_emitcode("mov","a,@%s",rname);
7966 pic16_emitcode("inc","%s",rname);
7967 pic16_emitcode("movx","a,@%s",rname);
7971 pic16_emitcode("inc","dptr");
7972 pic16_emitcode("movx","a,@dptr");
7976 pic16_emitcode("clr","a");
7977 pic16_emitcode("inc","dptr");
7978 pic16_emitcode("movc","a","@a+dptr");
7982 pic16_emitcode("inc","dptr");
7983 pic16_emitcode("lcall","__gptrget");
7988 /* if we are done */
7992 pic16_aopPut(AOP(result),"a",offset++);
7997 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7998 pic16_aopPut(AOP(result),"a",offset);
8005 /*-----------------------------------------------------------------*/
8006 /* genDataPointerGet - generates code when ptr offset is known */
8007 /*-----------------------------------------------------------------*/
8008 static void genDataPointerGet (operand *left,
8012 int size , offset = 0;
8015 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8018 /* optimization - most of the time, left and result are the same
8019 * address, but different types. for the pic code, we could omit
8023 pic16_aopOp(result,ic,TRUE);
8025 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8027 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8029 size = AOP_SIZE(result);
8032 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8036 pic16_freeAsmop(left,NULL,ic,TRUE);
8037 pic16_freeAsmop(result,NULL,ic,TRUE);
8040 /*-----------------------------------------------------------------*/
8041 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8042 /*-----------------------------------------------------------------*/
8043 static void genNearPointerGet (operand *left,
8048 //regs *preg = NULL ;
8050 sym_link *rtype, *retype;
8051 sym_link *ltype = operandType(left);
8054 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8056 rtype = operandType(result);
8057 retype= getSpec(rtype);
8059 pic16_aopOp(left,ic,FALSE);
8061 /* if left is rematerialisable and
8062 result is not bit variable type and
8063 the left is pointer to data space i.e
8064 lower 128 bytes of space */
8065 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8066 !IS_BITVAR(retype) &&
8067 DCL_TYPE(ltype) == POINTER) {
8068 //genDataPointerGet (left,result,ic);
8072 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8074 /* if the value is already in a pointer register
8075 then don't need anything more */
8076 if (!AOP_INPREG(AOP(left))) {
8077 /* otherwise get a free pointer register */
8078 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8081 preg = getFreePtr(ic,&aop,FALSE);
8082 pic16_emitcode("mov","%s,%s",
8084 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8085 rname = preg->name ;
8089 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8091 pic16_aopOp (result,ic,FALSE);
8093 /* if bitfield then unpack the bits */
8094 if (IS_BITVAR(retype))
8095 genUnpackBits (result,rname,POINTER);
8097 /* we have can just get the values */
8098 int size = AOP_SIZE(result);
8101 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8103 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8104 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8106 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8107 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8109 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8113 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8115 pic16_emitcode("mov","a,@%s",rname);
8116 pic16_aopPut(AOP(result),"a",offset);
8118 sprintf(buffer,"@%s",rname);
8119 pic16_aopPut(AOP(result),buffer,offset);
8123 pic16_emitcode("inc","%s",rname);
8128 /* now some housekeeping stuff */
8130 /* we had to allocate for this iCode */
8131 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8132 pic16_freeAsmop(NULL,aop,ic,TRUE);
8134 /* we did not allocate which means left
8135 already in a pointer register, then
8136 if size > 0 && this could be used again
8137 we have to point it back to where it
8139 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8140 if (AOP_SIZE(result) > 1 &&
8141 !OP_SYMBOL(left)->remat &&
8142 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8144 int size = AOP_SIZE(result) - 1;
8146 pic16_emitcode("dec","%s",rname);
8151 pic16_freeAsmop(left,NULL,ic,TRUE);
8152 pic16_freeAsmop(result,NULL,ic,TRUE);
8156 /*-----------------------------------------------------------------*/
8157 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8158 /*-----------------------------------------------------------------*/
8159 static void genPagedPointerGet (operand *left,
8166 sym_link *rtype, *retype;
8168 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8170 rtype = operandType(result);
8171 retype= getSpec(rtype);
8173 pic16_aopOp(left,ic,FALSE);
8175 /* if the value is already in a pointer register
8176 then don't need anything more */
8177 if (!AOP_INPREG(AOP(left))) {
8178 /* otherwise get a free pointer register */
8180 preg = getFreePtr(ic,&aop,FALSE);
8181 pic16_emitcode("mov","%s,%s",
8183 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8184 rname = preg->name ;
8186 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8188 pic16_freeAsmop(left,NULL,ic,TRUE);
8189 pic16_aopOp (result,ic,FALSE);
8191 /* if bitfield then unpack the bits */
8192 if (IS_BITVAR(retype))
8193 genUnpackBits (result,rname,PPOINTER);
8195 /* we have can just get the values */
8196 int size = AOP_SIZE(result);
8201 pic16_emitcode("movx","a,@%s",rname);
8202 pic16_aopPut(AOP(result),"a",offset);
8207 pic16_emitcode("inc","%s",rname);
8211 /* now some housekeeping stuff */
8213 /* we had to allocate for this iCode */
8214 pic16_freeAsmop(NULL,aop,ic,TRUE);
8216 /* we did not allocate which means left
8217 already in a pointer register, then
8218 if size > 0 && this could be used again
8219 we have to point it back to where it
8221 if (AOP_SIZE(result) > 1 &&
8222 !OP_SYMBOL(left)->remat &&
8223 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8225 int size = AOP_SIZE(result) - 1;
8227 pic16_emitcode("dec","%s",rname);
8232 pic16_freeAsmop(result,NULL,ic,TRUE);
8237 /*-----------------------------------------------------------------*/
8238 /* genFarPointerGet - gget value from far space */
8239 /*-----------------------------------------------------------------*/
8240 static void genFarPointerGet (operand *left,
8241 operand *result, iCode *ic)
8244 sym_link *retype = getSpec(operandType(result));
8246 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8248 pic16_aopOp(left,ic,FALSE);
8250 /* if the operand is already in dptr
8251 then we do nothing else we move the value to dptr */
8252 if (AOP_TYPE(left) != AOP_STR) {
8253 /* if this is remateriazable */
8254 if (AOP_TYPE(left) == AOP_IMMD)
8255 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8256 else { /* we need to get it byte by byte */
8257 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8258 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8259 if (options.model == MODEL_FLAT24)
8261 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8265 /* so dptr know contains the address */
8266 pic16_freeAsmop(left,NULL,ic,TRUE);
8267 pic16_aopOp(result,ic,FALSE);
8269 /* if bit then unpack */
8270 if (IS_BITVAR(retype))
8271 genUnpackBits(result,"dptr",FPOINTER);
8273 size = AOP_SIZE(result);
8277 pic16_emitcode("movx","a,@dptr");
8278 pic16_aopPut(AOP(result),"a",offset++);
8280 pic16_emitcode("inc","dptr");
8284 pic16_freeAsmop(result,NULL,ic,TRUE);
8287 /*-----------------------------------------------------------------*/
8288 /* genCodePointerGet - get value from code space */
8289 /*-----------------------------------------------------------------*/
8290 static void genCodePointerGet (operand *left,
8291 operand *result, iCode *ic)
8294 sym_link *retype = getSpec(operandType(result));
8296 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8298 pic16_aopOp(left,ic,FALSE);
8300 /* if the operand is already in dptr
8301 then we do nothing else we move the value to dptr */
8302 if (AOP_TYPE(left) != AOP_STR) {
8303 /* if this is remateriazable */
8304 if (AOP_TYPE(left) == AOP_IMMD)
8305 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8306 else { /* we need to get it byte by byte */
8307 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8308 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8309 if (options.model == MODEL_FLAT24)
8311 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8315 /* so dptr know contains the address */
8316 pic16_freeAsmop(left,NULL,ic,TRUE);
8317 pic16_aopOp(result,ic,FALSE);
8319 /* if bit then unpack */
8320 if (IS_BITVAR(retype))
8321 genUnpackBits(result,"dptr",CPOINTER);
8323 size = AOP_SIZE(result);
8327 pic16_emitcode("clr","a");
8328 pic16_emitcode("movc","a,@a+dptr");
8329 pic16_aopPut(AOP(result),"a",offset++);
8331 pic16_emitcode("inc","dptr");
8335 pic16_freeAsmop(result,NULL,ic,TRUE);
8338 /*-----------------------------------------------------------------*/
8339 /* genGenPointerGet - gget value from generic pointer space */
8340 /*-----------------------------------------------------------------*/
8341 static void genGenPointerGet (operand *left,
8342 operand *result, iCode *ic)
8345 sym_link *retype = getSpec(operandType(result));
8347 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8348 pic16_aopOp(left,ic,FALSE);
8349 pic16_aopOp(result,ic,FALSE);
8352 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8354 /* if the operand is already in dptr
8355 then we do nothing else we move the value to dptr */
8356 // if (AOP_TYPE(left) != AOP_STR) {
8357 /* if this is remateriazable */
8358 if (AOP_TYPE(left) == AOP_IMMD) {
8359 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8360 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8362 else { /* we need to get it byte by byte */
8364 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8365 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8367 size = AOP_SIZE(result);
8371 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8372 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8374 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8379 /* so dptr know contains the address */
8381 /* if bit then unpack */
8382 //if (IS_BITVAR(retype))
8383 // genUnpackBits(result,"dptr",GPOINTER);
8386 pic16_freeAsmop(left,NULL,ic,TRUE);
8387 pic16_freeAsmop(result,NULL,ic,TRUE);
8391 /*-----------------------------------------------------------------*/
8392 /* genConstPointerGet - get value from const generic pointer space */
8393 /*-----------------------------------------------------------------*/
8394 static void genConstPointerGet (operand *left,
8395 operand *result, iCode *ic)
8397 //sym_link *retype = getSpec(operandType(result));
8398 symbol *albl = newiTempLabel(NULL);
8399 symbol *blbl = newiTempLabel(NULL);
8402 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8403 pic16_aopOp(left,ic,FALSE);
8404 pic16_aopOp(result,ic,FALSE);
8407 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8409 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8411 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8412 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8413 pic16_emitpLabel(albl->key);
8415 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8417 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8418 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8419 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8420 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8422 pic16_emitpLabel(blbl->key);
8424 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8427 pic16_freeAsmop(left,NULL,ic,TRUE);
8428 pic16_freeAsmop(result,NULL,ic,TRUE);
8431 /*-----------------------------------------------------------------*/
8432 /* genPointerGet - generate code for pointer get */
8433 /*-----------------------------------------------------------------*/
8434 static void genPointerGet (iCode *ic)
8436 operand *left, *result ;
8437 sym_link *type, *etype;
8440 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8443 result = IC_RESULT(ic) ;
8445 /* depending on the type of pointer we need to
8446 move it to the correct pointer register */
8447 type = operandType(left);
8448 etype = getSpec(type);
8450 if (IS_PTR_CONST(type))
8451 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8453 /* if left is of type of pointer then it is simple */
8454 if (IS_PTR(type) && !IS_FUNC(type->next))
8455 p_type = DCL_TYPE(type);
8457 /* we have to go by the storage class */
8458 p_type = PTR_TYPE(SPEC_OCLS(etype));
8460 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8462 if (SPEC_OCLS(etype)->codesp ) {
8463 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8464 //p_type = CPOINTER ;
8467 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8468 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8469 /*p_type = FPOINTER ;*/
8471 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8472 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8473 /* p_type = PPOINTER; */
8475 if (SPEC_OCLS(etype) == idata )
8476 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8477 /* p_type = IPOINTER; */
8479 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8480 /* p_type = POINTER ; */
8483 /* now that we have the pointer type we assign
8484 the pointer values */
8489 genNearPointerGet (left,result,ic);
8493 genPagedPointerGet(left,result,ic);
8497 genFarPointerGet (left,result,ic);
8501 genConstPointerGet (left,result,ic);
8502 //pic16_emitcodePointerGet (left,result,ic);
8506 if (IS_PTR_CONST(type))
8507 genConstPointerGet (left,result,ic);
8509 genGenPointerGet (left,result,ic);
8515 /*-----------------------------------------------------------------*/
8516 /* genPackBits - generates code for packed bit storage */
8517 /*-----------------------------------------------------------------*/
8518 static void genPackBits (sym_link *etype ,
8520 char *rname, int p_type)
8528 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8529 blen = SPEC_BLEN(etype);
8530 bstr = SPEC_BSTR(etype);
8532 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8535 /* if the bit lenth is less than or */
8536 /* it exactly fits a byte then */
8537 if (SPEC_BLEN(etype) <= 8 ) {
8538 shCount = SPEC_BSTR(etype) ;
8540 /* shift left acc */
8543 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8548 pic16_emitcode ("mov","b,a");
8549 pic16_emitcode("mov","a,@%s",rname);
8553 pic16_emitcode ("mov","b,a");
8554 pic16_emitcode("movx","a,@dptr");
8558 pic16_emitcode ("push","b");
8559 pic16_emitcode ("push","acc");
8560 pic16_emitcode ("lcall","__gptrget");
8561 pic16_emitcode ("pop","b");
8565 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8566 ((unsigned char)(0xFF << (blen+bstr)) |
8567 (unsigned char)(0xFF >> (8-bstr)) ) );
8568 pic16_emitcode ("orl","a,b");
8569 if (p_type == GPOINTER)
8570 pic16_emitcode("pop","b");
8576 pic16_emitcode("mov","@%s,a",rname);
8580 pic16_emitcode("movx","@dptr,a");
8584 DEBUGpic16_emitcode(";lcall","__gptrput");
8589 if ( SPEC_BLEN(etype) <= 8 )
8592 pic16_emitcode("inc","%s",rname);
8593 rLen = SPEC_BLEN(etype) ;
8595 /* now generate for lengths greater than one byte */
8598 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8608 pic16_emitcode("mov","@%s,a",rname);
8610 pic16_emitcode("mov","@%s,%s",rname,l);
8615 pic16_emitcode("movx","@dptr,a");
8620 DEBUGpic16_emitcode(";lcall","__gptrput");
8623 pic16_emitcode ("inc","%s",rname);
8628 /* last last was not complete */
8630 /* save the byte & read byte */
8633 pic16_emitcode ("mov","b,a");
8634 pic16_emitcode("mov","a,@%s",rname);
8638 pic16_emitcode ("mov","b,a");
8639 pic16_emitcode("movx","a,@dptr");
8643 pic16_emitcode ("push","b");
8644 pic16_emitcode ("push","acc");
8645 pic16_emitcode ("lcall","__gptrget");
8646 pic16_emitcode ("pop","b");
8650 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8651 pic16_emitcode ("orl","a,b");
8654 if (p_type == GPOINTER)
8655 pic16_emitcode("pop","b");
8660 pic16_emitcode("mov","@%s,a",rname);
8664 pic16_emitcode("movx","@dptr,a");
8668 DEBUGpic16_emitcode(";lcall","__gptrput");
8672 /*-----------------------------------------------------------------*/
8673 /* genDataPointerSet - remat pointer to data space */
8674 /*-----------------------------------------------------------------*/
8675 static void genDataPointerSet(operand *right,
8679 int size, offset = 0 ;
8680 char *l, buffer[256];
8682 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8683 pic16_aopOp(right,ic,FALSE);
8685 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8686 size = AOP_SIZE(right);
8688 if ( AOP_TYPE(result) == AOP_PCODE) {
8689 fprintf(stderr,"genDataPointerSet %s, %d\n",
8690 AOP(result)->aopu.pcop->name,
8691 PCOI(AOP(result)->aopu.pcop)->offset);
8695 // tsd, was l+1 - the underline `_' prefix was being stripped
8698 sprintf(buffer,"(%s + %d)",l,offset);
8699 fprintf(stderr,"oops %s\n",buffer);
8701 sprintf(buffer,"%s",l);
8703 if (AOP_TYPE(right) == AOP_LIT) {
8704 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8705 lit = lit >> (8*offset);
8707 pic16_emitcode("movlw","%d",lit);
8708 pic16_emitcode("movwf","%s",buffer);
8710 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8711 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8712 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8715 pic16_emitcode("clrf","%s",buffer);
8716 //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8717 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8720 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8721 pic16_emitcode("movwf","%s",buffer);
8723 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8724 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8725 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8732 pic16_freeAsmop(right,NULL,ic,TRUE);
8733 pic16_freeAsmop(result,NULL,ic,TRUE);
8736 /*-----------------------------------------------------------------*/
8737 /* genNearPointerSet - pic16_emitcode for near pointer put */
8738 /*-----------------------------------------------------------------*/
8739 static void genNearPointerSet (operand *right,
8746 sym_link *ptype = operandType(result);
8749 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8750 retype= getSpec(operandType(right));
8752 pic16_aopOp(result,ic,FALSE);
8755 /* if the result is rematerializable &
8756 in data space & not a bit variable */
8757 //if (AOP_TYPE(result) == AOP_IMMD &&
8758 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8759 DCL_TYPE(ptype) == POINTER &&
8760 !IS_BITVAR(retype)) {
8761 genDataPointerSet (right,result,ic);
8762 pic16_freeAsmop(result,NULL,ic,TRUE);
8766 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8767 pic16_aopOp(right,ic,FALSE);
8768 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8770 /* if the value is already in a pointer register
8771 then don't need anything more */
8772 if (!AOP_INPREG(AOP(result))) {
8773 /* otherwise get a free pointer register */
8774 //aop = newAsmop(0);
8775 //preg = getFreePtr(ic,&aop,FALSE);
8776 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8777 //pic16_emitcode("mov","%s,%s",
8779 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8780 //rname = preg->name ;
8781 //pic16_emitcode("movwf","fsr0");
8782 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8783 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8784 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8785 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8789 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8792 /* if bitfield then unpack the bits */
8793 if (IS_BITVAR(retype)) {
8794 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8795 "The programmer is obviously confused");
8796 //genPackBits (retype,right,rname,POINTER);
8800 /* we have can just get the values */
8801 int size = AOP_SIZE(right);
8804 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8806 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8809 //pic16_emitcode("mov","@%s,a",rname);
8810 pic16_emitcode("movf","indf0,w ;1");
8813 if (AOP_TYPE(right) == AOP_LIT) {
8814 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8816 pic16_emitcode("movlw","%s",l);
8817 pic16_emitcode("movwf","indf0 ;2");
8819 pic16_emitcode("clrf","indf0");
8821 pic16_emitcode("movf","%s,w",l);
8822 pic16_emitcode("movwf","indf0 ;2");
8824 //pic16_emitcode("mov","@%s,%s",rname,l);
8827 pic16_emitcode("incf","fsr0,f ;3");
8828 //pic16_emitcode("inc","%s",rname);
8833 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8834 /* now some housekeeping stuff */
8836 /* we had to allocate for this iCode */
8837 pic16_freeAsmop(NULL,aop,ic,TRUE);
8839 /* we did not allocate which means left
8840 already in a pointer register, then
8841 if size > 0 && this could be used again
8842 we have to point it back to where it
8844 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8845 if (AOP_SIZE(right) > 1 &&
8846 !OP_SYMBOL(result)->remat &&
8847 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8849 int size = AOP_SIZE(right) - 1;
8851 pic16_emitcode("decf","fsr0,f");
8852 //pic16_emitcode("dec","%s",rname);
8856 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8859 pic16_freeAsmop(right,NULL,ic,TRUE);
8860 pic16_freeAsmop(result,NULL,ic,TRUE);
8863 /*-----------------------------------------------------------------*/
8864 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8865 /*-----------------------------------------------------------------*/
8866 static void genPagedPointerSet (operand *right,
8875 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8877 retype= getSpec(operandType(right));
8879 pic16_aopOp(result,ic,FALSE);
8881 /* if the value is already in a pointer register
8882 then don't need anything more */
8883 if (!AOP_INPREG(AOP(result))) {
8884 /* otherwise get a free pointer register */
8886 preg = getFreePtr(ic,&aop,FALSE);
8887 pic16_emitcode("mov","%s,%s",
8889 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8890 rname = preg->name ;
8892 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8894 pic16_freeAsmop(result,NULL,ic,TRUE);
8895 pic16_aopOp (right,ic,FALSE);
8897 /* if bitfield then unpack the bits */
8898 if (IS_BITVAR(retype))
8899 genPackBits (retype,right,rname,PPOINTER);
8901 /* we have can just get the values */
8902 int size = AOP_SIZE(right);
8906 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8909 pic16_emitcode("movx","@%s,a",rname);
8912 pic16_emitcode("inc","%s",rname);
8918 /* now some housekeeping stuff */
8920 /* we had to allocate for this iCode */
8921 pic16_freeAsmop(NULL,aop,ic,TRUE);
8923 /* we did not allocate which means left
8924 already in a pointer register, then
8925 if size > 0 && this could be used again
8926 we have to point it back to where it
8928 if (AOP_SIZE(right) > 1 &&
8929 !OP_SYMBOL(result)->remat &&
8930 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8932 int size = AOP_SIZE(right) - 1;
8934 pic16_emitcode("dec","%s",rname);
8939 pic16_freeAsmop(right,NULL,ic,TRUE);
8944 /*-----------------------------------------------------------------*/
8945 /* genFarPointerSet - set value from far space */
8946 /*-----------------------------------------------------------------*/
8947 static void genFarPointerSet (operand *right,
8948 operand *result, iCode *ic)
8951 sym_link *retype = getSpec(operandType(right));
8953 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8954 pic16_aopOp(result,ic,FALSE);
8956 /* if the operand is already in dptr
8957 then we do nothing else we move the value to dptr */
8958 if (AOP_TYPE(result) != AOP_STR) {
8959 /* if this is remateriazable */
8960 if (AOP_TYPE(result) == AOP_IMMD)
8961 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8962 else { /* we need to get it byte by byte */
8963 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8964 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8965 if (options.model == MODEL_FLAT24)
8967 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8971 /* so dptr know contains the address */
8972 pic16_freeAsmop(result,NULL,ic,TRUE);
8973 pic16_aopOp(right,ic,FALSE);
8975 /* if bit then unpack */
8976 if (IS_BITVAR(retype))
8977 genPackBits(retype,right,"dptr",FPOINTER);
8979 size = AOP_SIZE(right);
8983 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8985 pic16_emitcode("movx","@dptr,a");
8987 pic16_emitcode("inc","dptr");
8991 pic16_freeAsmop(right,NULL,ic,TRUE);
8994 /*-----------------------------------------------------------------*/
8995 /* genGenPointerSet - set value from generic pointer space */
8996 /*-----------------------------------------------------------------*/
8997 static void genGenPointerSet (operand *right,
8998 operand *result, iCode *ic)
9001 sym_link *retype = getSpec(operandType(right));
9003 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9005 pic16_aopOp(result,ic,FALSE);
9006 pic16_aopOp(right,ic,FALSE);
9007 size = AOP_SIZE(right);
9009 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9011 /* if the operand is already in dptr
9012 then we do nothing else we move the value to dptr */
9013 if (AOP_TYPE(result) != AOP_STR) {
9014 /* if this is remateriazable */
9015 if (AOP_TYPE(result) == AOP_IMMD) {
9016 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9017 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9019 else { /* we need to get it byte by byte */
9020 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9021 size = AOP_SIZE(right);
9024 /* hack hack! see if this the FSR. If so don't load W */
9025 if(AOP_TYPE(right) != AOP_ACC) {
9028 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9029 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9031 if(AOP_SIZE(result) > 1) {
9032 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9033 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9034 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9039 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9041 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9042 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9046 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9047 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9050 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9057 if(aopIdx(AOP(result),0) != 4) {
9059 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9063 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9068 /* so dptr know contains the address */
9071 /* if bit then unpack */
9072 if (IS_BITVAR(retype))
9073 genPackBits(retype,right,"dptr",GPOINTER);
9075 size = AOP_SIZE(right);
9078 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9082 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9083 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9085 if (AOP_TYPE(right) == AOP_LIT)
9086 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9088 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9090 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9097 pic16_freeAsmop(right,NULL,ic,TRUE);
9098 pic16_freeAsmop(result,NULL,ic,TRUE);
9101 /*-----------------------------------------------------------------*/
9102 /* genPointerSet - stores the value into a pointer location */
9103 /*-----------------------------------------------------------------*/
9104 static void genPointerSet (iCode *ic)
9106 operand *right, *result ;
9107 sym_link *type, *etype;
9110 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9112 right = IC_RIGHT(ic);
9113 result = IC_RESULT(ic) ;
9115 /* depending on the type of pointer we need to
9116 move it to the correct pointer register */
9117 type = operandType(result);
9118 etype = getSpec(type);
9119 /* if left is of type of pointer then it is simple */
9120 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9121 p_type = DCL_TYPE(type);
9124 /* we have to go by the storage class */
9125 p_type = PTR_TYPE(SPEC_OCLS(etype));
9127 /* if (SPEC_OCLS(etype)->codesp ) { */
9128 /* p_type = CPOINTER ; */
9131 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9132 /* p_type = FPOINTER ; */
9134 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9135 /* p_type = PPOINTER ; */
9137 /* if (SPEC_OCLS(etype) == idata ) */
9138 /* p_type = IPOINTER ; */
9140 /* p_type = POINTER ; */
9143 /* now that we have the pointer type we assign
9144 the pointer values */
9149 genNearPointerSet (right,result,ic);
9153 genPagedPointerSet (right,result,ic);
9157 genFarPointerSet (right,result,ic);
9161 genGenPointerSet (right,result,ic);
9165 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9166 "genPointerSet: illegal pointer type");
9170 /*-----------------------------------------------------------------*/
9171 /* genIfx - generate code for Ifx statement */
9172 /*-----------------------------------------------------------------*/
9173 static void genIfx (iCode *ic, iCode *popIc)
9175 operand *cond = IC_COND(ic);
9178 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9180 pic16_aopOp(cond,ic,FALSE);
9182 /* get the value into acc */
9183 if (AOP_TYPE(cond) != AOP_CRY)
9184 pic16_toBoolean(cond);
9187 /* the result is now in the accumulator */
9188 pic16_freeAsmop(cond,NULL,ic,TRUE);
9190 /* if there was something to be popped then do it */
9194 /* if the condition is a bit variable */
9195 if (isbit && IS_ITEMP(cond) &&
9197 genIfxJump(ic,SPIL_LOC(cond)->rname);
9198 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9201 if (isbit && !IS_ITEMP(cond))
9202 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9210 /*-----------------------------------------------------------------*/
9211 /* genAddrOf - generates code for address of */
9212 /*-----------------------------------------------------------------*/
9213 static void genAddrOf (iCode *ic)
9215 operand *right, *result, *left;
9218 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9221 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9223 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9224 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9225 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9227 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9229 size = AOP_SIZE(IC_RESULT(ic));
9234 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9235 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9240 pic16_freeAsmop(left,NULL,ic,FALSE);
9241 pic16_freeAsmop(result,NULL,ic,TRUE);
9246 /*-----------------------------------------------------------------*/
9247 /* genFarFarAssign - assignment when both are in far space */
9248 /*-----------------------------------------------------------------*/
9249 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9251 int size = AOP_SIZE(right);
9254 /* first push the right side on to the stack */
9256 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9258 pic16_emitcode ("push","acc");
9261 pic16_freeAsmop(right,NULL,ic,FALSE);
9262 /* now assign DPTR to result */
9263 pic16_aopOp(result,ic,FALSE);
9264 size = AOP_SIZE(result);
9266 pic16_emitcode ("pop","acc");
9267 pic16_aopPut(AOP(result),"a",--offset);
9269 pic16_freeAsmop(result,NULL,ic,FALSE);
9274 /*-----------------------------------------------------------------*/
9275 /* genAssign - generate code for assignment */
9276 /*-----------------------------------------------------------------*/
9277 static void genAssign (iCode *ic)
9279 operand *result, *right;
9280 int size, offset,know_W;
9281 unsigned long lit = 0L;
9283 result = IC_RESULT(ic);
9284 right = IC_RIGHT(ic) ;
9286 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9288 /* if they are the same */
9289 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9292 pic16_aopOp(right,ic,FALSE);
9293 pic16_aopOp(result,ic,TRUE);
9295 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9297 /* if they are the same registers */
9298 if (pic16_sameRegs(AOP(right),AOP(result)))
9301 /* if the result is a bit */
9302 if (AOP_TYPE(result) == AOP_CRY) {
9303 /* if the right size is a literal then
9304 we know what the value is */
9305 if (AOP_TYPE(right) == AOP_LIT) {
9307 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9308 pic16_popGet(AOP(result),0));
9310 if (((int) operandLitValue(right)))
9311 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9312 AOP(result)->aopu.aop_dir,
9313 AOP(result)->aopu.aop_dir);
9315 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9316 AOP(result)->aopu.aop_dir,
9317 AOP(result)->aopu.aop_dir);
9321 /* the right is also a bit variable */
9322 if (AOP_TYPE(right) == AOP_CRY) {
9323 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9324 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9325 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9327 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9328 AOP(result)->aopu.aop_dir,
9329 AOP(result)->aopu.aop_dir);
9330 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9331 AOP(right)->aopu.aop_dir,
9332 AOP(right)->aopu.aop_dir);
9333 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9334 AOP(result)->aopu.aop_dir,
9335 AOP(result)->aopu.aop_dir);
9340 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9341 pic16_toBoolean(right);
9343 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9344 //pic16_aopPut(AOP(result),"a",0);
9348 /* bit variables done */
9350 size = AOP_SIZE(result);
9352 if(AOP_TYPE(right) == AOP_LIT)
9353 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9355 /* VR - What is this?! */
9356 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9357 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9358 if(aopIdx(AOP(result),0) == 4) {
9359 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9360 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9361 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9364 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9370 if(AOP_TYPE(right) == AOP_LIT) {
9372 if(know_W != (lit&0xff))
9373 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9375 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9377 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9381 } else if (AOP_TYPE(right) == AOP_CRY) {
9382 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9384 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9385 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9388 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9391 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9392 normally should work, but mind that thw W register live range
9393 is not checked, so if the code generator assumes that the W
9394 is already loaded after such a pair, wrong code will be generated.
9396 Checking the live range is the next step.
9397 This is experimental code yet and has not been fully tested yet.
9398 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9399 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9402 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9404 /* This is the old code, which is assumed(?!) that works fine(!?) */
9406 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9407 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9416 pic16_freeAsmop (right,NULL,ic,FALSE);
9417 pic16_freeAsmop (result,NULL,ic,TRUE);
9420 /*-----------------------------------------------------------------*/
9421 /* genJumpTab - generates code for jump table */
9422 /*-----------------------------------------------------------------*/
9423 static void genJumpTab (iCode *ic)
9428 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9430 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9431 /* get the condition into accumulator */
9432 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9434 /* multiply by three */
9435 pic16_emitcode("add","a,acc");
9436 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9438 jtab = newiTempLabel(NULL);
9439 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9440 pic16_emitcode("jmp","@a+dptr");
9441 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9443 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9444 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9446 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9447 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9448 pic16_emitpLabel(jtab->key);
9450 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9452 /* now generate the jump labels */
9453 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9454 jtab = setNextItem(IC_JTLABELS(ic))) {
9455 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9456 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9462 /*-----------------------------------------------------------------*/
9463 /* genMixedOperation - gen code for operators between mixed types */
9464 /*-----------------------------------------------------------------*/
9466 TSD - Written for the PIC port - but this unfortunately is buggy.
9467 This routine is good in that it is able to efficiently promote
9468 types to different (larger) sizes. Unfortunately, the temporary
9469 variables that are optimized out by this routine are sometimes
9470 used in other places. So until I know how to really parse the
9471 iCode tree, I'm going to not be using this routine :(.
9473 static int genMixedOperation (iCode *ic)
9476 operand *result = IC_RESULT(ic);
9477 sym_link *ctype = operandType(IC_LEFT(ic));
9478 operand *right = IC_RIGHT(ic);
9484 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9486 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9492 nextright = IC_RIGHT(nextic);
9493 nextleft = IC_LEFT(nextic);
9494 nextresult = IC_RESULT(nextic);
9496 pic16_aopOp(right,ic,FALSE);
9497 pic16_aopOp(result,ic,FALSE);
9498 pic16_aopOp(nextright, nextic, FALSE);
9499 pic16_aopOp(nextleft, nextic, FALSE);
9500 pic16_aopOp(nextresult, nextic, FALSE);
9502 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9508 pic16_emitcode(";remove right +","");
9510 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9516 pic16_emitcode(";remove left +","");
9520 big = AOP_SIZE(nextleft);
9521 small = AOP_SIZE(nextright);
9523 switch(nextic->op) {
9526 pic16_emitcode(";optimize a +","");
9527 /* if unsigned or not an integral type */
9528 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9529 pic16_emitcode(";add a bit to something","");
9532 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9534 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9535 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9536 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9538 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9546 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9547 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9548 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9551 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9553 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9554 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9555 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9556 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9557 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9560 pic16_emitcode("rlf","known_zero,w");
9567 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9568 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9569 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9571 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9581 pic16_freeAsmop(right,NULL,ic,TRUE);
9582 pic16_freeAsmop(result,NULL,ic,TRUE);
9583 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9584 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9586 nextic->generated = 1;
9593 /*-----------------------------------------------------------------*/
9594 /* genCast - gen code for casting */
9595 /*-----------------------------------------------------------------*/
9596 static void genCast (iCode *ic)
9598 operand *result = IC_RESULT(ic);
9599 sym_link *ctype = operandType(IC_LEFT(ic));
9600 sym_link *rtype = operandType(IC_RIGHT(ic));
9601 operand *right = IC_RIGHT(ic);
9604 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9605 /* if they are equivalent then do nothing */
9606 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9609 pic16_aopOp(right,ic,FALSE) ;
9610 pic16_aopOp(result,ic,FALSE);
9612 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9614 /* if the result is a bit */
9615 if (AOP_TYPE(result) == AOP_CRY) {
9616 /* if the right size is a literal then
9617 we know what the value is */
9618 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9619 if (AOP_TYPE(right) == AOP_LIT) {
9621 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9622 pic16_popGet(AOP(result),0));
9624 if (((int) operandLitValue(right)))
9625 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9626 AOP(result)->aopu.aop_dir,
9627 AOP(result)->aopu.aop_dir);
9629 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9630 AOP(result)->aopu.aop_dir,
9631 AOP(result)->aopu.aop_dir);
9636 /* the right is also a bit variable */
9637 if (AOP_TYPE(right) == AOP_CRY) {
9640 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9642 pic16_emitcode("clrc","");
9643 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9644 AOP(right)->aopu.aop_dir,
9645 AOP(right)->aopu.aop_dir);
9646 pic16_aopPut(AOP(result),"c",0);
9651 if (AOP_TYPE(right) == AOP_REG) {
9652 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9653 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9654 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9656 pic16_toBoolean(right);
9657 pic16_aopPut(AOP(result),"a",0);
9661 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9663 size = AOP_SIZE(result);
9665 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9667 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9668 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9669 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9672 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9677 /* if they are the same size : or less */
9678 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9680 /* if they are in the same place */
9681 if (pic16_sameRegs(AOP(right),AOP(result)))
9684 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9685 if (IS_PTR_CONST(rtype))
9686 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9687 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9688 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9690 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9691 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9692 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9693 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9694 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9695 if(AOP_SIZE(result) <2)
9696 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9700 /* if they in different places then copy */
9701 size = AOP_SIZE(result);
9704 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9705 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9707 //pic16_aopPut(AOP(result),
9708 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9718 /* if the result is of type pointer */
9719 if (IS_PTR(ctype)) {
9722 sym_link *type = operandType(right);
9723 sym_link *etype = getSpec(type);
9724 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9726 /* pointer to generic pointer */
9727 if (IS_GENPTR(ctype)) {
9731 p_type = DCL_TYPE(type);
9733 /* we have to go by the storage class */
9734 p_type = PTR_TYPE(SPEC_OCLS(etype));
9736 /* if (SPEC_OCLS(etype)->codesp ) */
9737 /* p_type = CPOINTER ; */
9739 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9740 /* p_type = FPOINTER ; */
9742 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9743 /* p_type = PPOINTER; */
9745 /* if (SPEC_OCLS(etype) == idata ) */
9746 /* p_type = IPOINTER ; */
9748 /* p_type = POINTER ; */
9751 /* the first two bytes are known */
9752 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9753 size = GPTRSIZE - 1;
9756 if(offset < AOP_SIZE(right)) {
9757 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9758 if ((AOP_TYPE(right) == AOP_PCODE) &&
9759 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9760 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9761 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9763 pic16_aopPut(AOP(result),
9764 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9768 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9771 /* the last byte depending on type */
9775 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9778 pic16_emitcode(";BUG!? ","%d",__LINE__);
9782 pic16_emitcode(";BUG!? ","%d",__LINE__);
9786 pic16_emitcode(";BUG!? ","%d",__LINE__);
9791 /* this should never happen */
9792 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9793 "got unknown pointer type");
9796 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9800 /* just copy the pointers */
9801 size = AOP_SIZE(result);
9804 pic16_aopPut(AOP(result),
9805 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9814 /* so we now know that the size of destination is greater
9815 than the size of the source.
9816 Now, if the next iCode is an operator then we might be
9817 able to optimize the operation without performing a cast.
9819 if(genMixedOperation(ic))
9822 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9824 /* we move to result for the size of source */
9825 size = AOP_SIZE(right);
9828 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9829 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9833 /* now depending on the sign of the destination */
9834 size = AOP_SIZE(result) - AOP_SIZE(right);
9835 /* if unsigned or not an integral type */
9836 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9838 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9840 /* we need to extend the sign :{ */
9843 /* Save one instruction of casting char to int */
9844 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9845 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9846 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
9848 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9851 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9853 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9855 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9858 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
9863 pic16_freeAsmop(right,NULL,ic,TRUE);
9864 pic16_freeAsmop(result,NULL,ic,TRUE);
9868 /*-----------------------------------------------------------------*/
9869 /* genDjnz - generate decrement & jump if not zero instrucion */
9870 /*-----------------------------------------------------------------*/
9871 static int genDjnz (iCode *ic, iCode *ifx)
9874 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9879 /* if the if condition has a false label
9880 then we cannot save */
9884 /* if the minus is not of the form
9886 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9887 !IS_OP_LITERAL(IC_RIGHT(ic)))
9890 if (operandLitValue(IC_RIGHT(ic)) != 1)
9893 /* if the size of this greater than one then no
9895 if (getSize(operandType(IC_RESULT(ic))) > 1)
9898 /* otherwise we can save BIG */
9899 lbl = newiTempLabel(NULL);
9900 lbl1= newiTempLabel(NULL);
9902 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9904 if (IS_AOP_PREG(IC_RESULT(ic))) {
9905 pic16_emitcode("dec","%s",
9906 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9907 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9908 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9912 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9913 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9915 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9916 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9919 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9920 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9921 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9922 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9925 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9930 /*-----------------------------------------------------------------*/
9931 /* genReceive - generate code for a receive iCode */
9932 /*-----------------------------------------------------------------*/
9933 static void genReceive (iCode *ic)
9935 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9937 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9938 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9939 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9941 int size = getSize(operandType(IC_RESULT(ic)));
9942 int offset = pic16_fReturnSizePic - size;
9944 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9945 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9948 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9949 size = AOP_SIZE(IC_RESULT(ic));
9952 pic16_emitcode ("pop","acc");
9953 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9958 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9960 assignResultValue(IC_RESULT(ic));
9963 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9966 /*-----------------------------------------------------------------*/
9967 /* genpic16Code - generate code for pic16 based controllers */
9968 /*-----------------------------------------------------------------*/
9970 * At this point, ralloc.c has gone through the iCode and attempted
9971 * to optimize in a way suitable for a PIC. Now we've got to generate
9972 * PIC instructions that correspond to the iCode.
9974 * Once the instructions are generated, we'll pass through both the
9975 * peep hole optimizer and the pCode optimizer.
9976 *-----------------------------------------------------------------*/
9978 void genpic16Code (iCode *lic)
9983 lineHead = lineCurr = NULL;
9985 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9986 pic16_addpBlock(pb);
9989 /* if debug information required */
9990 if (options.debug && currFunc) {
9992 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9994 if (IS_STATIC(currFunc->etype)) {
9995 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9996 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9998 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9999 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10008 for (ic = lic ; ic ; ic = ic->next ) {
10010 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10011 // DEBUGpic16_emitcode("; VR", "");
10012 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10013 if ( cln != ic->lineno ) {
10014 if ( options.debug ) {
10016 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10017 FileBaseName(ic->filename),ic->lineno,
10018 ic->level,ic->block);
10022 pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
10023 pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
10024 printCLine(ic->filename, ic->lineno));
10026 pic16_addpCode2pBlock(pb,
10027 pic16_newpCodeCSource(ic->lineno,
10029 printCLine(ic->filename, ic->lineno)));
10033 /* if the result is marked as
10034 spilt and rematerializable or code for
10035 this has already been generated then
10037 if (resultRemat(ic) || ic->generated )
10040 /* depending on the operation */
10059 /* IPOP happens only when trying to restore a
10060 spilt live range, if there is an ifx statement
10061 following this pop then the if statement might
10062 be using some of the registers being popped which
10063 would destroy the contents of the register so
10064 we need to check for this condition and handle it */
10066 ic->next->op == IFX &&
10067 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10068 genIfx (ic->next,ic);
10086 genEndFunction (ic);
10102 pic16_genPlus (ic) ;
10106 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10107 pic16_genMinus (ic);
10123 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10127 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10134 /* note these two are xlated by algebraic equivalence
10135 during parsing SDCC.y */
10136 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10137 "got '>=' or '<=' shouldn't have come here");
10141 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10153 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10157 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10161 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10185 genRightShift (ic);
10188 case GET_VALUE_AT_ADDRESS:
10193 if (POINTER_SET(ic))
10220 addSet(&_G.sendSet,ic);
10229 /* now we are ready to call the
10230 peep hole optimizer */
10231 if (!options.nopeep) {
10232 peepHole (&lineHead);
10234 /* now do the actual printing */
10235 printLine (lineHead,codeOutFile);
10238 DFPRINTF((stderr,"printing pBlock\n\n"));
10239 pic16_printpBlock(stdout,pb);