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;
293 //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);
1275 //fprintf(stderr, "allocating new register -> %s\n", str);
1276 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1278 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1280 PCOR(pcop)->instance = offset;
1285 static pCodeOp *popRegFromIdx(int rIdx)
1289 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1290 __FUNCTION__,__LINE__,rIdx);
1292 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1294 PCOR(pcop)->rIdx = rIdx;
1295 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1296 PCOR(pcop)->r->isFree = 0;
1297 PCOR(pcop)->r->wasUsed = 1;
1299 pcop->type = PCOR(pcop)->r->pc_type;
1305 /*---------------------------------------------------------------------------------*/
1306 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1308 /*---------------------------------------------------------------------------------*/
1309 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1314 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1315 temp = pic16_popGet(aop_dst, offset);
1316 pcop2->pcop2 = temp;
1322 /*-----------------------------------------------------------------*/
1323 /* pic16_popGet - asm operator to pcode operator conversion */
1324 /*-----------------------------------------------------------------*/
1325 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1327 //char *s = buffer ;
1332 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1333 /* offset is greater than
1336 if (offset > (aop->size - 1) &&
1337 aop->type != AOP_LIT)
1338 return NULL; //zero;
1340 /* depending on type */
1341 switch (aop->type) {
1348 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1352 DEBUGpic16_emitcode(";","%d",__LINE__);
1353 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1356 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1359 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1360 pcop->type = PO_DIR;
1364 sprintf(s,"(%s + %d)",
1368 sprintf(s,"%s",aop->aopu.aop_dir);
1369 pcop->name = Safe_calloc(1,strlen(s)+1);
1370 strcpy(pcop->name,s);
1372 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1373 strcpy(pcop->name,aop->aopu.aop_dir);
1374 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1375 if(PCOR(pcop)->r == NULL) {
1376 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1377 PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1378 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1380 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1382 PCOR(pcop)->instance = offset;
1389 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1391 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1392 PCOR(pcop)->rIdx = rIdx;
1393 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1394 PCOR(pcop)->r->wasUsed=1;
1395 PCOR(pcop)->r->isFree=0;
1397 PCOR(pcop)->instance = offset;
1398 pcop->type = PCOR(pcop)->r->pc_type;
1399 //rs = aop->aopu.aop_reg[offset]->name;
1400 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1405 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1406 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1407 //if(PCOR(pcop)->r == NULL)
1408 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1412 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1415 DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1416 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1418 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1419 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1420 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1421 pcop->type = PCOR(pcop)->r->pc_type;
1422 pcop->name = PCOR(pcop)->r->name;
1428 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1430 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1431 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1432 PCOI(pcop)->offset = offset;
1436 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1437 "pic16_popGet got unsupported aop->type");
1440 /*-----------------------------------------------------------------*/
1441 /* pic16_aopPut - puts a string for a aop */
1442 /*-----------------------------------------------------------------*/
1443 void pic16_aopPut (asmop *aop, char *s, int offset)
1448 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1450 if (aop->size && offset > ( aop->size - 1)) {
1451 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1452 "pic16_aopPut got offset > aop->size");
1456 /* will assign value to value */
1457 /* depending on where it is ofcourse */
1458 switch (aop->type) {
1461 sprintf(d,"(%s + %d)",
1462 aop->aopu.aop_dir,offset);
1463 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1466 sprintf(d,"%s",aop->aopu.aop_dir);
1469 DEBUGpic16_emitcode(";","%d",__LINE__);
1471 pic16_emitcode("movf","%s,w",s);
1472 pic16_emitcode("movwf","%s",d);
1475 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1476 if(offset >= aop->size) {
1477 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1480 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1483 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1490 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1491 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1494 strcmp(s,"r0") == 0 ||
1495 strcmp(s,"r1") == 0 ||
1496 strcmp(s,"r2") == 0 ||
1497 strcmp(s,"r3") == 0 ||
1498 strcmp(s,"r4") == 0 ||
1499 strcmp(s,"r5") == 0 ||
1500 strcmp(s,"r6") == 0 ||
1501 strcmp(s,"r7") == 0 )
1502 pic16_emitcode("mov","%s,%s ; %d",
1503 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1507 if(strcmp(s,"W")==0 )
1508 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1510 pic16_emitcode("movwf","%s",
1511 aop->aopu.aop_reg[offset]->name);
1513 if(strcmp(s,zero)==0) {
1514 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1516 } else if(strcmp(s,"W")==0) {
1517 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1518 pcop->type = PO_GPR_REGISTER;
1520 PCOR(pcop)->rIdx = -1;
1521 PCOR(pcop)->r = NULL;
1523 DEBUGpic16_emitcode(";","%d",__LINE__);
1524 pcop->name = Safe_strdup(s);
1525 pic16_emitpcode(POC_MOVFW,pcop);
1526 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1527 } else if(strcmp(s,one)==0) {
1528 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1529 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1531 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1539 if (aop->type == AOP_DPTR2)
1545 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1546 "pic16_aopPut writting to code space");
1550 while (offset > aop->coff) {
1552 pic16_emitcode ("inc","dptr");
1555 while (offset < aop->coff) {
1557 pic16_emitcode("lcall","__decdptr");
1562 /* if not in accumulater */
1565 pic16_emitcode ("movx","@dptr,a");
1567 if (aop->type == AOP_DPTR2)
1575 while (offset > aop->coff) {
1577 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1579 while (offset < aop->coff) {
1581 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1587 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1592 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1594 if (strcmp(s,"r0") == 0 ||
1595 strcmp(s,"r1") == 0 ||
1596 strcmp(s,"r2") == 0 ||
1597 strcmp(s,"r3") == 0 ||
1598 strcmp(s,"r4") == 0 ||
1599 strcmp(s,"r5") == 0 ||
1600 strcmp(s,"r6") == 0 ||
1601 strcmp(s,"r7") == 0 ) {
1603 sprintf(buffer,"a%s",s);
1604 pic16_emitcode("mov","@%s,%s",
1605 aop->aopu.aop_ptr->name,buffer);
1607 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1612 if (strcmp(s,"a") == 0)
1613 pic16_emitcode("push","acc");
1615 pic16_emitcode("push","%s",s);
1620 /* if bit variable */
1621 if (!aop->aopu.aop_dir) {
1622 pic16_emitcode("clr","a");
1623 pic16_emitcode("rlc","a");
1626 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1629 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1632 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1634 lbl = newiTempLabel(NULL);
1636 if (strcmp(s,"a")) {
1639 pic16_emitcode("clr","c");
1640 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1641 pic16_emitcode("cpl","c");
1642 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1643 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1650 if (strcmp(aop->aopu.aop_str[offset],s))
1651 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1656 if (!offset && (strcmp(s,"acc") == 0))
1659 if (strcmp(aop->aopu.aop_str[offset],s))
1660 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1664 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1665 "pic16_aopPut got unsupported aop->type");
1671 /*-----------------------------------------------------------------*/
1672 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1673 /*-----------------------------------------------------------------*/
1674 static void mov2w (asmop *aop, int offset)
1680 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1682 if ( aop->type == AOP_PCODE ||
1683 aop->type == AOP_LIT )
1684 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1686 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1690 /*-----------------------------------------------------------------*/
1691 /* reAdjustPreg - points a register back to where it should */
1692 /*-----------------------------------------------------------------*/
1693 static void reAdjustPreg (asmop *aop)
1697 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1699 if ((size = aop->size) <= 1)
1702 switch (aop->type) {
1706 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1710 if (aop->type == AOP_DPTR2)
1716 pic16_emitcode("lcall","__decdptr");
1719 if (aop->type == AOP_DPTR2)
1729 /*-----------------------------------------------------------------*/
1730 /* genNotFloat - generates not for float operations */
1731 /*-----------------------------------------------------------------*/
1732 static void genNotFloat (operand *op, operand *res)
1738 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1739 /* we will put 127 in the first byte of
1741 pic16_aopPut(AOP(res),"#127",0);
1742 size = AOP_SIZE(op) - 1;
1745 l = pic16_aopGet(op->aop,offset++,FALSE,FALSE);
1749 pic16_emitcode("orl","a,%s",
1750 pic16_aopGet(op->aop,
1751 offset++,FALSE,FALSE));
1753 tlbl = newiTempLabel(NULL);
1755 tlbl = newiTempLabel(NULL);
1756 pic16_aopPut(res->aop,one,1);
1757 pic16_emitcode("jz","%05d_DS_",(tlbl->key+100));
1758 pic16_aopPut(res->aop,zero,1);
1759 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
1761 size = res->aop->size - 2;
1763 /* put zeros in the rest */
1765 pic16_aopPut(res->aop,zero,offset++);
1769 /*-----------------------------------------------------------------*/
1770 /* opIsGptr: returns non-zero if the passed operand is */
1771 /* a generic pointer type. */
1772 /*-----------------------------------------------------------------*/
1773 static int opIsGptr(operand *op)
1775 sym_link *type = operandType(op);
1777 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1778 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1786 /*-----------------------------------------------------------------*/
1787 /* pic16_getDataSize - get the operand data size */
1788 /*-----------------------------------------------------------------*/
1789 int pic16_getDataSize(operand *op)
1791 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1794 return AOP_SIZE(op);
1796 // tsd- in the pic port, the genptr size is 1, so this code here
1797 // fails. ( in the 8051 port, the size was 4).
1800 size = AOP_SIZE(op);
1801 if (size == GPTRSIZE)
1803 sym_link *type = operandType(op);
1804 if (IS_GENPTR(type))
1806 /* generic pointer; arithmetic operations
1807 * should ignore the high byte (pointer type).
1810 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1817 /*-----------------------------------------------------------------*/
1818 /* pic16_outAcc - output Acc */
1819 /*-----------------------------------------------------------------*/
1820 void pic16_outAcc(operand *result)
1823 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1824 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1827 size = pic16_getDataSize(result);
1829 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1832 /* unsigned or positive */
1834 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1839 /*-----------------------------------------------------------------*/
1840 /* pic16_outBitC - output a bit C */
1841 /*-----------------------------------------------------------------*/
1842 void pic16_outBitC(operand *result)
1845 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1846 /* if the result is bit */
1847 if (AOP_TYPE(result) == AOP_CRY)
1848 pic16_aopPut(AOP(result),"c",0);
1850 pic16_emitcode("clr","a ; %d", __LINE__);
1851 pic16_emitcode("rlc","a");
1852 pic16_outAcc(result);
1856 /*-----------------------------------------------------------------*/
1857 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1858 /*-----------------------------------------------------------------*/
1859 void pic16_toBoolean(operand *oper)
1861 int size = AOP_SIZE(oper) - 1;
1864 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1866 if ( AOP_TYPE(oper) != AOP_ACC) {
1867 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1870 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1875 /*-----------------------------------------------------------------*/
1876 /* genNot - generate code for ! operation */
1877 /*-----------------------------------------------------------------*/
1878 static void genNot (iCode *ic)
1881 sym_link *optype = operandType(IC_LEFT(ic));
1884 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1885 /* assign asmOps to operand & result */
1886 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1887 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1889 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1890 /* if in bit space then a special case */
1891 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1892 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1893 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1894 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1896 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1897 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1898 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1903 /* if type float then do float */
1904 if (IS_FLOAT(optype)) {
1905 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1909 size = AOP_SIZE(IC_RESULT(ic));
1911 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1912 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1913 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1916 pic16_toBoolean(IC_LEFT(ic));
1918 tlbl = newiTempLabel(NULL);
1919 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1920 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1921 pic16_outBitC(IC_RESULT(ic));
1924 /* release the aops */
1925 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1926 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1930 /*-----------------------------------------------------------------*/
1931 /* genCpl - generate code for complement */
1932 /*-----------------------------------------------------------------*/
1933 static void genCpl (iCode *ic)
1939 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1940 /* assign asmOps to operand & result */
1941 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1942 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1944 /* if both are in bit space then
1946 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1947 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1949 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1950 pic16_emitcode("cpl","c");
1951 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1955 size = AOP_SIZE(IC_RESULT(ic));
1958 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1960 pic16_emitcode("cpl","a");
1961 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1963 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1964 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
1966 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1967 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1975 /* release the aops */
1976 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1977 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1980 /*-----------------------------------------------------------------*/
1981 /* genUminusFloat - unary minus for floating points */
1982 /*-----------------------------------------------------------------*/
1983 static void genUminusFloat(operand *op,operand *result)
1985 int size ,offset =0 ;
1988 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1989 /* for this we just need to flip the
1990 first it then copy the rest in place */
1991 size = AOP_SIZE(op) - 1;
1992 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1996 pic16_emitcode("cpl","acc.7");
1997 pic16_aopPut(AOP(result),"a",3);
2000 pic16_aopPut(AOP(result),
2001 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
2007 /*-----------------------------------------------------------------*/
2008 /* genUminus - unary minus code generation */
2009 /*-----------------------------------------------------------------*/
2010 static void genUminus (iCode *ic)
2013 sym_link *optype, *rtype;
2016 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2018 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2019 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
2021 /* if both in bit space then special
2023 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2024 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2026 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2027 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2028 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2033 optype = operandType(IC_LEFT(ic));
2034 rtype = operandType(IC_RESULT(ic));
2036 /* if float then do float stuff */
2037 if (IS_FLOAT(optype)) {
2038 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2042 /* otherwise subtract from zero by taking the 2's complement */
2043 size = AOP_SIZE(IC_LEFT(ic));
2045 for(i=0; i<size; i++) {
2046 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2047 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2049 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2050 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2054 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2055 for(i=1; i<size; i++) {
2057 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2061 /* release the aops */
2062 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2063 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2066 /*-----------------------------------------------------------------*/
2067 /* saveRegisters - will look for a call and save the registers */
2068 /*-----------------------------------------------------------------*/
2069 static void saveRegisters(iCode *lic)
2076 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2078 for (ic = lic ; ic ; ic = ic->next)
2079 if (ic->op == CALL || ic->op == PCALL)
2083 fprintf(stderr,"found parameter push with no function call\n");
2087 /* if the registers have been saved already then
2089 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2092 /* find the registers in use at this time
2093 and push them away to safety */
2094 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2098 if (options.useXstack) {
2099 if (bitVectBitValue(rsave,R0_IDX))
2100 pic16_emitcode("mov","b,r0");
2101 pic16_emitcode("mov","r0,%s",spname);
2102 for (i = 0 ; i < pic16_nRegs ; i++) {
2103 if (bitVectBitValue(rsave,i)) {
2105 pic16_emitcode("mov","a,b");
2107 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2108 pic16_emitcode("movx","@r0,a");
2109 pic16_emitcode("inc","r0");
2112 pic16_emitcode("mov","%s,r0",spname);
2113 if (bitVectBitValue(rsave,R0_IDX))
2114 pic16_emitcode("mov","r0,b");
2116 //for (i = 0 ; i < pic16_nRegs ; i++) {
2117 // if (bitVectBitValue(rsave,i))
2118 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2121 dtype = operandType(IC_LEFT(ic));
2122 if (currFunc && dtype &&
2123 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2124 IFFUNC_ISISR(currFunc->type) &&
2127 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2130 /*-----------------------------------------------------------------*/
2131 /* unsaveRegisters - pop the pushed registers */
2132 /*-----------------------------------------------------------------*/
2133 static void unsaveRegisters (iCode *ic)
2138 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2139 /* find the registers in use at this time
2140 and push them away to safety */
2141 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2144 if (options.useXstack) {
2145 pic16_emitcode("mov","r0,%s",spname);
2146 for (i = pic16_nRegs ; i >= 0 ; i--) {
2147 if (bitVectBitValue(rsave,i)) {
2148 pic16_emitcode("dec","r0");
2149 pic16_emitcode("movx","a,@r0");
2151 pic16_emitcode("mov","b,a");
2153 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2157 pic16_emitcode("mov","%s,r0",spname);
2158 if (bitVectBitValue(rsave,R0_IDX))
2159 pic16_emitcode("mov","r0,b");
2161 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2162 // if (bitVectBitValue(rsave,i))
2163 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2169 /*-----------------------------------------------------------------*/
2171 /*-----------------------------------------------------------------*/
2172 static void pushSide(operand * oper, int size)
2176 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2178 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2179 if (AOP_TYPE(oper) != AOP_REG &&
2180 AOP_TYPE(oper) != AOP_DIR &&
2182 pic16_emitcode("mov","a,%s",l);
2183 pic16_emitcode("push","acc");
2185 pic16_emitcode("push","%s",l);
2190 /*-----------------------------------------------------------------*/
2191 /* assignResultValue - */
2192 /*-----------------------------------------------------------------*/
2193 static void assignResultValue(operand * oper)
2195 int size = AOP_SIZE(oper);
2197 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2199 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2201 if(!GpsuedoStkPtr) {
2202 /* The last byte in the assignment is in W */
2204 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2209 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2211 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2216 /*-----------------------------------------------------------------*/
2217 /* genIpush - genrate code for pushing this gets a little complex */
2218 /*-----------------------------------------------------------------*/
2219 static void genIpush (iCode *ic)
2222 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2224 int size, offset = 0 ;
2228 /* if this is not a parm push : ie. it is spill push
2229 and spill push is always done on the local stack */
2230 if (!ic->parmPush) {
2232 /* and the item is spilt then do nothing */
2233 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2236 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2237 size = AOP_SIZE(IC_LEFT(ic));
2238 /* push it on the stack */
2240 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2245 pic16_emitcode("push","%s",l);
2250 /* this is a paramter push: in this case we call
2251 the routine to find the call and save those
2252 registers that need to be saved */
2255 /* then do the push */
2256 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2259 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2260 size = AOP_SIZE(IC_LEFT(ic));
2263 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2264 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2265 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2267 pic16_emitcode("mov","a,%s",l);
2268 pic16_emitcode("push","acc");
2270 pic16_emitcode("push","%s",l);
2273 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2277 /*-----------------------------------------------------------------*/
2278 /* genIpop - recover the registers: can happen only for spilling */
2279 /*-----------------------------------------------------------------*/
2280 static void genIpop (iCode *ic)
2282 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2287 /* if the temp was not pushed then */
2288 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2291 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2292 size = AOP_SIZE(IC_LEFT(ic));
2295 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2298 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2302 /*-----------------------------------------------------------------*/
2303 /* unsaverbank - restores the resgister bank from stack */
2304 /*-----------------------------------------------------------------*/
2305 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2307 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2313 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2315 if (options.useXstack) {
2317 r = getFreePtr(ic,&aop,FALSE);
2320 pic16_emitcode("mov","%s,_spx",r->name);
2321 pic16_emitcode("movx","a,@%s",r->name);
2322 pic16_emitcode("mov","psw,a");
2323 pic16_emitcode("dec","%s",r->name);
2326 pic16_emitcode ("pop","psw");
2329 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2330 if (options.useXstack) {
2331 pic16_emitcode("movx","a,@%s",r->name);
2332 //pic16_emitcode("mov","(%s+%d),a",
2333 // regspic16[i].base,8*bank+regspic16[i].offset);
2334 pic16_emitcode("dec","%s",r->name);
2337 pic16_emitcode("pop",""); //"(%s+%d)",
2338 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2341 if (options.useXstack) {
2343 pic16_emitcode("mov","_spx,%s",r->name);
2344 pic16_freeAsmop(NULL,aop,ic,TRUE);
2350 /*-----------------------------------------------------------------*/
2351 /* saverbank - saves an entire register bank on the stack */
2352 /*-----------------------------------------------------------------*/
2353 static void saverbank (int bank, iCode *ic, bool pushPsw)
2355 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2361 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2362 if (options.useXstack) {
2365 r = getFreePtr(ic,&aop,FALSE);
2366 pic16_emitcode("mov","%s,_spx",r->name);
2370 for (i = 0 ; i < pic16_nRegs ;i++) {
2371 if (options.useXstack) {
2372 pic16_emitcode("inc","%s",r->name);
2373 //pic16_emitcode("mov","a,(%s+%d)",
2374 // regspic16[i].base,8*bank+regspic16[i].offset);
2375 pic16_emitcode("movx","@%s,a",r->name);
2377 pic16_emitcode("push","");// "(%s+%d)",
2378 //regspic16[i].base,8*bank+regspic16[i].offset);
2382 if (options.useXstack) {
2383 pic16_emitcode("mov","a,psw");
2384 pic16_emitcode("movx","@%s,a",r->name);
2385 pic16_emitcode("inc","%s",r->name);
2386 pic16_emitcode("mov","_spx,%s",r->name);
2387 pic16_freeAsmop (NULL,aop,ic,TRUE);
2390 pic16_emitcode("push","psw");
2392 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2398 /*-----------------------------------------------------------------*/
2399 /* genCall - generates a call statement */
2400 /*-----------------------------------------------------------------*/
2401 static void genCall (iCode *ic)
2405 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2407 /* if caller saves & we have not saved then */
2411 /* if we are calling a function that is not using
2412 the same register bank then we need to save the
2413 destination registers on the stack */
2414 dtype = operandType(IC_LEFT(ic));
2415 if (currFunc && dtype &&
2416 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2417 IFFUNC_ISISR(currFunc->type) &&
2420 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2422 /* if send set is not empty the assign */
2425 /* For the Pic port, there is no data stack.
2426 * So parameters passed to functions are stored
2427 * in registers. (The pCode optimizer will get
2428 * rid of most of these :).
2430 int psuedoStkPtr=-1;
2431 int firstTimeThruLoop = 1;
2433 _G.sendSet = reverseSet(_G.sendSet);
2435 /* First figure how many parameters are getting passed */
2436 for (sic = setFirstItem(_G.sendSet) ; sic ;
2437 sic = setNextItem(_G.sendSet)) {
2439 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2440 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2441 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2444 for (sic = setFirstItem(_G.sendSet) ; sic ;
2445 sic = setNextItem(_G.sendSet)) {
2446 int size, offset = 0;
2448 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2449 size = AOP_SIZE(IC_LEFT(sic));
2452 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2453 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2455 if(!firstTimeThruLoop) {
2456 /* If this is not the first time we've been through the loop
2457 * then we need to save the parameter in a temporary
2458 * register. The last byte of the last parameter is
2460 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2463 firstTimeThruLoop=0;
2465 //if (strcmp(l,fReturn[offset])) {
2466 mov2w (AOP(IC_LEFT(sic)), offset);
2468 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2469 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2470 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2472 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2477 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2482 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2483 OP_SYMBOL(IC_LEFT(ic))->rname :
2484 OP_SYMBOL(IC_LEFT(ic))->name));
2487 /* if we need assign a result value */
2488 if ((IS_ITEMP(IC_RESULT(ic)) &&
2489 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2490 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2491 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2494 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2497 assignResultValue(IC_RESULT(ic));
2499 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2500 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2502 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2505 /* adjust the stack for parameters if
2507 if (ic->parmBytes) {
2509 if (ic->parmBytes > 3) {
2510 pic16_emitcode("mov","a,%s",spname);
2511 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2512 pic16_emitcode("mov","%s,a",spname);
2514 for ( i = 0 ; i < ic->parmBytes ;i++)
2515 pic16_emitcode("dec","%s",spname);
2519 /* if register bank was saved then pop them */
2521 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2523 /* if we hade saved some registers then unsave them */
2524 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2525 unsaveRegisters (ic);
2530 /*-----------------------------------------------------------------*/
2531 /* genPcall - generates a call by pointer statement */
2532 /*-----------------------------------------------------------------*/
2533 static void genPcall (iCode *ic)
2536 symbol *rlbl = newiTempLabel(NULL);
2539 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2540 /* if caller saves & we have not saved then */
2544 /* if we are calling a function that is not using
2545 the same register bank then we need to save the
2546 destination registers on the stack */
2547 dtype = operandType(IC_LEFT(ic));
2548 if (currFunc && dtype &&
2549 IFFUNC_ISISR(currFunc->type) &&
2550 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2551 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2554 /* push the return address on to the stack */
2555 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2556 pic16_emitcode("push","acc");
2557 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2558 pic16_emitcode("push","acc");
2560 if (options.model == MODEL_FLAT24)
2562 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2563 pic16_emitcode("push","acc");
2566 /* now push the calling address */
2567 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2569 pushSide(IC_LEFT(ic), FPTRSIZE);
2571 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2573 /* if send set is not empty the assign */
2577 for (sic = setFirstItem(_G.sendSet) ; sic ;
2578 sic = setNextItem(_G.sendSet)) {
2579 int size, offset = 0;
2580 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2581 size = AOP_SIZE(IC_LEFT(sic));
2583 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2585 if (strcmp(l,fReturn[offset]))
2586 pic16_emitcode("mov","%s,%s",
2591 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2596 pic16_emitcode("ret","");
2597 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2600 /* if we need assign a result value */
2601 if ((IS_ITEMP(IC_RESULT(ic)) &&
2602 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2603 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2604 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2607 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2610 assignResultValue(IC_RESULT(ic));
2612 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2615 /* adjust the stack for parameters if
2617 if (ic->parmBytes) {
2619 if (ic->parmBytes > 3) {
2620 pic16_emitcode("mov","a,%s",spname);
2621 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2622 pic16_emitcode("mov","%s,a",spname);
2624 for ( i = 0 ; i < ic->parmBytes ;i++)
2625 pic16_emitcode("dec","%s",spname);
2629 /* if register bank was saved then unsave them */
2630 if (currFunc && dtype &&
2631 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2632 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2634 /* if we hade saved some registers then
2637 unsaveRegisters (ic);
2641 /*-----------------------------------------------------------------*/
2642 /* resultRemat - result is rematerializable */
2643 /*-----------------------------------------------------------------*/
2644 static int resultRemat (iCode *ic)
2646 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2647 if (SKIP_IC(ic) || ic->op == IFX)
2650 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2651 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2652 if (sym->remat && !POINTER_SET(ic))
2659 #if defined(__BORLANDC__) || defined(_MSC_VER)
2660 #define STRCASECMP stricmp
2662 #define STRCASECMP strcasecmp
2666 /*-----------------------------------------------------------------*/
2667 /* inExcludeList - return 1 if the string is in exclude Reg list */
2668 /*-----------------------------------------------------------------*/
2669 static bool inExcludeList(char *s)
2671 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2674 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2675 if (options.excludeRegs[i] &&
2676 STRCASECMP(options.excludeRegs[i],"none") == 0)
2679 for ( i = 0 ; options.excludeRegs[i]; i++) {
2680 if (options.excludeRegs[i] &&
2681 STRCASECMP(s,options.excludeRegs[i]) == 0)
2688 /*-----------------------------------------------------------------*/
2689 /* genFunction - generated code for function entry */
2690 /*-----------------------------------------------------------------*/
2691 static void genFunction (iCode *ic)
2696 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2698 labelOffset += (max_key+4);
2702 /* create the function header */
2703 pic16_emitcode(";","-----------------------------------------");
2704 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2705 pic16_emitcode(";","-----------------------------------------");
2707 pic16_emitcode("","%s:",sym->rname);
2708 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2710 ftype = operandType(IC_LEFT(ic));
2712 /* if critical function then turn interrupts off */
2713 if (IFFUNC_ISCRITICAL(ftype))
2714 pic16_emitcode("clr","ea");
2716 /* here we need to generate the equates for the
2717 register bank if required */
2719 if (FUNC_REGBANK(ftype) != rbank) {
2722 rbank = FUNC_REGBANK(ftype);
2723 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2724 if (strcmp(regspic16[i].base,"0") == 0)
2725 pic16_emitcode("","%s = 0x%02x",
2727 8*rbank+regspic16[i].offset);
2729 pic16_emitcode ("","%s = %s + 0x%02x",
2732 8*rbank+regspic16[i].offset);
2737 /* if this is an interrupt service routine then
2738 save acc, b, dpl, dph */
2739 if (IFFUNC_ISISR(sym->type)) {
2740 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2741 pic16_emitpcodeNULLop(POC_NOP);
2742 pic16_emitpcodeNULLop(POC_NOP);
2743 pic16_emitpcodeNULLop(POC_NOP);
2744 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2745 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2746 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2747 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2749 pic16_pBlockConvert2ISR(pb);
2751 if (!inExcludeList("acc"))
2752 pic16_emitcode ("push","acc");
2753 if (!inExcludeList("b"))
2754 pic16_emitcode ("push","b");
2755 if (!inExcludeList("dpl"))
2756 pic16_emitcode ("push","dpl");
2757 if (!inExcludeList("dph"))
2758 pic16_emitcode ("push","dph");
2759 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2761 pic16_emitcode ("push", "dpx");
2762 /* Make sure we're using standard DPTR */
2763 pic16_emitcode ("push", "dps");
2764 pic16_emitcode ("mov", "dps, #0x00");
2765 if (options.stack10bit)
2767 /* This ISR could conceivably use DPTR2. Better save it. */
2768 pic16_emitcode ("push", "dpl1");
2769 pic16_emitcode ("push", "dph1");
2770 pic16_emitcode ("push", "dpx1");
2773 /* if this isr has no bank i.e. is going to
2774 run with bank 0 , then we need to save more
2776 if (!FUNC_REGBANK(sym->type)) {
2778 /* if this function does not call any other
2779 function then we can be economical and
2780 save only those registers that are used */
2781 if (! IFFUNC_HASFCALL(sym->type)) {
2784 /* if any registers used */
2785 if (sym->regsUsed) {
2786 /* save the registers used */
2787 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2788 if (bitVectBitValue(sym->regsUsed,i) ||
2789 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2790 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2795 /* this function has a function call cannot
2796 determines register usage so we will have the
2798 saverbank(0,ic,FALSE);
2803 /* if callee-save to be used for this function
2804 then save the registers being used in this function */
2805 if (IFFUNC_CALLEESAVES(sym->type)) {
2808 /* if any registers used */
2809 if (sym->regsUsed) {
2810 /* save the registers used */
2811 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2812 if (bitVectBitValue(sym->regsUsed,i) ||
2813 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2814 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2822 /* set the register bank to the desired value */
2823 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2824 pic16_emitcode("push","psw");
2825 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2828 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2830 if (options.useXstack) {
2831 pic16_emitcode("mov","r0,%s",spname);
2832 pic16_emitcode("mov","a,_bp");
2833 pic16_emitcode("movx","@r0,a");
2834 pic16_emitcode("inc","%s",spname);
2838 /* set up the stack */
2839 pic16_emitcode ("push","_bp"); /* save the callers stack */
2841 pic16_emitcode ("mov","_bp,%s",spname);
2844 /* adjust the stack for the function */
2849 werror(W_STACK_OVERFLOW,sym->name);
2851 if (i > 3 && sym->recvSize < 4) {
2853 pic16_emitcode ("mov","a,sp");
2854 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2855 pic16_emitcode ("mov","sp,a");
2860 pic16_emitcode("inc","sp");
2865 pic16_emitcode ("mov","a,_spx");
2866 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2867 pic16_emitcode ("mov","_spx,a");
2872 /*-----------------------------------------------------------------*/
2873 /* genEndFunction - generates epilogue for functions */
2874 /*-----------------------------------------------------------------*/
2875 static void genEndFunction (iCode *ic)
2877 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2879 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2881 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2883 pic16_emitcode ("mov","%s,_bp",spname);
2886 /* if use external stack but some variables were
2887 added to the local stack then decrement the
2889 if (options.useXstack && sym->stack) {
2890 pic16_emitcode("mov","a,sp");
2891 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2892 pic16_emitcode("mov","sp,a");
2896 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2897 if (options.useXstack) {
2898 pic16_emitcode("mov","r0,%s",spname);
2899 pic16_emitcode("movx","a,@r0");
2900 pic16_emitcode("mov","_bp,a");
2901 pic16_emitcode("dec","%s",spname);
2905 pic16_emitcode ("pop","_bp");
2909 /* restore the register bank */
2910 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2911 pic16_emitcode ("pop","psw");
2913 if (IFFUNC_ISISR(sym->type)) {
2915 /* now we need to restore the registers */
2916 /* if this isr has no bank i.e. is going to
2917 run with bank 0 , then we need to save more
2919 if (!FUNC_REGBANK(sym->type)) {
2921 /* if this function does not call any other
2922 function then we can be economical and
2923 save only those registers that are used */
2924 if (! IFFUNC_HASFCALL(sym->type)) {
2927 /* if any registers used */
2928 if (sym->regsUsed) {
2929 /* save the registers used */
2930 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2931 if (bitVectBitValue(sym->regsUsed,i) ||
2932 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2933 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2938 /* this function has a function call cannot
2939 determines register usage so we will have the
2941 unsaverbank(0,ic,FALSE);
2945 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2947 if (options.stack10bit)
2949 pic16_emitcode ("pop", "dpx1");
2950 pic16_emitcode ("pop", "dph1");
2951 pic16_emitcode ("pop", "dpl1");
2953 pic16_emitcode ("pop", "dps");
2954 pic16_emitcode ("pop", "dpx");
2956 if (!inExcludeList("dph"))
2957 pic16_emitcode ("pop","dph");
2958 if (!inExcludeList("dpl"))
2959 pic16_emitcode ("pop","dpl");
2960 if (!inExcludeList("b"))
2961 pic16_emitcode ("pop","b");
2962 if (!inExcludeList("acc"))
2963 pic16_emitcode ("pop","acc");
2965 if (IFFUNC_ISCRITICAL(sym->type))
2966 pic16_emitcode("setb","ea");
2969 /* if debug then send end of function */
2970 /* if (options.debug && currFunc) { */
2973 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2974 FileBaseName(ic->filename),currFunc->lastLine,
2975 ic->level,ic->block);
2976 if (IS_STATIC(currFunc->etype))
2977 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2979 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2983 pic16_emitcode ("reti","");
2985 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2986 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2987 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
2988 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
2989 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2990 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2992 pic16_emitpcodeNULLop(POC_RETFIE);
2996 if (IFFUNC_ISCRITICAL(sym->type))
2997 pic16_emitcode("setb","ea");
2999 if (IFFUNC_CALLEESAVES(sym->type)) {
3002 /* if any registers used */
3003 if (sym->regsUsed) {
3004 /* save the registers used */
3005 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
3006 if (bitVectBitValue(sym->regsUsed,i) ||
3007 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
3008 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
3014 /* if debug then send end of function */
3017 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
3018 FileBaseName(ic->filename),currFunc->lastLine,
3019 ic->level,ic->block);
3020 if (IS_STATIC(currFunc->etype))
3021 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3023 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3027 pic16_emitcode ("return","");
3028 pic16_emitpcodeNULLop(POC_RETURN);
3030 /* Mark the end of a function */
3031 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3036 /*-----------------------------------------------------------------*/
3037 /* genRet - generate code for return statement */
3038 /*-----------------------------------------------------------------*/
3039 static void genRet (iCode *ic)
3041 int size,offset = 0 , pushed = 0;
3043 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3044 /* if we have no return value then
3045 just generate the "ret" */
3049 /* we have something to return then
3050 move the return value into place */
3051 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3052 size = AOP_SIZE(IC_LEFT(ic));
3056 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3058 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3060 pic16_emitcode("push","%s",l);
3063 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3065 if (strcmp(fReturn[offset],l)) {
3066 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3067 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3068 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3070 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3073 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3083 if (strcmp(fReturn[pushed],"a"))
3084 pic16_emitcode("pop",fReturn[pushed]);
3086 pic16_emitcode("pop","acc");
3089 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3092 /* generate a jump to the return label
3093 if the next is not the return statement */
3094 if (!(ic->next && ic->next->op == LABEL &&
3095 IC_LABEL(ic->next) == returnLabel)) {
3097 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3098 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3103 /*-----------------------------------------------------------------*/
3104 /* genLabel - generates a label */
3105 /*-----------------------------------------------------------------*/
3106 static void genLabel (iCode *ic)
3108 /* special case never generate */
3109 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3110 if (IC_LABEL(ic) == entryLabel)
3113 pic16_emitpLabel(IC_LABEL(ic)->key);
3114 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3117 /*-----------------------------------------------------------------*/
3118 /* genGoto - generates a goto */
3119 /*-----------------------------------------------------------------*/
3121 static void genGoto (iCode *ic)
3123 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3124 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3128 /*-----------------------------------------------------------------*/
3129 /* genMultbits :- multiplication of bits */
3130 /*-----------------------------------------------------------------*/
3131 static void genMultbits (operand *left,
3135 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3137 if(!pic16_sameRegs(AOP(result),AOP(right)))
3138 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3140 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3141 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3142 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3147 /*-----------------------------------------------------------------*/
3148 /* genMultOneByte : 8 bit multiplication & division */
3149 /*-----------------------------------------------------------------*/
3150 static void genMultOneByte (operand *left,
3154 sym_link *opetype = operandType(result);
3159 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3160 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3161 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3163 /* (if two literals, the value is computed before) */
3164 /* if one literal, literal on the right */
3165 if (AOP_TYPE(left) == AOP_LIT){
3171 size = AOP_SIZE(result);
3174 if (AOP_TYPE(right) == AOP_LIT){
3175 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3176 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3177 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3178 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3179 pic16_emitcode("call","genMultLit");
3181 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3182 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3183 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3184 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3185 pic16_emitcode("call","pic16_genMult8X8_8");
3188 pic16_genMult8X8_8 (left, right,result);
3191 /* signed or unsigned */
3192 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3193 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3195 //pic16_emitcode("mul","ab");
3196 /* if result size = 1, mul signed = mul unsigned */
3197 //pic16_aopPut(AOP(result),"a",0);
3199 } else { // (size > 1)
3201 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3202 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3203 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3204 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3206 if (SPEC_USIGN(opetype)){
3207 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3208 pic16_genUMult8X8_16 (left, right, result, NULL);
3211 /* for filling the MSBs */
3212 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3213 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3217 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3219 pic16_emitcode("mov","a,b");
3221 /* adjust the MSB if left or right neg */
3223 /* if one literal */
3224 if (AOP_TYPE(right) == AOP_LIT){
3225 pic16_emitcode("multiply ","right is a lit");
3226 /* AND literal negative */
3227 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3228 /* adjust MSB (c==0 after mul) */
3229 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3233 pic16_genSMult8X8_16 (left, right, result, NULL);
3237 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3239 pic16_emitcode("rlc","a");
3240 pic16_emitcode("subb","a,acc");
3248 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3249 //pic16_aopPut(AOP(result),"a",offset++);
3253 /*-----------------------------------------------------------------*/
3254 /* genMult - generates code for multiplication */
3255 /*-----------------------------------------------------------------*/
3256 static void genMult (iCode *ic)
3258 operand *left = IC_LEFT(ic);
3259 operand *right = IC_RIGHT(ic);
3260 operand *result= IC_RESULT(ic);
3262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3263 /* assign the amsops */
3264 pic16_aopOp (left,ic,FALSE);
3265 pic16_aopOp (right,ic,FALSE);
3266 pic16_aopOp (result,ic,TRUE);
3268 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3270 /* special cases first */
3272 if (AOP_TYPE(left) == AOP_CRY &&
3273 AOP_TYPE(right)== AOP_CRY) {
3274 genMultbits(left,right,result);
3278 /* if both are of size == 1 */
3279 if (AOP_SIZE(left) == 1 &&
3280 AOP_SIZE(right) == 1 ) {
3281 genMultOneByte(left,right,result);
3285 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3287 /* should have been converted to function call */
3291 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3292 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3293 pic16_freeAsmop(result,NULL,ic,TRUE);
3296 /*-----------------------------------------------------------------*/
3297 /* genDivbits :- division of bits */
3298 /*-----------------------------------------------------------------*/
3299 static void genDivbits (operand *left,
3306 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3307 /* the result must be bit */
3308 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3309 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3313 pic16_emitcode("div","ab");
3314 pic16_emitcode("rrc","a");
3315 pic16_aopPut(AOP(result),"c",0);
3318 /*-----------------------------------------------------------------*/
3319 /* genDivOneByte : 8 bit division */
3320 /*-----------------------------------------------------------------*/
3321 static void genDivOneByte (operand *left,
3325 sym_link *opetype = operandType(result);
3330 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3331 size = AOP_SIZE(result) - 1;
3333 /* signed or unsigned */
3334 if (SPEC_USIGN(opetype)) {
3335 /* unsigned is easy */
3336 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3337 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3339 pic16_emitcode("div","ab");
3340 pic16_aopPut(AOP(result),"a",0);
3342 pic16_aopPut(AOP(result),zero,offset++);
3346 /* signed is a little bit more difficult */
3348 /* save the signs of the operands */
3349 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3351 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3352 pic16_emitcode("push","acc"); /* save it on the stack */
3354 /* now sign adjust for both left & right */
3355 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3357 lbl = newiTempLabel(NULL);
3358 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3359 pic16_emitcode("cpl","a");
3360 pic16_emitcode("inc","a");
3361 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3362 pic16_emitcode("mov","b,a");
3364 /* sign adjust left side */
3365 l = pic16_aopGet(AOP(left),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));
3374 /* now the division */
3375 pic16_emitcode("div","ab");
3376 /* we are interested in the lower order
3378 pic16_emitcode("mov","b,a");
3379 lbl = newiTempLabel(NULL);
3380 pic16_emitcode("pop","acc");
3381 /* if there was an over flow we don't
3382 adjust the sign of the result */
3383 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3384 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3386 pic16_emitcode("clr","a");
3387 pic16_emitcode("subb","a,b");
3388 pic16_emitcode("mov","b,a");
3389 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3391 /* now we are done */
3392 pic16_aopPut(AOP(result),"b",0);
3394 pic16_emitcode("mov","c,b.7");
3395 pic16_emitcode("subb","a,acc");
3398 pic16_aopPut(AOP(result),"a",offset++);
3402 /*-----------------------------------------------------------------*/
3403 /* genDiv - generates code for division */
3404 /*-----------------------------------------------------------------*/
3405 static void genDiv (iCode *ic)
3407 operand *left = IC_LEFT(ic);
3408 operand *right = IC_RIGHT(ic);
3409 operand *result= IC_RESULT(ic);
3411 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3412 /* assign the amsops */
3413 pic16_aopOp (left,ic,FALSE);
3414 pic16_aopOp (right,ic,FALSE);
3415 pic16_aopOp (result,ic,TRUE);
3417 /* special cases first */
3419 if (AOP_TYPE(left) == AOP_CRY &&
3420 AOP_TYPE(right)== AOP_CRY) {
3421 genDivbits(left,right,result);
3425 /* if both are of size == 1 */
3426 if (AOP_SIZE(left) == 1 &&
3427 AOP_SIZE(right) == 1 ) {
3428 genDivOneByte(left,right,result);
3432 /* should have been converted to function call */
3435 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3436 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3437 pic16_freeAsmop(result,NULL,ic,TRUE);
3440 /*-----------------------------------------------------------------*/
3441 /* genModbits :- modulus of bits */
3442 /*-----------------------------------------------------------------*/
3443 static void genModbits (operand *left,
3450 /* the result must be bit */
3451 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3452 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3456 pic16_emitcode("div","ab");
3457 pic16_emitcode("mov","a,b");
3458 pic16_emitcode("rrc","a");
3459 pic16_aopPut(AOP(result),"c",0);
3462 /*-----------------------------------------------------------------*/
3463 /* genModOneByte : 8 bit modulus */
3464 /*-----------------------------------------------------------------*/
3465 static void genModOneByte (operand *left,
3469 sym_link *opetype = operandType(result);
3473 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3474 /* signed or unsigned */
3475 if (SPEC_USIGN(opetype)) {
3476 /* unsigned is easy */
3477 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3478 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3480 pic16_emitcode("div","ab");
3481 pic16_aopPut(AOP(result),"b",0);
3485 /* signed is a little bit more difficult */
3487 /* save the signs of the operands */
3488 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3491 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3492 pic16_emitcode("push","acc"); /* save it on the stack */
3494 /* now sign adjust for both left & right */
3495 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3498 lbl = newiTempLabel(NULL);
3499 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3500 pic16_emitcode("cpl","a");
3501 pic16_emitcode("inc","a");
3502 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3503 pic16_emitcode("mov","b,a");
3505 /* sign adjust left side */
3506 l = pic16_aopGet(AOP(left),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));
3515 /* now the multiplication */
3516 pic16_emitcode("div","ab");
3517 /* we are interested in the lower order
3519 lbl = newiTempLabel(NULL);
3520 pic16_emitcode("pop","acc");
3521 /* if there was an over flow we don't
3522 adjust the sign of the result */
3523 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3524 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3526 pic16_emitcode("clr","a");
3527 pic16_emitcode("subb","a,b");
3528 pic16_emitcode("mov","b,a");
3529 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3531 /* now we are done */
3532 pic16_aopPut(AOP(result),"b",0);
3536 /*-----------------------------------------------------------------*/
3537 /* genMod - generates code for division */
3538 /*-----------------------------------------------------------------*/
3539 static void genMod (iCode *ic)
3541 operand *left = IC_LEFT(ic);
3542 operand *right = IC_RIGHT(ic);
3543 operand *result= IC_RESULT(ic);
3545 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3546 /* assign the amsops */
3547 pic16_aopOp (left,ic,FALSE);
3548 pic16_aopOp (right,ic,FALSE);
3549 pic16_aopOp (result,ic,TRUE);
3551 /* special cases first */
3553 if (AOP_TYPE(left) == AOP_CRY &&
3554 AOP_TYPE(right)== AOP_CRY) {
3555 genModbits(left,right,result);
3559 /* if both are of size == 1 */
3560 if (AOP_SIZE(left) == 1 &&
3561 AOP_SIZE(right) == 1 ) {
3562 genModOneByte(left,right,result);
3566 /* should have been converted to function call */
3570 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3571 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3572 pic16_freeAsmop(result,NULL,ic,TRUE);
3575 /*-----------------------------------------------------------------*/
3576 /* genIfxJump :- will create a jump depending on the ifx */
3577 /*-----------------------------------------------------------------*/
3579 note: May need to add parameter to indicate when a variable is in bit space.
3581 static void genIfxJump (iCode *ic, char *jval)
3584 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3585 /* if true label then we jump if condition
3587 if ( IC_TRUE(ic) ) {
3589 if(strcmp(jval,"a") == 0)
3591 else if (strcmp(jval,"c") == 0)
3594 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3595 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3598 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3599 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3603 /* false label is present */
3604 if(strcmp(jval,"a") == 0)
3606 else if (strcmp(jval,"c") == 0)
3609 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3610 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3613 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3614 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3619 /* mark the icode as generated */
3623 /*-----------------------------------------------------------------*/
3625 /*-----------------------------------------------------------------*/
3626 static void genSkip(iCode *ifx,int status_bit)
3631 if ( IC_TRUE(ifx) ) {
3632 switch(status_bit) {
3647 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3648 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3652 switch(status_bit) {
3666 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3667 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3673 /*-----------------------------------------------------------------*/
3675 /*-----------------------------------------------------------------*/
3676 static void genSkipc(resolvedIfx *rifx)
3686 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3687 rifx->generated = 1;
3690 /*-----------------------------------------------------------------*/
3692 /*-----------------------------------------------------------------*/
3693 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3698 if( (rifx->condition ^ invert_condition) & 1)
3703 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3704 rifx->generated = 1;
3707 /*-----------------------------------------------------------------*/
3709 /*-----------------------------------------------------------------*/
3710 static void genSkipz(iCode *ifx, int condition)
3721 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3723 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3726 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3728 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3731 /*-----------------------------------------------------------------*/
3733 /*-----------------------------------------------------------------*/
3734 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3740 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3742 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3745 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3746 rifx->generated = 1;
3750 /*-----------------------------------------------------------------*/
3751 /* genChkZeroes :- greater or less than comparison */
3752 /* For each byte in a literal that is zero, inclusive or the */
3753 /* the corresponding byte in the operand with W */
3754 /* returns true if any of the bytes are zero */
3755 /*-----------------------------------------------------------------*/
3756 static int genChkZeroes(operand *op, int lit, int size)
3763 i = (lit >> (size*8)) & 0xff;
3767 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3769 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3778 /*-----------------------------------------------------------------*/
3779 /* genCmp :- greater or less than comparison */
3780 /*-----------------------------------------------------------------*/
3781 static void genCmp (operand *left,operand *right,
3782 operand *result, iCode *ifx, int sign)
3784 int size; //, offset = 0 ;
3785 unsigned long lit = 0L,i = 0;
3786 resolvedIfx rFalseIfx;
3787 // resolvedIfx rTrueIfx;
3789 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3792 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3793 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3797 resolveIfx(&rFalseIfx,ifx);
3798 truelbl = newiTempLabel(NULL);
3799 size = max(AOP_SIZE(left),AOP_SIZE(right));
3801 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3805 /* if literal is on the right then swap with left */
3806 if ((AOP_TYPE(right) == AOP_LIT)) {
3807 operand *tmp = right ;
3808 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3809 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3812 lit = (lit - 1) & mask;
3815 rFalseIfx.condition ^= 1;
3818 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3819 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3823 //if(IC_TRUE(ifx) == NULL)
3824 /* if left & right are bit variables */
3825 if (AOP_TYPE(left) == AOP_CRY &&
3826 AOP_TYPE(right) == AOP_CRY ) {
3827 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3828 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3830 /* subtract right from left if at the
3831 end the carry flag is set then we know that
3832 left is greater than right */
3836 symbol *lbl = newiTempLabel(NULL);
3839 if(AOP_TYPE(right) == AOP_LIT) {
3841 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3843 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3850 genSkipCond(&rFalseIfx,left,size-1,7);
3852 /* no need to compare to 0...*/
3853 /* NOTE: this is a de-generate compare that most certainly
3854 * creates some dead code. */
3855 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3857 if(ifx) ifx->generated = 1;
3864 //i = (lit >> (size*8)) & 0xff;
3865 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3867 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3869 i = ((0-lit) & 0xff);
3872 /* lit is 0x7f, all signed chars are less than
3873 * this except for 0x7f itself */
3874 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3875 genSkipz2(&rFalseIfx,0);
3877 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3878 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3879 genSkipc(&rFalseIfx);
3884 genSkipz2(&rFalseIfx,1);
3886 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3887 genSkipc(&rFalseIfx);
3891 if(ifx) ifx->generated = 1;
3895 /* chars are out of the way. now do ints and longs */
3898 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3905 genSkipCond(&rFalseIfx,left,size,7);
3906 if(ifx) ifx->generated = 1;
3911 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3913 //rFalseIfx.condition ^= 1;
3914 //genSkipCond(&rFalseIfx,left,size,7);
3915 //rFalseIfx.condition ^= 1;
3917 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3918 if(rFalseIfx.condition)
3919 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3921 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3923 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3924 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3925 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3928 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3930 if(rFalseIfx.condition) {
3932 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3938 genSkipc(&rFalseIfx);
3939 pic16_emitpLabel(truelbl->key);
3940 if(ifx) ifx->generated = 1;
3947 if( (lit & 0xff) == 0) {
3948 /* lower byte is zero */
3949 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3950 i = ((lit >> 8) & 0xff) ^0x80;
3951 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3952 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3953 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3954 genSkipc(&rFalseIfx);
3957 if(ifx) ifx->generated = 1;
3962 /* Special cases for signed longs */
3963 if( (lit & 0xffffff) == 0) {
3964 /* lower byte is zero */
3965 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3966 i = ((lit >> 8*3) & 0xff) ^0x80;
3967 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3968 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3969 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3970 genSkipc(&rFalseIfx);
3973 if(ifx) ifx->generated = 1;
3981 if(lit & (0x80 << (size*8))) {
3982 /* lit is negative */
3983 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3985 //genSkipCond(&rFalseIfx,left,size,7);
3987 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3989 if(rFalseIfx.condition)
3990 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3992 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3996 /* lit is positive */
3997 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3998 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3999 if(rFalseIfx.condition)
4000 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4002 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4007 This works, but is only good for ints.
4008 It also requires a "known zero" register.
4009 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
4010 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
4011 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
4012 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
4013 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
4014 genSkipc(&rFalseIfx);
4016 pic16_emitpLabel(truelbl->key);
4017 if(ifx) ifx->generated = 1;
4021 /* There are no more special cases, so perform a general compare */
4023 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4024 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4028 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4030 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4032 //rFalseIfx.condition ^= 1;
4033 genSkipc(&rFalseIfx);
4035 pic16_emitpLabel(truelbl->key);
4037 if(ifx) ifx->generated = 1;
4044 /* sign is out of the way. So now do an unsigned compare */
4045 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4048 /* General case - compare to an unsigned literal on the right.*/
4050 i = (lit >> (size*8)) & 0xff;
4051 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4052 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4054 i = (lit >> (size*8)) & 0xff;
4057 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4059 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4061 /* this byte of the lit is zero,
4062 *if it's not the last then OR in the variable */
4064 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4069 pic16_emitpLabel(lbl->key);
4070 //if(emitFinalCheck)
4071 genSkipc(&rFalseIfx);
4073 pic16_emitpLabel(truelbl->key);
4075 if(ifx) ifx->generated = 1;
4082 if(AOP_TYPE(left) == AOP_LIT) {
4083 //symbol *lbl = newiTempLabel(NULL);
4085 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4088 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4091 if((lit == 0) && (sign == 0)){
4094 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4096 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4098 genSkipz2(&rFalseIfx,0);
4099 if(ifx) ifx->generated = 1;
4106 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4107 /* degenerate compare can never be true */
4108 if(rFalseIfx.condition == 0)
4109 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4111 if(ifx) ifx->generated = 1;
4116 /* signed comparisons to a literal byte */
4118 int lp1 = (lit+1) & 0xff;
4120 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4123 rFalseIfx.condition ^= 1;
4124 genSkipCond(&rFalseIfx,right,0,7);
4127 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4128 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4129 genSkipz2(&rFalseIfx,1);
4132 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4133 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4134 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4135 rFalseIfx.condition ^= 1;
4136 genSkipc(&rFalseIfx);
4140 /* unsigned comparisons to a literal byte */
4142 switch(lit & 0xff ) {
4144 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4145 genSkipz2(&rFalseIfx,0);
4148 rFalseIfx.condition ^= 1;
4149 genSkipCond(&rFalseIfx,right,0,7);
4153 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4154 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4155 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4156 rFalseIfx.condition ^= 1;
4157 if (AOP_TYPE(result) == AOP_CRY)
4158 genSkipc(&rFalseIfx);
4160 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4161 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4167 if(ifx) ifx->generated = 1;
4173 /* Size is greater than 1 */
4181 /* this means lit = 0xffffffff, or -1 */
4184 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4185 rFalseIfx.condition ^= 1;
4186 genSkipCond(&rFalseIfx,right,size,7);
4187 if(ifx) ifx->generated = 1;
4194 if(rFalseIfx.condition) {
4195 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4196 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4199 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4201 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4205 if(rFalseIfx.condition) {
4206 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4207 pic16_emitpLabel(truelbl->key);
4209 rFalseIfx.condition ^= 1;
4210 genSkipCond(&rFalseIfx,right,s,7);
4213 if(ifx) ifx->generated = 1;
4217 if((size == 1) && (0 == (lp1&0xff))) {
4218 /* lower byte of signed word is zero */
4219 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4220 i = ((lp1 >> 8) & 0xff) ^0x80;
4221 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4222 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4223 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4224 rFalseIfx.condition ^= 1;
4225 genSkipc(&rFalseIfx);
4228 if(ifx) ifx->generated = 1;
4232 if(lit & (0x80 << (size*8))) {
4233 /* Lit is less than zero */
4234 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4235 //rFalseIfx.condition ^= 1;
4236 //genSkipCond(&rFalseIfx,left,size,7);
4237 //rFalseIfx.condition ^= 1;
4238 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4239 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4241 if(rFalseIfx.condition)
4242 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4244 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4248 /* Lit is greater than or equal to zero */
4249 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4250 //rFalseIfx.condition ^= 1;
4251 //genSkipCond(&rFalseIfx,right,size,7);
4252 //rFalseIfx.condition ^= 1;
4254 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4255 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4257 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4258 if(rFalseIfx.condition)
4259 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4261 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4266 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4267 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4271 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4273 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4275 rFalseIfx.condition ^= 1;
4276 //rFalseIfx.condition = 1;
4277 genSkipc(&rFalseIfx);
4279 pic16_emitpLabel(truelbl->key);
4281 if(ifx) ifx->generated = 1;
4286 /* compare word or long to an unsigned literal on the right.*/
4291 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4294 break; /* handled above */
4297 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4299 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4300 genSkipz2(&rFalseIfx,0);
4304 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4306 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4309 if(rFalseIfx.condition)
4310 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4312 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4315 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4316 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4318 rFalseIfx.condition ^= 1;
4319 genSkipc(&rFalseIfx);
4322 pic16_emitpLabel(truelbl->key);
4324 if(ifx) ifx->generated = 1;
4330 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4331 i = (lit >> (size*8)) & 0xff;
4333 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4334 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4337 i = (lit >> (size*8)) & 0xff;
4340 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4342 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4344 /* this byte of the lit is zero,
4345 *if it's not the last then OR in the variable */
4347 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4352 pic16_emitpLabel(lbl->key);
4354 rFalseIfx.condition ^= 1;
4355 genSkipc(&rFalseIfx);
4359 pic16_emitpLabel(truelbl->key);
4360 if(ifx) ifx->generated = 1;
4364 /* Compare two variables */
4366 DEBUGpic16_emitcode(";sign","%d",sign);
4370 /* Sigh. thus sucks... */
4372 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4373 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4374 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4375 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4376 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4377 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4379 /* Signed char comparison */
4380 /* Special thanks to Nikolai Golovchenko for this snippet */
4381 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4382 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4383 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4384 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4385 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4386 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4388 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4389 genSkipc(&rFalseIfx);
4391 if(ifx) ifx->generated = 1;
4397 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4398 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4402 /* The rest of the bytes of a multi-byte compare */
4406 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4409 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4410 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4415 pic16_emitpLabel(lbl->key);
4417 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4418 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4419 (AOP_TYPE(result) == AOP_REG)) {
4420 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4421 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4423 genSkipc(&rFalseIfx);
4425 //genSkipc(&rFalseIfx);
4426 if(ifx) ifx->generated = 1;
4433 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4434 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4435 pic16_outBitC(result);
4437 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4438 /* if the result is used in the next
4439 ifx conditional branch then generate
4440 code a little differently */
4442 genIfxJump (ifx,"c");
4444 pic16_outBitC(result);
4445 /* leave the result in acc */
4450 /*-----------------------------------------------------------------*/
4451 /* genCmpGt :- greater than comparison */
4452 /*-----------------------------------------------------------------*/
4453 static void genCmpGt (iCode *ic, iCode *ifx)
4455 operand *left, *right, *result;
4456 sym_link *letype , *retype;
4459 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4461 right= IC_RIGHT(ic);
4462 result = IC_RESULT(ic);
4464 letype = getSpec(operandType(left));
4465 retype =getSpec(operandType(right));
4466 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4467 /* assign the amsops */
4468 pic16_aopOp (left,ic,FALSE);
4469 pic16_aopOp (right,ic,FALSE);
4470 pic16_aopOp (result,ic,TRUE);
4472 genCmp(right, left, result, ifx, sign);
4474 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4475 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4476 pic16_freeAsmop(result,NULL,ic,TRUE);
4479 /*-----------------------------------------------------------------*/
4480 /* genCmpLt - less than comparisons */
4481 /*-----------------------------------------------------------------*/
4482 static void genCmpLt (iCode *ic, iCode *ifx)
4484 operand *left, *right, *result;
4485 sym_link *letype , *retype;
4488 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4490 right= IC_RIGHT(ic);
4491 result = IC_RESULT(ic);
4493 letype = getSpec(operandType(left));
4494 retype =getSpec(operandType(right));
4495 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4497 /* assign the amsops */
4498 pic16_aopOp (left,ic,FALSE);
4499 pic16_aopOp (right,ic,FALSE);
4500 pic16_aopOp (result,ic,TRUE);
4502 genCmp(left, right, result, ifx, sign);
4504 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4505 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4506 pic16_freeAsmop(result,NULL,ic,TRUE);
4509 /*-----------------------------------------------------------------*/
4510 /* genc16bit2lit - compare a 16 bit value to a literal */
4511 /*-----------------------------------------------------------------*/
4512 static void genc16bit2lit(operand *op, int lit, int offset)
4516 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4517 if( (lit&0xff) == 0)
4522 switch( BYTEofLONG(lit,i)) {
4524 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4527 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4530 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4533 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4534 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4539 switch( BYTEofLONG(lit,i)) {
4541 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4545 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4549 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4552 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4554 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4560 /*-----------------------------------------------------------------*/
4561 /* gencjneshort - compare and jump if not equal */
4562 /*-----------------------------------------------------------------*/
4563 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4565 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4567 int res_offset = 0; /* the result may be a different size then left or right */
4568 int res_size = AOP_SIZE(result);
4572 unsigned long lit = 0L;
4573 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4574 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4576 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4577 resolveIfx(&rIfx,ifx);
4578 lbl = newiTempLabel(NULL);
4581 /* if the left side is a literal or
4582 if the right is in a pointer register and left
4584 if ((AOP_TYPE(left) == AOP_LIT) ||
4585 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4590 if(AOP_TYPE(right) == AOP_LIT)
4591 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4593 /* if the right side is a literal then anything goes */
4594 if (AOP_TYPE(right) == AOP_LIT &&
4595 AOP_TYPE(left) != AOP_DIR ) {
4598 genc16bit2lit(left, lit, 0);
4600 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4605 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4606 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4608 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4612 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4614 if(res_offset < res_size-1)
4622 /* if the right side is in a register or in direct space or
4623 if the left is a pointer register & right is not */
4624 else if (AOP_TYPE(right) == AOP_REG ||
4625 AOP_TYPE(right) == AOP_DIR ||
4626 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4627 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4628 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4629 int lbl_key = lbl->key;
4632 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4633 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4635 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4636 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4637 __FUNCTION__,__LINE__);
4641 /* switch(size) { */
4643 /* genc16bit2lit(left, lit, 0); */
4645 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4650 if((AOP_TYPE(left) == AOP_DIR) &&
4651 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4653 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4654 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4656 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4658 switch (lit & 0xff) {
4660 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4663 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4664 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4665 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4669 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4670 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4671 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4672 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4676 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4677 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4682 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4685 if(AOP_TYPE(result) == AOP_CRY) {
4686 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4691 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4693 /* fix me. probably need to check result size too */
4694 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4699 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4700 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4707 if(res_offset < res_size-1)
4712 } else if(AOP_TYPE(right) == AOP_REG &&
4713 AOP_TYPE(left) != AOP_DIR){
4716 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4717 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4718 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4723 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4725 if(res_offset < res_size-1)
4730 /* right is a pointer reg need both a & b */
4732 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4734 pic16_emitcode("mov","b,%s",l);
4735 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4736 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4741 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4743 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4745 pic16_emitpLabel(lbl->key);
4747 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4754 /*-----------------------------------------------------------------*/
4755 /* gencjne - compare and jump if not equal */
4756 /*-----------------------------------------------------------------*/
4757 static void gencjne(operand *left, operand *right, iCode *ifx)
4759 symbol *tlbl = newiTempLabel(NULL);
4761 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4762 gencjneshort(left, right, lbl);
4764 pic16_emitcode("mov","a,%s",one);
4765 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4766 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4767 pic16_emitcode("clr","a");
4768 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4770 pic16_emitpLabel(lbl->key);
4771 pic16_emitpLabel(tlbl->key);
4776 /*-----------------------------------------------------------------*/
4777 /* genCmpEq - generates code for equal to */
4778 /*-----------------------------------------------------------------*/
4779 static void genCmpEq (iCode *ic, iCode *ifx)
4781 operand *left, *right, *result;
4782 unsigned long lit = 0L;
4785 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4788 DEBUGpic16_emitcode ("; ifx is non-null","");
4790 DEBUGpic16_emitcode ("; ifx is null","");
4792 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4793 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4794 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4796 size = max(AOP_SIZE(left),AOP_SIZE(right));
4798 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4800 /* if literal, literal on the right or
4801 if the right is in a pointer register and left
4803 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4804 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4805 operand *tmp = right ;
4811 if(ifx && !AOP_SIZE(result)){
4813 /* if they are both bit variables */
4814 if (AOP_TYPE(left) == AOP_CRY &&
4815 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4816 if(AOP_TYPE(right) == AOP_LIT){
4817 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4819 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4820 pic16_emitcode("cpl","c");
4821 } else if(lit == 1L) {
4822 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4824 pic16_emitcode("clr","c");
4826 /* AOP_TYPE(right) == AOP_CRY */
4828 symbol *lbl = newiTempLabel(NULL);
4829 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4830 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4831 pic16_emitcode("cpl","c");
4832 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4834 /* if true label then we jump if condition
4836 tlbl = newiTempLabel(NULL);
4837 if ( IC_TRUE(ifx) ) {
4838 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4839 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4841 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4842 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4844 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4847 /* left and right are both bit variables, result is carry */
4850 resolveIfx(&rIfx,ifx);
4852 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4853 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4854 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4855 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4860 /* They're not both bit variables. Is the right a literal? */
4861 if(AOP_TYPE(right) == AOP_LIT) {
4862 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4867 switch(lit & 0xff) {
4869 if ( IC_TRUE(ifx) ) {
4870 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4872 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4874 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4875 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4879 if ( IC_TRUE(ifx) ) {
4880 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4882 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4884 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4885 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4889 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4891 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4896 /* end of size == 1 */
4900 genc16bit2lit(left,lit,offset);
4903 /* end of size == 2 */
4908 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4909 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4910 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4911 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4915 /* search for patterns that can be optimized */
4917 genc16bit2lit(left,lit,0);
4920 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4922 genc16bit2lit(left,lit,2);
4924 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4925 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4938 } else if(AOP_TYPE(right) == AOP_CRY ) {
4939 /* we know the left is not a bit, but that the right is */
4940 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4941 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4942 pic16_popGet(AOP(right),offset));
4943 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4945 /* if the two are equal, then W will be 0 and the Z bit is set
4946 * we could test Z now, or go ahead and check the high order bytes if
4947 * the variable we're comparing is larger than a byte. */
4950 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4952 if ( IC_TRUE(ifx) ) {
4954 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4955 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4958 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4959 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4963 /* They're both variables that are larger than bits */
4966 tlbl = newiTempLabel(NULL);
4969 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4970 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4972 if ( IC_TRUE(ifx) ) {
4975 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4976 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4979 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4980 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4984 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4985 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4989 if(s>1 && IC_TRUE(ifx)) {
4990 pic16_emitpLabel(tlbl->key);
4991 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4995 /* mark the icode as generated */
5000 /* if they are both bit variables */
5001 if (AOP_TYPE(left) == AOP_CRY &&
5002 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
5003 if(AOP_TYPE(right) == AOP_LIT){
5004 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5006 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5007 pic16_emitcode("cpl","c");
5008 } else if(lit == 1L) {
5009 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5011 pic16_emitcode("clr","c");
5013 /* AOP_TYPE(right) == AOP_CRY */
5015 symbol *lbl = newiTempLabel(NULL);
5016 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5017 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5018 pic16_emitcode("cpl","c");
5019 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5022 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5023 pic16_outBitC(result);
5027 genIfxJump (ifx,"c");
5030 /* if the result is used in an arithmetic operation
5031 then put the result in place */
5032 pic16_outBitC(result);
5035 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5036 gencjne(left,right,result,ifx);
5039 gencjne(left,right,newiTempLabel(NULL));
5041 if(IC_TRUE(ifx)->key)
5042 gencjne(left,right,IC_TRUE(ifx)->key);
5044 gencjne(left,right,IC_FALSE(ifx)->key);
5048 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5049 pic16_aopPut(AOP(result),"a",0);
5054 genIfxJump (ifx,"a");
5058 /* if the result is used in an arithmetic operation
5059 then put the result in place */
5061 if (AOP_TYPE(result) != AOP_CRY)
5062 pic16_outAcc(result);
5064 /* leave the result in acc */
5068 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5069 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5070 pic16_freeAsmop(result,NULL,ic,TRUE);
5073 /*-----------------------------------------------------------------*/
5074 /* ifxForOp - returns the icode containing the ifx for operand */
5075 /*-----------------------------------------------------------------*/
5076 static iCode *ifxForOp ( operand *op, iCode *ic )
5078 /* if true symbol then needs to be assigned */
5079 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5080 if (IS_TRUE_SYMOP(op))
5083 /* if this has register type condition and
5084 the next instruction is ifx with the same operand
5085 and live to of the operand is upto the ifx only then */
5087 ic->next->op == IFX &&
5088 IC_COND(ic->next)->key == op->key &&
5089 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5093 ic->next->op == IFX &&
5094 IC_COND(ic->next)->key == op->key) {
5095 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5099 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5101 ic->next->op == IFX)
5102 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5105 ic->next->op == IFX &&
5106 IC_COND(ic->next)->key == op->key) {
5107 DEBUGpic16_emitcode ("; "," key is okay");
5108 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5109 OP_SYMBOL(op)->liveTo,
5116 /*-----------------------------------------------------------------*/
5117 /* genAndOp - for && operation */
5118 /*-----------------------------------------------------------------*/
5119 static void genAndOp (iCode *ic)
5121 operand *left,*right, *result;
5124 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5125 /* note here that && operations that are in an
5126 if statement are taken away by backPatchLabels
5127 only those used in arthmetic operations remain */
5128 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5129 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5130 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5132 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5134 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5135 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5136 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5138 /* if both are bit variables */
5139 /* if (AOP_TYPE(left) == AOP_CRY && */
5140 /* AOP_TYPE(right) == AOP_CRY ) { */
5141 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5142 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5143 /* pic16_outBitC(result); */
5145 /* tlbl = newiTempLabel(NULL); */
5146 /* pic16_toBoolean(left); */
5147 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5148 /* pic16_toBoolean(right); */
5149 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5150 /* pic16_outBitAcc(result); */
5153 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5154 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5155 pic16_freeAsmop(result,NULL,ic,TRUE);
5159 /*-----------------------------------------------------------------*/
5160 /* genOrOp - for || operation */
5161 /*-----------------------------------------------------------------*/
5164 modified this code, but it doesn't appear to ever get called
5167 static void genOrOp (iCode *ic)
5169 operand *left,*right, *result;
5172 /* note here that || operations that are in an
5173 if statement are taken away by backPatchLabels
5174 only those used in arthmetic operations remain */
5175 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5176 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5177 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5178 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5180 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5182 /* if both are bit variables */
5183 if (AOP_TYPE(left) == AOP_CRY &&
5184 AOP_TYPE(right) == AOP_CRY ) {
5185 pic16_emitcode("clrc","");
5186 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5187 AOP(left)->aopu.aop_dir,
5188 AOP(left)->aopu.aop_dir);
5189 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5190 AOP(right)->aopu.aop_dir,
5191 AOP(right)->aopu.aop_dir);
5192 pic16_emitcode("setc","");
5195 tlbl = newiTempLabel(NULL);
5196 pic16_toBoolean(left);
5198 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5199 pic16_toBoolean(right);
5200 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5202 pic16_outBitAcc(result);
5205 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5206 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5207 pic16_freeAsmop(result,NULL,ic,TRUE);
5210 /*-----------------------------------------------------------------*/
5211 /* isLiteralBit - test if lit == 2^n */
5212 /*-----------------------------------------------------------------*/
5213 static int isLiteralBit(unsigned long lit)
5215 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5216 0x100L,0x200L,0x400L,0x800L,
5217 0x1000L,0x2000L,0x4000L,0x8000L,
5218 0x10000L,0x20000L,0x40000L,0x80000L,
5219 0x100000L,0x200000L,0x400000L,0x800000L,
5220 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5221 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5224 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5225 for(idx = 0; idx < 32; idx++)
5231 /*-----------------------------------------------------------------*/
5232 /* continueIfTrue - */
5233 /*-----------------------------------------------------------------*/
5234 static void continueIfTrue (iCode *ic)
5236 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5238 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5242 /*-----------------------------------------------------------------*/
5244 /*-----------------------------------------------------------------*/
5245 static void jumpIfTrue (iCode *ic)
5247 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5249 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5253 /*-----------------------------------------------------------------*/
5254 /* jmpTrueOrFalse - */
5255 /*-----------------------------------------------------------------*/
5256 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5258 // ugly but optimized by peephole
5259 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5261 symbol *nlbl = newiTempLabel(NULL);
5262 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5263 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5264 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5265 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5268 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5269 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5274 /*-----------------------------------------------------------------*/
5275 /* genAnd - code for and */
5276 /*-----------------------------------------------------------------*/
5277 static void genAnd (iCode *ic, iCode *ifx)
5279 operand *left, *right, *result;
5281 unsigned long lit = 0L;
5286 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5287 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5288 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5289 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5291 resolveIfx(&rIfx,ifx);
5293 /* if left is a literal & right is not then exchange them */
5294 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5295 AOP_NEEDSACC(left)) {
5296 operand *tmp = right ;
5301 /* if result = right then exchange them */
5302 if(pic16_sameRegs(AOP(result),AOP(right))){
5303 operand *tmp = right ;
5308 /* if right is bit then exchange them */
5309 if (AOP_TYPE(right) == AOP_CRY &&
5310 AOP_TYPE(left) != AOP_CRY){
5311 operand *tmp = right ;
5315 if(AOP_TYPE(right) == AOP_LIT)
5316 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5318 size = AOP_SIZE(result);
5320 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5323 // result = bit & yy;
5324 if (AOP_TYPE(left) == AOP_CRY){
5325 // c = bit & literal;
5326 if(AOP_TYPE(right) == AOP_LIT){
5328 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5331 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5334 if(size && (AOP_TYPE(result) == AOP_CRY)){
5335 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5338 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5342 pic16_emitcode("clr","c");
5345 if (AOP_TYPE(right) == AOP_CRY){
5347 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5348 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5351 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5353 pic16_emitcode("rrc","a");
5354 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5360 pic16_outBitC(result);
5362 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5363 genIfxJump(ifx, "c");
5367 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5368 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5369 if((AOP_TYPE(right) == AOP_LIT) &&
5370 (AOP_TYPE(result) == AOP_CRY) &&
5371 (AOP_TYPE(left) != AOP_CRY)){
5372 int posbit = isLiteralBit(lit);
5376 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5379 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5385 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5386 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5388 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5389 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5392 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5393 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5394 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5401 symbol *tlbl = newiTempLabel(NULL);
5402 int sizel = AOP_SIZE(left);
5404 pic16_emitcode("setb","c");
5406 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5407 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5409 if((posbit = isLiteralBit(bytelit)) != 0)
5410 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5412 if(bytelit != 0x0FFL)
5413 pic16_emitcode("anl","a,%s",
5414 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5415 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5420 // bit = left & literal
5422 pic16_emitcode("clr","c");
5423 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5425 // if(left & literal)
5428 jmpTrueOrFalse(ifx, tlbl);
5432 pic16_outBitC(result);
5436 /* if left is same as result */
5437 if(pic16_sameRegs(AOP(result),AOP(left))){
5439 for(;size--; offset++,lit>>=8) {
5440 if(AOP_TYPE(right) == AOP_LIT){
5441 switch(lit & 0xff) {
5443 /* and'ing with 0 has clears the result */
5444 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5445 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5448 /* and'ing with 0xff is a nop when the result and left are the same */
5453 int p = my_powof2( (~lit) & 0xff );
5455 /* only one bit is set in the literal, so use a bcf instruction */
5456 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5457 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5460 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5461 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5462 if(know_W != (lit&0xff))
5463 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5465 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5470 if (AOP_TYPE(left) == AOP_ACC) {
5471 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5473 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5474 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5481 // left & result in different registers
5482 if(AOP_TYPE(result) == AOP_CRY){
5484 // if(size), result in bit
5485 // if(!size && ifx), conditional oper: if(left & right)
5486 symbol *tlbl = newiTempLabel(NULL);
5487 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5489 pic16_emitcode("setb","c");
5491 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5492 pic16_emitcode("anl","a,%s",
5493 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5494 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5499 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5500 pic16_outBitC(result);
5502 jmpTrueOrFalse(ifx, tlbl);
5504 for(;(size--);offset++) {
5506 // result = left & right
5507 if(AOP_TYPE(right) == AOP_LIT){
5508 int t = (lit >> (offset*8)) & 0x0FFL;
5511 pic16_emitcode("clrf","%s",
5512 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5513 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5516 pic16_emitcode("movf","%s,w",
5517 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5518 pic16_emitcode("movwf","%s",
5519 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5520 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5521 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5524 pic16_emitcode("movlw","0x%x",t);
5525 pic16_emitcode("andwf","%s,w",
5526 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5527 pic16_emitcode("movwf","%s",
5528 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5530 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5531 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5532 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5537 if (AOP_TYPE(left) == AOP_ACC) {
5538 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5539 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5541 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5542 pic16_emitcode("andwf","%s,w",
5543 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5544 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5545 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5547 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5548 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5554 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5555 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5556 pic16_freeAsmop(result,NULL,ic,TRUE);
5559 /*-----------------------------------------------------------------*/
5560 /* genOr - code for or */
5561 /*-----------------------------------------------------------------*/
5562 static void genOr (iCode *ic, iCode *ifx)
5564 operand *left, *right, *result;
5566 unsigned long lit = 0L;
5568 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5570 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5571 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5572 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5574 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5576 /* if left is a literal & right is not then exchange them */
5577 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5578 AOP_NEEDSACC(left)) {
5579 operand *tmp = right ;
5584 /* if result = right then exchange them */
5585 if(pic16_sameRegs(AOP(result),AOP(right))){
5586 operand *tmp = right ;
5591 /* if right is bit then exchange them */
5592 if (AOP_TYPE(right) == AOP_CRY &&
5593 AOP_TYPE(left) != AOP_CRY){
5594 operand *tmp = right ;
5599 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5601 if(AOP_TYPE(right) == AOP_LIT)
5602 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5604 size = AOP_SIZE(result);
5608 if (AOP_TYPE(left) == AOP_CRY){
5609 if(AOP_TYPE(right) == AOP_LIT){
5610 // c = bit & literal;
5612 // lit != 0 => result = 1
5613 if(AOP_TYPE(result) == AOP_CRY){
5615 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5616 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5617 // AOP(result)->aopu.aop_dir,
5618 // AOP(result)->aopu.aop_dir);
5620 continueIfTrue(ifx);
5624 // lit == 0 => result = left
5625 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5627 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5630 if (AOP_TYPE(right) == AOP_CRY){
5631 if(pic16_sameRegs(AOP(result),AOP(left))){
5633 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5634 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5635 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5637 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5638 AOP(result)->aopu.aop_dir,
5639 AOP(result)->aopu.aop_dir);
5640 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5641 AOP(right)->aopu.aop_dir,
5642 AOP(right)->aopu.aop_dir);
5643 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5644 AOP(result)->aopu.aop_dir,
5645 AOP(result)->aopu.aop_dir);
5647 if( AOP_TYPE(result) == AOP_ACC) {
5648 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5649 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5650 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5651 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5655 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5656 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5657 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5658 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5660 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5661 AOP(result)->aopu.aop_dir,
5662 AOP(result)->aopu.aop_dir);
5663 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5664 AOP(right)->aopu.aop_dir,
5665 AOP(right)->aopu.aop_dir);
5666 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5667 AOP(left)->aopu.aop_dir,
5668 AOP(left)->aopu.aop_dir);
5669 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5670 AOP(result)->aopu.aop_dir,
5671 AOP(result)->aopu.aop_dir);
5676 symbol *tlbl = newiTempLabel(NULL);
5677 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5680 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5681 if( AOP_TYPE(right) == AOP_ACC) {
5682 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5684 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5685 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5690 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5691 pic16_emitcode(";XXX setb","c");
5692 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5693 AOP(left)->aopu.aop_dir,tlbl->key+100);
5694 pic16_toBoolean(right);
5695 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5696 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5697 jmpTrueOrFalse(ifx, tlbl);
5701 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5708 pic16_outBitC(result);
5710 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5711 genIfxJump(ifx, "c");
5715 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5716 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5717 if((AOP_TYPE(right) == AOP_LIT) &&
5718 (AOP_TYPE(result) == AOP_CRY) &&
5719 (AOP_TYPE(left) != AOP_CRY)){
5721 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5724 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5726 continueIfTrue(ifx);
5729 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5730 // lit = 0, result = boolean(left)
5732 pic16_emitcode(";XXX setb","c");
5733 pic16_toBoolean(right);
5735 symbol *tlbl = newiTempLabel(NULL);
5736 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5738 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5740 genIfxJump (ifx,"a");
5744 pic16_outBitC(result);
5748 /* if left is same as result */
5749 if(pic16_sameRegs(AOP(result),AOP(left))){
5751 for(;size--; offset++,lit>>=8) {
5752 if(AOP_TYPE(right) == AOP_LIT){
5753 if((lit & 0xff) == 0)
5754 /* or'ing with 0 has no effect */
5757 int p = my_powof2(lit & 0xff);
5759 /* only one bit is set in the literal, so use a bsf instruction */
5760 pic16_emitpcode(POC_BSF,
5761 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5763 if(know_W != (lit & 0xff))
5764 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5765 know_W = lit & 0xff;
5766 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5771 if (AOP_TYPE(left) == AOP_ACC) {
5772 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5773 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5775 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5776 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5778 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5779 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5785 // left & result in different registers
5786 if(AOP_TYPE(result) == AOP_CRY){
5788 // if(size), result in bit
5789 // if(!size && ifx), conditional oper: if(left | right)
5790 symbol *tlbl = newiTempLabel(NULL);
5791 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5792 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5796 pic16_emitcode(";XXX setb","c");
5798 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5799 pic16_emitcode(";XXX orl","a,%s",
5800 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5801 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5806 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5807 pic16_outBitC(result);
5809 jmpTrueOrFalse(ifx, tlbl);
5810 } else for(;(size--);offset++){
5812 // result = left & right
5813 if(AOP_TYPE(right) == AOP_LIT){
5814 int t = (lit >> (offset*8)) & 0x0FFL;
5817 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5818 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5820 pic16_emitcode("movf","%s,w",
5821 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5822 pic16_emitcode("movwf","%s",
5823 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5826 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5827 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5828 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5830 pic16_emitcode("movlw","0x%x",t);
5831 pic16_emitcode("iorwf","%s,w",
5832 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5833 pic16_emitcode("movwf","%s",
5834 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5840 // faster than result <- left, anl result,right
5841 // and better if result is SFR
5842 if (AOP_TYPE(left) == AOP_ACC) {
5843 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5844 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5846 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5847 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5849 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5850 pic16_emitcode("iorwf","%s,w",
5851 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5853 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5854 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5859 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5860 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5861 pic16_freeAsmop(result,NULL,ic,TRUE);
5864 /*-----------------------------------------------------------------*/
5865 /* genXor - code for xclusive or */
5866 /*-----------------------------------------------------------------*/
5867 static void genXor (iCode *ic, iCode *ifx)
5869 operand *left, *right, *result;
5871 unsigned long lit = 0L;
5873 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5875 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5876 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5877 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5879 /* if left is a literal & right is not ||
5880 if left needs acc & right does not */
5881 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5882 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5883 operand *tmp = right ;
5888 /* if result = right then exchange them */
5889 if(pic16_sameRegs(AOP(result),AOP(right))){
5890 operand *tmp = right ;
5895 /* if right is bit then exchange them */
5896 if (AOP_TYPE(right) == AOP_CRY &&
5897 AOP_TYPE(left) != AOP_CRY){
5898 operand *tmp = right ;
5902 if(AOP_TYPE(right) == AOP_LIT)
5903 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5905 size = AOP_SIZE(result);
5909 if (AOP_TYPE(left) == AOP_CRY){
5910 if(AOP_TYPE(right) == AOP_LIT){
5911 // c = bit & literal;
5913 // lit>>1 != 0 => result = 1
5914 if(AOP_TYPE(result) == AOP_CRY){
5916 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
5917 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5919 continueIfTrue(ifx);
5922 pic16_emitcode("setb","c");
5926 // lit == 0, result = left
5927 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5929 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5931 // lit == 1, result = not(left)
5932 if(size && pic16_sameRegs(AOP(result),AOP(left))){
5933 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
5934 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
5935 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5938 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5939 pic16_emitcode("cpl","c");
5946 symbol *tlbl = newiTempLabel(NULL);
5947 if (AOP_TYPE(right) == AOP_CRY){
5949 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5952 int sizer = AOP_SIZE(right);
5954 // if val>>1 != 0, result = 1
5955 pic16_emitcode("setb","c");
5957 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5959 // test the msb of the lsb
5960 pic16_emitcode("anl","a,#0xfe");
5961 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5965 pic16_emitcode("rrc","a");
5967 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5968 pic16_emitcode("cpl","c");
5969 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5974 pic16_outBitC(result);
5976 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5977 genIfxJump(ifx, "c");
5981 if(pic16_sameRegs(AOP(result),AOP(left))){
5982 /* if left is same as result */
5983 for(;size--; offset++) {
5984 if(AOP_TYPE(right) == AOP_LIT){
5985 int t = (lit >> (offset*8)) & 0x0FFL;
5989 if (IS_AOP_PREG(left)) {
5990 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5991 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5992 pic16_aopPut(AOP(result),"a",offset);
5994 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5995 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5996 pic16_emitcode("xrl","%s,%s",
5997 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5998 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6001 if (AOP_TYPE(left) == AOP_ACC)
6002 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6004 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6005 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
6007 if (IS_AOP_PREG(left)) {
6008 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6009 pic16_aopPut(AOP(result),"a",offset);
6011 pic16_emitcode("xrl","%s,a",
6012 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
6018 // left & result in different registers
6019 if(AOP_TYPE(result) == AOP_CRY){
6021 // if(size), result in bit
6022 // if(!size && ifx), conditional oper: if(left ^ right)
6023 symbol *tlbl = newiTempLabel(NULL);
6024 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6026 pic16_emitcode("setb","c");
6028 if((AOP_TYPE(right) == AOP_LIT) &&
6029 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6030 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6032 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6033 pic16_emitcode("xrl","a,%s",
6034 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6036 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6041 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6042 pic16_outBitC(result);
6044 jmpTrueOrFalse(ifx, tlbl);
6045 } else for(;(size--);offset++){
6047 // result = left & right
6048 if(AOP_TYPE(right) == AOP_LIT){
6049 int t = (lit >> (offset*8)) & 0x0FFL;
6052 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6053 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6054 pic16_emitcode("movf","%s,w",
6055 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6056 pic16_emitcode("movwf","%s",
6057 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6060 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6061 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6062 pic16_emitcode("comf","%s,w",
6063 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6064 pic16_emitcode("movwf","%s",
6065 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6068 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6069 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6070 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6071 pic16_emitcode("movlw","0x%x",t);
6072 pic16_emitcode("xorwf","%s,w",
6073 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6074 pic16_emitcode("movwf","%s",
6075 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6081 // faster than result <- left, anl result,right
6082 // and better if result is SFR
6083 if (AOP_TYPE(left) == AOP_ACC) {
6084 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6085 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6087 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6088 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6089 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6090 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6092 if ( AOP_TYPE(result) != AOP_ACC){
6093 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6094 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6100 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6101 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6102 pic16_freeAsmop(result,NULL,ic,TRUE);
6105 /*-----------------------------------------------------------------*/
6106 /* genInline - write the inline code out */
6107 /*-----------------------------------------------------------------*/
6108 static void genInline (iCode *ic)
6110 char *buffer, *bp, *bp1;
6112 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6114 _G.inLine += (!options.asmpeep);
6116 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6117 strcpy(buffer,IC_INLINE(ic));
6119 /* emit each line as a code */
6125 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6132 pic16_emitcode(bp1,"");
6138 if ((bp1 != bp) && *bp1)
6139 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6143 _G.inLine -= (!options.asmpeep);
6146 /*-----------------------------------------------------------------*/
6147 /* genRRC - rotate right with carry */
6148 /*-----------------------------------------------------------------*/
6149 static void genRRC (iCode *ic)
6151 operand *left , *result ;
6152 int size, offset = 0, same;
6154 /* rotate right with carry */
6156 result=IC_RESULT(ic);
6157 pic16_aopOp (left,ic,FALSE);
6158 pic16_aopOp (result,ic,FALSE);
6160 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6162 same = pic16_sameRegs(AOP(result),AOP(left));
6164 size = AOP_SIZE(result);
6166 /* get the lsb and put it into the carry */
6167 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6174 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6176 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6177 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6183 pic16_freeAsmop(left,NULL,ic,TRUE);
6184 pic16_freeAsmop(result,NULL,ic,TRUE);
6187 /*-----------------------------------------------------------------*/
6188 /* genRLC - generate code for rotate left with carry */
6189 /*-----------------------------------------------------------------*/
6190 static void genRLC (iCode *ic)
6192 operand *left , *result ;
6193 int size, offset = 0;
6196 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6197 /* rotate right with carry */
6199 result=IC_RESULT(ic);
6200 pic16_aopOp (left,ic,FALSE);
6201 pic16_aopOp (result,ic,FALSE);
6203 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6205 same = pic16_sameRegs(AOP(result),AOP(left));
6207 /* move it to the result */
6208 size = AOP_SIZE(result);
6210 /* get the msb and put it into the carry */
6211 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6218 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6220 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6221 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6228 pic16_freeAsmop(left,NULL,ic,TRUE);
6229 pic16_freeAsmop(result,NULL,ic,TRUE);
6232 /*-----------------------------------------------------------------*/
6233 /* genGetHbit - generates code get highest order bit */
6234 /*-----------------------------------------------------------------*/
6235 static void genGetHbit (iCode *ic)
6237 operand *left, *result;
6239 result=IC_RESULT(ic);
6240 pic16_aopOp (left,ic,FALSE);
6241 pic16_aopOp (result,ic,FALSE);
6243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6244 /* get the highest order byte into a */
6245 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6246 if(AOP_TYPE(result) == AOP_CRY){
6247 pic16_emitcode("rlc","a");
6248 pic16_outBitC(result);
6251 pic16_emitcode("rl","a");
6252 pic16_emitcode("anl","a,#0x01");
6253 pic16_outAcc(result);
6257 pic16_freeAsmop(left,NULL,ic,TRUE);
6258 pic16_freeAsmop(result,NULL,ic,TRUE);
6261 /*-----------------------------------------------------------------*/
6262 /* AccRol - rotate left accumulator by known count */
6263 /*-----------------------------------------------------------------*/
6264 static void AccRol (int shCount)
6266 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6267 shCount &= 0x0007; // shCount : 0..7
6272 pic16_emitcode("rl","a");
6275 pic16_emitcode("rl","a");
6276 pic16_emitcode("rl","a");
6279 pic16_emitcode("swap","a");
6280 pic16_emitcode("rr","a");
6283 pic16_emitcode("swap","a");
6286 pic16_emitcode("swap","a");
6287 pic16_emitcode("rl","a");
6290 pic16_emitcode("rr","a");
6291 pic16_emitcode("rr","a");
6294 pic16_emitcode("rr","a");
6299 /*-----------------------------------------------------------------*/
6300 /* AccLsh - left shift accumulator by known count */
6301 /*-----------------------------------------------------------------*/
6302 static void AccLsh (int shCount)
6304 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6307 pic16_emitcode("add","a,acc");
6310 pic16_emitcode("add","a,acc");
6311 pic16_emitcode("add","a,acc");
6313 /* rotate left accumulator */
6315 /* and kill the lower order bits */
6316 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6321 /*-----------------------------------------------------------------*/
6322 /* AccRsh - right shift accumulator by known count */
6323 /*-----------------------------------------------------------------*/
6324 static void AccRsh (int shCount)
6326 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6330 pic16_emitcode("rrc","a");
6332 /* rotate right accumulator */
6333 AccRol(8 - shCount);
6334 /* and kill the higher order bits */
6335 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6341 /*-----------------------------------------------------------------*/
6342 /* AccSRsh - signed right shift accumulator by known count */
6343 /*-----------------------------------------------------------------*/
6344 static void AccSRsh (int shCount)
6347 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6350 pic16_emitcode("mov","c,acc.7");
6351 pic16_emitcode("rrc","a");
6352 } else if(shCount == 2){
6353 pic16_emitcode("mov","c,acc.7");
6354 pic16_emitcode("rrc","a");
6355 pic16_emitcode("mov","c,acc.7");
6356 pic16_emitcode("rrc","a");
6358 tlbl = newiTempLabel(NULL);
6359 /* rotate right accumulator */
6360 AccRol(8 - shCount);
6361 /* and kill the higher order bits */
6362 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6363 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6364 pic16_emitcode("orl","a,#0x%02x",
6365 (unsigned char)~SRMask[shCount]);
6366 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6371 /*-----------------------------------------------------------------*/
6372 /* shiftR1Left2Result - shift right one byte from left to result */
6373 /*-----------------------------------------------------------------*/
6374 static void shiftR1Left2ResultSigned (operand *left, int offl,
6375 operand *result, int offr,
6380 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6382 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6386 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6388 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6390 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6391 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),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));
6404 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6405 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6411 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6413 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6414 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6417 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6418 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6419 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6421 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6422 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6424 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6428 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6429 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6430 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6431 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6432 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6436 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6438 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6439 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6441 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6442 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6443 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6444 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6445 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6450 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6451 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6452 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6453 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6454 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6455 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6457 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6458 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6459 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6460 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6461 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6467 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6468 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6469 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6470 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6472 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6473 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6474 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6482 /*-----------------------------------------------------------------*/
6483 /* shiftR1Left2Result - shift right one byte from left to result */
6484 /*-----------------------------------------------------------------*/
6485 static void shiftR1Left2Result (operand *left, int offl,
6486 operand *result, int offr,
6487 int shCount, int sign)
6491 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6493 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6495 /* Copy the msb into the carry if signed. */
6497 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6507 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6509 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6510 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6516 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6518 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6519 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6522 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6527 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6529 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6530 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6533 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6534 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6535 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6536 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6540 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6541 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6542 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6546 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6547 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6548 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6550 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6555 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6556 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6557 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6558 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6559 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6564 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6565 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6566 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6575 /*-----------------------------------------------------------------*/
6576 /* shiftL1Left2Result - shift left one byte from left to result */
6577 /*-----------------------------------------------------------------*/
6578 static void shiftL1Left2Result (operand *left, int offl,
6579 operand *result, int offr, int shCount)
6584 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6586 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6587 DEBUGpic16_emitcode ("; ***","same = %d",same);
6588 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6590 /* shift left accumulator */
6591 //AccLsh(shCount); // don't comment out just yet...
6592 // pic16_aopPut(AOP(result),"a",offr);
6596 /* Shift left 1 bit position */
6597 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6599 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6601 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6602 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6606 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6607 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6608 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6609 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6612 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6613 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6614 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6615 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6616 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6619 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6620 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6621 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6624 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6625 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6626 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6627 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6630 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6631 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6632 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6633 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6634 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6637 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6638 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6639 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6643 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6648 /*-----------------------------------------------------------------*/
6649 /* movLeft2Result - move byte from left to result */
6650 /*-----------------------------------------------------------------*/
6651 static void movLeft2Result (operand *left, int offl,
6652 operand *result, int offr)
6655 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6656 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6657 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6659 if (*l == '@' && (IS_AOP_PREG(result))) {
6660 pic16_emitcode("mov","a,%s",l);
6661 pic16_aopPut(AOP(result),"a",offr);
6663 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6664 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6669 /*-----------------------------------------------------------------*/
6670 /* shiftL2Left2Result - shift left two bytes from left to result */
6671 /*-----------------------------------------------------------------*/
6672 static void shiftL2Left2Result (operand *left, int offl,
6673 operand *result, int offr, int shCount)
6677 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6679 if(pic16_sameRegs(AOP(result), AOP(left))) {
6687 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6688 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6689 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6693 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6694 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6700 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6701 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6702 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6703 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6704 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6705 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6706 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6708 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6709 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6713 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6714 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6715 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6716 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6717 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6718 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6719 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6720 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6721 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6722 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6725 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6726 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6727 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6728 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6729 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6739 /* note, use a mov/add for the shift since the mov has a
6740 chance of getting optimized out */
6741 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6742 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6743 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6744 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6745 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6749 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6750 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6756 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6757 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6758 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6759 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6760 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6761 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6762 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6763 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6767 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6768 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6772 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6773 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6774 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6775 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6777 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6778 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6779 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6780 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6781 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6782 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6783 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6784 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6787 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6788 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6789 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6790 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6791 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6796 /*-----------------------------------------------------------------*/
6797 /* shiftR2Left2Result - shift right two bytes from left to result */
6798 /*-----------------------------------------------------------------*/
6799 static void shiftR2Left2Result (operand *left, int offl,
6800 operand *result, int offr,
6801 int shCount, int sign)
6805 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6806 same = pic16_sameRegs(AOP(result), AOP(left));
6808 if(same && ((offl + MSB16) == offr)){
6810 /* don't crash result[offr] */
6811 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6812 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6815 movLeft2Result(left,offl, result, offr);
6816 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6819 /* a:x >> shCount (x = lsb(result))*/
6822 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6824 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6833 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6838 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6839 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6841 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6842 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6843 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6844 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6849 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6852 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6853 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6860 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6861 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6862 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6864 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6865 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6866 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6867 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6869 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6870 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6871 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6873 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6874 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6875 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6876 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6877 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6881 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6882 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6886 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6887 pic16_emitpcode(POC_BTFSC,
6888 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6889 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6897 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6898 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6900 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6901 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6902 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6903 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6905 pic16_emitpcode(POC_BTFSC,
6906 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6907 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6909 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6910 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6911 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6912 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6914 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6915 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6916 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6917 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6918 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6919 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6920 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6921 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6923 pic16_emitpcode(POC_BTFSC,
6924 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6925 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6927 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6928 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6935 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6936 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6937 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6938 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6941 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6943 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6948 /*-----------------------------------------------------------------*/
6949 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6950 /*-----------------------------------------------------------------*/
6951 static void shiftLLeftOrResult (operand *left, int offl,
6952 operand *result, int offr, int shCount)
6954 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6955 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6956 /* shift left accumulator */
6958 /* or with result */
6959 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6960 /* back to result */
6961 pic16_aopPut(AOP(result),"a",offr);
6964 /*-----------------------------------------------------------------*/
6965 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6966 /*-----------------------------------------------------------------*/
6967 static void shiftRLeftOrResult (operand *left, int offl,
6968 operand *result, int offr, int shCount)
6970 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6971 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6972 /* shift right accumulator */
6974 /* or with result */
6975 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6976 /* back to result */
6977 pic16_aopPut(AOP(result),"a",offr);
6980 /*-----------------------------------------------------------------*/
6981 /* genlshOne - left shift a one byte quantity by known count */
6982 /*-----------------------------------------------------------------*/
6983 static void genlshOne (operand *result, operand *left, int shCount)
6985 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6986 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6989 /*-----------------------------------------------------------------*/
6990 /* genlshTwo - left shift two bytes by known amount != 0 */
6991 /*-----------------------------------------------------------------*/
6992 static void genlshTwo (operand *result,operand *left, int shCount)
6996 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6997 size = pic16_getDataSize(result);
6999 /* if shCount >= 8 */
7005 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7007 movLeft2Result(left, LSB, result, MSB16);
7009 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
7012 /* 1 <= shCount <= 7 */
7015 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7017 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7021 /*-----------------------------------------------------------------*/
7022 /* shiftLLong - shift left one long from left to result */
7023 /* offl = LSB or MSB16 */
7024 /*-----------------------------------------------------------------*/
7025 static void shiftLLong (operand *left, operand *result, int offr )
7028 int size = AOP_SIZE(result);
7030 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7031 if(size >= LSB+offr){
7032 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7034 pic16_emitcode("add","a,acc");
7035 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7036 size >= MSB16+offr && offr != LSB )
7037 pic16_emitcode("xch","a,%s",
7038 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7040 pic16_aopPut(AOP(result),"a",LSB+offr);
7043 if(size >= MSB16+offr){
7044 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7045 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7048 pic16_emitcode("rlc","a");
7049 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7050 size >= MSB24+offr && offr != LSB)
7051 pic16_emitcode("xch","a,%s",
7052 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7054 pic16_aopPut(AOP(result),"a",MSB16+offr);
7057 if(size >= MSB24+offr){
7058 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7059 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7062 pic16_emitcode("rlc","a");
7063 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7064 size >= MSB32+offr && offr != LSB )
7065 pic16_emitcode("xch","a,%s",
7066 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7068 pic16_aopPut(AOP(result),"a",MSB24+offr);
7071 if(size > MSB32+offr){
7072 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7073 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7076 pic16_emitcode("rlc","a");
7077 pic16_aopPut(AOP(result),"a",MSB32+offr);
7080 pic16_aopPut(AOP(result),zero,LSB);
7083 /*-----------------------------------------------------------------*/
7084 /* genlshFour - shift four byte by a known amount != 0 */
7085 /*-----------------------------------------------------------------*/
7086 static void genlshFour (operand *result, operand *left, int shCount)
7090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7091 size = AOP_SIZE(result);
7093 /* if shifting more that 3 bytes */
7094 if (shCount >= 24 ) {
7097 /* lowest order of left goes to the highest
7098 order of the destination */
7099 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7101 movLeft2Result(left, LSB, result, MSB32);
7102 pic16_aopPut(AOP(result),zero,LSB);
7103 pic16_aopPut(AOP(result),zero,MSB16);
7104 pic16_aopPut(AOP(result),zero,MSB32);
7108 /* more than two bytes */
7109 else if ( shCount >= 16 ) {
7110 /* lower order two bytes goes to higher order two bytes */
7112 /* if some more remaining */
7114 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7116 movLeft2Result(left, MSB16, result, MSB32);
7117 movLeft2Result(left, LSB, result, MSB24);
7119 pic16_aopPut(AOP(result),zero,MSB16);
7120 pic16_aopPut(AOP(result),zero,LSB);
7124 /* if more than 1 byte */
7125 else if ( shCount >= 8 ) {
7126 /* lower order three bytes goes to higher order three bytes */
7130 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7132 movLeft2Result(left, LSB, result, MSB16);
7134 else{ /* size = 4 */
7136 movLeft2Result(left, MSB24, result, MSB32);
7137 movLeft2Result(left, MSB16, result, MSB24);
7138 movLeft2Result(left, LSB, result, MSB16);
7139 pic16_aopPut(AOP(result),zero,LSB);
7141 else if(shCount == 1)
7142 shiftLLong(left, result, MSB16);
7144 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7145 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7146 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7147 pic16_aopPut(AOP(result),zero,LSB);
7152 /* 1 <= shCount <= 7 */
7153 else if(shCount <= 2){
7154 shiftLLong(left, result, LSB);
7156 shiftLLong(result, result, LSB);
7158 /* 3 <= shCount <= 7, optimize */
7160 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7161 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7162 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7166 /*-----------------------------------------------------------------*/
7167 /* genLeftShiftLiteral - left shifting by known count */
7168 /*-----------------------------------------------------------------*/
7169 static void genLeftShiftLiteral (operand *left,
7174 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7177 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7178 pic16_freeAsmop(right,NULL,ic,TRUE);
7180 pic16_aopOp(left,ic,FALSE);
7181 pic16_aopOp(result,ic,FALSE);
7183 size = getSize(operandType(result));
7186 pic16_emitcode("; shift left ","result %d, left %d",size,
7190 /* I suppose that the left size >= result size */
7193 movLeft2Result(left, size, result, size);
7197 else if(shCount >= (size * 8))
7199 pic16_aopPut(AOP(result),zero,size);
7203 genlshOne (result,left,shCount);
7208 genlshTwo (result,left,shCount);
7212 genlshFour (result,left,shCount);
7216 pic16_freeAsmop(left,NULL,ic,TRUE);
7217 pic16_freeAsmop(result,NULL,ic,TRUE);
7220 /*-----------------------------------------------------------------*
7221 * genMultiAsm - repeat assembly instruction for size of register.
7222 * if endian == 1, then the high byte (i.e base address + size of
7223 * register) is used first else the low byte is used first;
7224 *-----------------------------------------------------------------*/
7225 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7230 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7243 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7248 /*-----------------------------------------------------------------*/
7249 /* genLeftShift - generates code for left shifting */
7250 /*-----------------------------------------------------------------*/
7251 static void genLeftShift (iCode *ic)
7253 operand *left,*right, *result;
7256 symbol *tlbl , *tlbl1;
7259 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7261 right = IC_RIGHT(ic);
7263 result = IC_RESULT(ic);
7265 pic16_aopOp(right,ic,FALSE);
7267 /* if the shift count is known then do it
7268 as efficiently as possible */
7269 if (AOP_TYPE(right) == AOP_LIT) {
7270 genLeftShiftLiteral (left,right,result,ic);
7274 /* shift count is unknown then we have to form
7275 a loop get the loop count in B : Note: we take
7276 only the lower order byte since shifting
7277 more that 32 bits make no sense anyway, ( the
7278 largest size of an object can be only 32 bits ) */
7281 pic16_aopOp(left,ic,FALSE);
7282 pic16_aopOp(result,ic,FALSE);
7284 /* now move the left to the result if they are not the
7286 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7287 AOP_SIZE(result) > 1) {
7289 size = AOP_SIZE(result);
7292 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7293 if (*l == '@' && (IS_AOP_PREG(result))) {
7295 pic16_emitcode("mov","a,%s",l);
7296 pic16_aopPut(AOP(result),"a",offset);
7298 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7299 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7300 //pic16_aopPut(AOP(result),l,offset);
7306 size = AOP_SIZE(result);
7308 /* if it is only one byte then */
7310 if(optimized_for_speed) {
7311 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7312 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7313 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7314 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7315 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7316 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7317 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7318 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7319 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7320 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7321 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7322 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7325 tlbl = newiTempLabel(NULL);
7326 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7327 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7328 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7331 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7332 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7333 pic16_emitpLabel(tlbl->key);
7334 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7335 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7337 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7342 if (pic16_sameRegs(AOP(left),AOP(result))) {
7344 tlbl = newiTempLabel(NULL);
7345 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7346 genMultiAsm(POC_RRCF, result, size,1);
7347 pic16_emitpLabel(tlbl->key);
7348 genMultiAsm(POC_RLCF, result, size,0);
7349 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7351 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7355 //tlbl = newiTempLabel(NULL);
7357 //tlbl1 = newiTempLabel(NULL);
7359 //reAdjustPreg(AOP(result));
7361 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7362 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7363 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7365 //pic16_emitcode("add","a,acc");
7366 //pic16_aopPut(AOP(result),"a",offset++);
7368 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7370 // pic16_emitcode("rlc","a");
7371 // pic16_aopPut(AOP(result),"a",offset++);
7373 //reAdjustPreg(AOP(result));
7375 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7376 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7379 tlbl = newiTempLabel(NULL);
7380 tlbl1= newiTempLabel(NULL);
7382 size = AOP_SIZE(result);
7385 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7387 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7389 /* offset should be 0, 1 or 3 */
7390 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7392 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7394 pic16_emitpcode(POC_MOVWF, pctemp);
7397 pic16_emitpLabel(tlbl->key);
7400 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7402 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7404 pic16_emitpcode(POC_DECFSZ, pctemp);
7405 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7406 pic16_emitpLabel(tlbl1->key);
7408 pic16_popReleaseTempReg(pctemp);
7412 pic16_freeAsmop (right,NULL,ic,TRUE);
7413 pic16_freeAsmop(left,NULL,ic,TRUE);
7414 pic16_freeAsmop(result,NULL,ic,TRUE);
7417 /*-----------------------------------------------------------------*/
7418 /* genrshOne - right shift a one byte quantity by known count */
7419 /*-----------------------------------------------------------------*/
7420 static void genrshOne (operand *result, operand *left,
7421 int shCount, int sign)
7423 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7424 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7427 /*-----------------------------------------------------------------*/
7428 /* genrshTwo - right shift two bytes by known amount != 0 */
7429 /*-----------------------------------------------------------------*/
7430 static void genrshTwo (operand *result,operand *left,
7431 int shCount, int sign)
7433 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7434 /* if shCount >= 8 */
7438 shiftR1Left2Result(left, MSB16, result, LSB,
7441 movLeft2Result(left, MSB16, result, LSB);
7443 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7446 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7447 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7451 /* 1 <= shCount <= 7 */
7453 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7456 /*-----------------------------------------------------------------*/
7457 /* shiftRLong - shift right one long from left to result */
7458 /* offl = LSB or MSB16 */
7459 /*-----------------------------------------------------------------*/
7460 static void shiftRLong (operand *left, int offl,
7461 operand *result, int sign)
7463 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7465 pic16_emitcode("clr","c");
7466 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7468 pic16_emitcode("mov","c,acc.7");
7469 pic16_emitcode("rrc","a");
7470 pic16_aopPut(AOP(result),"a",MSB32-offl);
7472 /* add sign of "a" */
7473 pic16_addSign(result, MSB32, sign);
7475 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7476 pic16_emitcode("rrc","a");
7477 pic16_aopPut(AOP(result),"a",MSB24-offl);
7479 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7480 pic16_emitcode("rrc","a");
7481 pic16_aopPut(AOP(result),"a",MSB16-offl);
7484 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7485 pic16_emitcode("rrc","a");
7486 pic16_aopPut(AOP(result),"a",LSB);
7490 /*-----------------------------------------------------------------*/
7491 /* genrshFour - shift four byte by a known amount != 0 */
7492 /*-----------------------------------------------------------------*/
7493 static void genrshFour (operand *result, operand *left,
7494 int shCount, int sign)
7496 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7497 /* if shifting more that 3 bytes */
7498 if(shCount >= 24 ) {
7501 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7503 movLeft2Result(left, MSB32, result, LSB);
7505 pic16_addSign(result, MSB16, sign);
7507 else if(shCount >= 16){
7510 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7512 movLeft2Result(left, MSB24, result, LSB);
7513 movLeft2Result(left, MSB32, result, MSB16);
7515 pic16_addSign(result, MSB24, sign);
7517 else if(shCount >= 8){
7520 shiftRLong(left, MSB16, result, sign);
7521 else if(shCount == 0){
7522 movLeft2Result(left, MSB16, result, LSB);
7523 movLeft2Result(left, MSB24, result, MSB16);
7524 movLeft2Result(left, MSB32, result, MSB24);
7525 pic16_addSign(result, MSB32, sign);
7528 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7529 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7530 /* the last shift is signed */
7531 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7532 pic16_addSign(result, MSB32, sign);
7535 else{ /* 1 <= shCount <= 7 */
7537 shiftRLong(left, LSB, result, sign);
7539 shiftRLong(result, LSB, result, sign);
7542 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7543 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7544 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7549 /*-----------------------------------------------------------------*/
7550 /* genRightShiftLiteral - right shifting by known count */
7551 /*-----------------------------------------------------------------*/
7552 static void genRightShiftLiteral (operand *left,
7558 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7561 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7562 pic16_freeAsmop(right,NULL,ic,TRUE);
7564 pic16_aopOp(left,ic,FALSE);
7565 pic16_aopOp(result,ic,FALSE);
7568 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7572 lsize = pic16_getDataSize(left);
7573 res_size = pic16_getDataSize(result);
7574 /* test the LEFT size !!! */
7576 /* I suppose that the left size >= result size */
7579 movLeft2Result(left, lsize, result, res_size);
7582 else if(shCount >= (lsize * 8)){
7585 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7587 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7588 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7593 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7594 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7595 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7597 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7602 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7609 genrshOne (result,left,shCount,sign);
7613 genrshTwo (result,left,shCount,sign);
7617 genrshFour (result,left,shCount,sign);
7625 pic16_freeAsmop(left,NULL,ic,TRUE);
7626 pic16_freeAsmop(result,NULL,ic,TRUE);
7629 /*-----------------------------------------------------------------*/
7630 /* genSignedRightShift - right shift of signed number */
7631 /*-----------------------------------------------------------------*/
7632 static void genSignedRightShift (iCode *ic)
7634 operand *right, *left, *result;
7637 symbol *tlbl, *tlbl1 ;
7640 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7642 /* we do it the hard way put the shift count in b
7643 and loop thru preserving the sign */
7644 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7646 right = IC_RIGHT(ic);
7648 result = IC_RESULT(ic);
7650 pic16_aopOp(right,ic,FALSE);
7651 pic16_aopOp(left,ic,FALSE);
7652 pic16_aopOp(result,ic,FALSE);
7655 if ( AOP_TYPE(right) == AOP_LIT) {
7656 genRightShiftLiteral (left,right,result,ic,1);
7659 /* shift count is unknown then we have to form
7660 a loop get the loop count in B : Note: we take
7661 only the lower order byte since shifting
7662 more that 32 bits make no sense anyway, ( the
7663 largest size of an object can be only 32 bits ) */
7665 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7666 //pic16_emitcode("inc","b");
7667 //pic16_freeAsmop (right,NULL,ic,TRUE);
7668 //pic16_aopOp(left,ic,FALSE);
7669 //pic16_aopOp(result,ic,FALSE);
7671 /* now move the left to the result if they are not the
7673 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7674 AOP_SIZE(result) > 1) {
7676 size = AOP_SIZE(result);
7680 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7681 if (*l == '@' && IS_AOP_PREG(result)) {
7683 pic16_emitcode("mov","a,%s",l);
7684 pic16_aopPut(AOP(result),"a",offset);
7686 pic16_aopPut(AOP(result),l,offset);
7688 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7689 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7695 /* mov the highest order bit to OVR */
7696 tlbl = newiTempLabel(NULL);
7697 tlbl1= newiTempLabel(NULL);
7699 size = AOP_SIZE(result);
7702 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7704 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7706 /* offset should be 0, 1 or 3 */
7707 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7709 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7711 pic16_emitpcode(POC_MOVWF, pctemp);
7714 pic16_emitpLabel(tlbl->key);
7716 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7717 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7720 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7723 pic16_emitpcode(POC_DECFSZ, pctemp);
7724 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7725 pic16_emitpLabel(tlbl1->key);
7727 pic16_popReleaseTempReg(pctemp);
7729 size = AOP_SIZE(result);
7731 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7732 pic16_emitcode("rlc","a");
7733 pic16_emitcode("mov","ov,c");
7734 /* if it is only one byte then */
7736 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7738 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7739 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7740 pic16_emitcode("mov","c,ov");
7741 pic16_emitcode("rrc","a");
7742 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7743 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7744 pic16_aopPut(AOP(result),"a",0);
7748 reAdjustPreg(AOP(result));
7749 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7750 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7751 pic16_emitcode("mov","c,ov");
7753 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7755 pic16_emitcode("rrc","a");
7756 pic16_aopPut(AOP(result),"a",offset--);
7758 reAdjustPreg(AOP(result));
7759 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7760 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7765 pic16_freeAsmop(left,NULL,ic,TRUE);
7766 pic16_freeAsmop(result,NULL,ic,TRUE);
7767 pic16_freeAsmop(right,NULL,ic,TRUE);
7770 /*-----------------------------------------------------------------*/
7771 /* genRightShift - generate code for right shifting */
7772 /*-----------------------------------------------------------------*/
7773 static void genRightShift (iCode *ic)
7775 operand *right, *left, *result;
7779 symbol *tlbl, *tlbl1 ;
7781 /* if signed then we do it the hard way preserve the
7782 sign bit moving it inwards */
7783 retype = getSpec(operandType(IC_RESULT(ic)));
7784 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7786 if (!SPEC_USIGN(retype)) {
7787 genSignedRightShift (ic);
7791 /* signed & unsigned types are treated the same : i.e. the
7792 signed is NOT propagated inwards : quoting from the
7793 ANSI - standard : "for E1 >> E2, is equivalent to division
7794 by 2**E2 if unsigned or if it has a non-negative value,
7795 otherwise the result is implementation defined ", MY definition
7796 is that the sign does not get propagated */
7798 right = IC_RIGHT(ic);
7800 result = IC_RESULT(ic);
7802 pic16_aopOp(right,ic,FALSE);
7804 /* if the shift count is known then do it
7805 as efficiently as possible */
7806 if (AOP_TYPE(right) == AOP_LIT) {
7807 genRightShiftLiteral (left,right,result,ic, 0);
7811 /* shift count is unknown then we have to form
7812 a loop get the loop count in B : Note: we take
7813 only the lower order byte since shifting
7814 more that 32 bits make no sense anyway, ( the
7815 largest size of an object can be only 32 bits ) */
7817 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7818 pic16_emitcode("inc","b");
7819 pic16_aopOp(left,ic,FALSE);
7820 pic16_aopOp(result,ic,FALSE);
7822 /* now move the left to the result if they are not the
7824 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7825 AOP_SIZE(result) > 1) {
7827 size = AOP_SIZE(result);
7830 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7831 if (*l == '@' && IS_AOP_PREG(result)) {
7833 pic16_emitcode("mov","a,%s",l);
7834 pic16_aopPut(AOP(result),"a",offset);
7836 pic16_aopPut(AOP(result),l,offset);
7841 tlbl = newiTempLabel(NULL);
7842 tlbl1= newiTempLabel(NULL);
7843 size = AOP_SIZE(result);
7846 /* if it is only one byte then */
7849 tlbl = newiTempLabel(NULL);
7850 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7851 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7852 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7855 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7856 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7857 pic16_emitpLabel(tlbl->key);
7858 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7859 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7861 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7866 reAdjustPreg(AOP(result));
7867 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7868 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7871 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7873 pic16_emitcode("rrc","a");
7874 pic16_aopPut(AOP(result),"a",offset--);
7876 reAdjustPreg(AOP(result));
7878 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7879 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7882 pic16_freeAsmop(left,NULL,ic,TRUE);
7883 pic16_freeAsmop (right,NULL,ic,TRUE);
7884 pic16_freeAsmop(result,NULL,ic,TRUE);
7887 /*-----------------------------------------------------------------*/
7888 /* genUnpackBits - generates code for unpacking bits */
7889 /*-----------------------------------------------------------------*/
7890 static void genUnpackBits (operand *result, char *rname, int ptype)
7897 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7898 etype = getSpec(operandType(result));
7900 /* read the first byte */
7905 pic16_emitcode("mov","a,@%s",rname);
7909 pic16_emitcode("movx","a,@%s",rname);
7913 pic16_emitcode("movx","a,@dptr");
7917 pic16_emitcode("clr","a");
7918 pic16_emitcode("movc","a","@a+dptr");
7922 pic16_emitcode("lcall","__gptrget");
7926 /* if we have bitdisplacement then it fits */
7927 /* into this byte completely or if length is */
7928 /* less than a byte */
7929 if ((shCnt = SPEC_BSTR(etype)) ||
7930 (SPEC_BLEN(etype) <= 8)) {
7932 /* shift right acc */
7935 pic16_emitcode("anl","a,#0x%02x",
7936 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7937 pic16_aopPut(AOP(result),"a",offset);
7941 /* bit field did not fit in a byte */
7942 rlen = SPEC_BLEN(etype) - 8;
7943 pic16_aopPut(AOP(result),"a",offset++);
7950 pic16_emitcode("inc","%s",rname);
7951 pic16_emitcode("mov","a,@%s",rname);
7955 pic16_emitcode("inc","%s",rname);
7956 pic16_emitcode("movx","a,@%s",rname);
7960 pic16_emitcode("inc","dptr");
7961 pic16_emitcode("movx","a,@dptr");
7965 pic16_emitcode("clr","a");
7966 pic16_emitcode("inc","dptr");
7967 pic16_emitcode("movc","a","@a+dptr");
7971 pic16_emitcode("inc","dptr");
7972 pic16_emitcode("lcall","__gptrget");
7977 /* if we are done */
7981 pic16_aopPut(AOP(result),"a",offset++);
7986 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7987 pic16_aopPut(AOP(result),"a",offset);
7994 /*-----------------------------------------------------------------*/
7995 /* genDataPointerGet - generates code when ptr offset is known */
7996 /*-----------------------------------------------------------------*/
7997 static void genDataPointerGet (operand *left,
8001 int size , offset = 0;
8004 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8007 /* optimization - most of the time, left and result are the same
8008 * address, but different types. for the pic code, we could omit
8012 pic16_aopOp(result,ic,TRUE);
8014 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8016 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
8018 size = AOP_SIZE(result);
8021 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8025 pic16_freeAsmop(left,NULL,ic,TRUE);
8026 pic16_freeAsmop(result,NULL,ic,TRUE);
8029 /*-----------------------------------------------------------------*/
8030 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8031 /*-----------------------------------------------------------------*/
8032 static void genNearPointerGet (operand *left,
8037 //regs *preg = NULL ;
8039 sym_link *rtype, *retype;
8040 sym_link *ltype = operandType(left);
8043 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8045 rtype = operandType(result);
8046 retype= getSpec(rtype);
8048 pic16_aopOp(left,ic,FALSE);
8050 /* if left is rematerialisable and
8051 result is not bit variable type and
8052 the left is pointer to data space i.e
8053 lower 128 bytes of space */
8054 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8055 !IS_BITVAR(retype) &&
8056 DCL_TYPE(ltype) == POINTER) {
8057 //genDataPointerGet (left,result,ic);
8061 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8063 /* if the value is already in a pointer register
8064 then don't need anything more */
8065 if (!AOP_INPREG(AOP(left))) {
8066 /* otherwise get a free pointer register */
8067 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8070 preg = getFreePtr(ic,&aop,FALSE);
8071 pic16_emitcode("mov","%s,%s",
8073 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8074 rname = preg->name ;
8078 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8080 pic16_aopOp (result,ic,FALSE);
8082 /* if bitfield then unpack the bits */
8083 if (IS_BITVAR(retype))
8084 genUnpackBits (result,rname,POINTER);
8086 /* we have can just get the values */
8087 int size = AOP_SIZE(result);
8090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8092 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8093 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8095 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8096 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8098 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8102 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8104 pic16_emitcode("mov","a,@%s",rname);
8105 pic16_aopPut(AOP(result),"a",offset);
8107 sprintf(buffer,"@%s",rname);
8108 pic16_aopPut(AOP(result),buffer,offset);
8112 pic16_emitcode("inc","%s",rname);
8117 /* now some housekeeping stuff */
8119 /* we had to allocate for this iCode */
8120 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8121 pic16_freeAsmop(NULL,aop,ic,TRUE);
8123 /* we did not allocate which means left
8124 already in a pointer register, then
8125 if size > 0 && this could be used again
8126 we have to point it back to where it
8128 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8129 if (AOP_SIZE(result) > 1 &&
8130 !OP_SYMBOL(left)->remat &&
8131 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8133 int size = AOP_SIZE(result) - 1;
8135 pic16_emitcode("dec","%s",rname);
8140 pic16_freeAsmop(left,NULL,ic,TRUE);
8141 pic16_freeAsmop(result,NULL,ic,TRUE);
8145 /*-----------------------------------------------------------------*/
8146 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8147 /*-----------------------------------------------------------------*/
8148 static void genPagedPointerGet (operand *left,
8155 sym_link *rtype, *retype;
8157 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8159 rtype = operandType(result);
8160 retype= getSpec(rtype);
8162 pic16_aopOp(left,ic,FALSE);
8164 /* if the value is already in a pointer register
8165 then don't need anything more */
8166 if (!AOP_INPREG(AOP(left))) {
8167 /* otherwise get a free pointer register */
8169 preg = getFreePtr(ic,&aop,FALSE);
8170 pic16_emitcode("mov","%s,%s",
8172 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8173 rname = preg->name ;
8175 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8177 pic16_freeAsmop(left,NULL,ic,TRUE);
8178 pic16_aopOp (result,ic,FALSE);
8180 /* if bitfield then unpack the bits */
8181 if (IS_BITVAR(retype))
8182 genUnpackBits (result,rname,PPOINTER);
8184 /* we have can just get the values */
8185 int size = AOP_SIZE(result);
8190 pic16_emitcode("movx","a,@%s",rname);
8191 pic16_aopPut(AOP(result),"a",offset);
8196 pic16_emitcode("inc","%s",rname);
8200 /* now some housekeeping stuff */
8202 /* we had to allocate for this iCode */
8203 pic16_freeAsmop(NULL,aop,ic,TRUE);
8205 /* we did not allocate which means left
8206 already in a pointer register, then
8207 if size > 0 && this could be used again
8208 we have to point it back to where it
8210 if (AOP_SIZE(result) > 1 &&
8211 !OP_SYMBOL(left)->remat &&
8212 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8214 int size = AOP_SIZE(result) - 1;
8216 pic16_emitcode("dec","%s",rname);
8221 pic16_freeAsmop(result,NULL,ic,TRUE);
8226 /*-----------------------------------------------------------------*/
8227 /* genFarPointerGet - gget value from far space */
8228 /*-----------------------------------------------------------------*/
8229 static void genFarPointerGet (operand *left,
8230 operand *result, iCode *ic)
8233 sym_link *retype = getSpec(operandType(result));
8235 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8237 pic16_aopOp(left,ic,FALSE);
8239 /* if the operand is already in dptr
8240 then we do nothing else we move the value to dptr */
8241 if (AOP_TYPE(left) != AOP_STR) {
8242 /* if this is remateriazable */
8243 if (AOP_TYPE(left) == AOP_IMMD)
8244 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8245 else { /* we need to get it byte by byte */
8246 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8247 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8248 if (options.model == MODEL_FLAT24)
8250 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8254 /* so dptr know contains the address */
8255 pic16_freeAsmop(left,NULL,ic,TRUE);
8256 pic16_aopOp(result,ic,FALSE);
8258 /* if bit then unpack */
8259 if (IS_BITVAR(retype))
8260 genUnpackBits(result,"dptr",FPOINTER);
8262 size = AOP_SIZE(result);
8266 pic16_emitcode("movx","a,@dptr");
8267 pic16_aopPut(AOP(result),"a",offset++);
8269 pic16_emitcode("inc","dptr");
8273 pic16_freeAsmop(result,NULL,ic,TRUE);
8276 /*-----------------------------------------------------------------*/
8277 /* genCodePointerGet - get value from code space */
8278 /*-----------------------------------------------------------------*/
8279 static void genCodePointerGet (operand *left,
8280 operand *result, iCode *ic)
8283 sym_link *retype = getSpec(operandType(result));
8285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8287 pic16_aopOp(left,ic,FALSE);
8289 /* if the operand is already in dptr
8290 then we do nothing else we move the value to dptr */
8291 if (AOP_TYPE(left) != AOP_STR) {
8292 /* if this is remateriazable */
8293 if (AOP_TYPE(left) == AOP_IMMD)
8294 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8295 else { /* we need to get it byte by byte */
8296 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8297 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8298 if (options.model == MODEL_FLAT24)
8300 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8304 /* so dptr know contains the address */
8305 pic16_freeAsmop(left,NULL,ic,TRUE);
8306 pic16_aopOp(result,ic,FALSE);
8308 /* if bit then unpack */
8309 if (IS_BITVAR(retype))
8310 genUnpackBits(result,"dptr",CPOINTER);
8312 size = AOP_SIZE(result);
8316 pic16_emitcode("clr","a");
8317 pic16_emitcode("movc","a,@a+dptr");
8318 pic16_aopPut(AOP(result),"a",offset++);
8320 pic16_emitcode("inc","dptr");
8324 pic16_freeAsmop(result,NULL,ic,TRUE);
8327 /*-----------------------------------------------------------------*/
8328 /* genGenPointerGet - gget value from generic pointer space */
8329 /*-----------------------------------------------------------------*/
8330 static void genGenPointerGet (operand *left,
8331 operand *result, iCode *ic)
8334 sym_link *retype = getSpec(operandType(result));
8336 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8337 pic16_aopOp(left,ic,FALSE);
8338 pic16_aopOp(result,ic,FALSE);
8341 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8343 /* if the operand is already in dptr
8344 then we do nothing else we move the value to dptr */
8345 // if (AOP_TYPE(left) != AOP_STR) {
8346 /* if this is remateriazable */
8347 if (AOP_TYPE(left) == AOP_IMMD) {
8348 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8349 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8351 else { /* we need to get it byte by byte */
8353 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8354 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8356 size = AOP_SIZE(result);
8360 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8361 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8363 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8368 /* so dptr know contains the address */
8370 /* if bit then unpack */
8371 //if (IS_BITVAR(retype))
8372 // genUnpackBits(result,"dptr",GPOINTER);
8375 pic16_freeAsmop(left,NULL,ic,TRUE);
8376 pic16_freeAsmop(result,NULL,ic,TRUE);
8380 /*-----------------------------------------------------------------*/
8381 /* genConstPointerGet - get value from const generic pointer space */
8382 /*-----------------------------------------------------------------*/
8383 static void genConstPointerGet (operand *left,
8384 operand *result, iCode *ic)
8386 //sym_link *retype = getSpec(operandType(result));
8387 symbol *albl = newiTempLabel(NULL);
8388 symbol *blbl = newiTempLabel(NULL);
8391 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8392 pic16_aopOp(left,ic,FALSE);
8393 pic16_aopOp(result,ic,FALSE);
8396 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8398 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8400 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8401 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8402 pic16_emitpLabel(albl->key);
8404 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8406 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8407 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8408 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8409 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8411 pic16_emitpLabel(blbl->key);
8413 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8416 pic16_freeAsmop(left,NULL,ic,TRUE);
8417 pic16_freeAsmop(result,NULL,ic,TRUE);
8420 /*-----------------------------------------------------------------*/
8421 /* genPointerGet - generate code for pointer get */
8422 /*-----------------------------------------------------------------*/
8423 static void genPointerGet (iCode *ic)
8425 operand *left, *result ;
8426 sym_link *type, *etype;
8429 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8432 result = IC_RESULT(ic) ;
8434 /* depending on the type of pointer we need to
8435 move it to the correct pointer register */
8436 type = operandType(left);
8437 etype = getSpec(type);
8439 if (IS_PTR_CONST(type))
8440 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8442 /* if left is of type of pointer then it is simple */
8443 if (IS_PTR(type) && !IS_FUNC(type->next))
8444 p_type = DCL_TYPE(type);
8446 /* we have to go by the storage class */
8447 p_type = PTR_TYPE(SPEC_OCLS(etype));
8449 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8451 if (SPEC_OCLS(etype)->codesp ) {
8452 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8453 //p_type = CPOINTER ;
8456 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8457 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8458 /*p_type = FPOINTER ;*/
8460 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8461 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8462 /* p_type = PPOINTER; */
8464 if (SPEC_OCLS(etype) == idata )
8465 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8466 /* p_type = IPOINTER; */
8468 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8469 /* p_type = POINTER ; */
8472 /* now that we have the pointer type we assign
8473 the pointer values */
8478 genNearPointerGet (left,result,ic);
8482 genPagedPointerGet(left,result,ic);
8486 genFarPointerGet (left,result,ic);
8490 genConstPointerGet (left,result,ic);
8491 //pic16_emitcodePointerGet (left,result,ic);
8495 if (IS_PTR_CONST(type))
8496 genConstPointerGet (left,result,ic);
8498 genGenPointerGet (left,result,ic);
8504 /*-----------------------------------------------------------------*/
8505 /* genPackBits - generates code for packed bit storage */
8506 /*-----------------------------------------------------------------*/
8507 static void genPackBits (sym_link *etype ,
8509 char *rname, int p_type)
8517 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8518 blen = SPEC_BLEN(etype);
8519 bstr = SPEC_BSTR(etype);
8521 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8524 /* if the bit lenth is less than or */
8525 /* it exactly fits a byte then */
8526 if (SPEC_BLEN(etype) <= 8 ) {
8527 shCount = SPEC_BSTR(etype) ;
8529 /* shift left acc */
8532 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8537 pic16_emitcode ("mov","b,a");
8538 pic16_emitcode("mov","a,@%s",rname);
8542 pic16_emitcode ("mov","b,a");
8543 pic16_emitcode("movx","a,@dptr");
8547 pic16_emitcode ("push","b");
8548 pic16_emitcode ("push","acc");
8549 pic16_emitcode ("lcall","__gptrget");
8550 pic16_emitcode ("pop","b");
8554 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8555 ((unsigned char)(0xFF << (blen+bstr)) |
8556 (unsigned char)(0xFF >> (8-bstr)) ) );
8557 pic16_emitcode ("orl","a,b");
8558 if (p_type == GPOINTER)
8559 pic16_emitcode("pop","b");
8565 pic16_emitcode("mov","@%s,a",rname);
8569 pic16_emitcode("movx","@dptr,a");
8573 DEBUGpic16_emitcode(";lcall","__gptrput");
8578 if ( SPEC_BLEN(etype) <= 8 )
8581 pic16_emitcode("inc","%s",rname);
8582 rLen = SPEC_BLEN(etype) ;
8584 /* now generate for lengths greater than one byte */
8587 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8597 pic16_emitcode("mov","@%s,a",rname);
8599 pic16_emitcode("mov","@%s,%s",rname,l);
8604 pic16_emitcode("movx","@dptr,a");
8609 DEBUGpic16_emitcode(";lcall","__gptrput");
8612 pic16_emitcode ("inc","%s",rname);
8617 /* last last was not complete */
8619 /* save the byte & read byte */
8622 pic16_emitcode ("mov","b,a");
8623 pic16_emitcode("mov","a,@%s",rname);
8627 pic16_emitcode ("mov","b,a");
8628 pic16_emitcode("movx","a,@dptr");
8632 pic16_emitcode ("push","b");
8633 pic16_emitcode ("push","acc");
8634 pic16_emitcode ("lcall","__gptrget");
8635 pic16_emitcode ("pop","b");
8639 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8640 pic16_emitcode ("orl","a,b");
8643 if (p_type == GPOINTER)
8644 pic16_emitcode("pop","b");
8649 pic16_emitcode("mov","@%s,a",rname);
8653 pic16_emitcode("movx","@dptr,a");
8657 DEBUGpic16_emitcode(";lcall","__gptrput");
8661 /*-----------------------------------------------------------------*/
8662 /* genDataPointerSet - remat pointer to data space */
8663 /*-----------------------------------------------------------------*/
8664 static void genDataPointerSet(operand *right,
8668 int size, offset = 0 ;
8669 char *l, buffer[256];
8671 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8672 pic16_aopOp(right,ic,FALSE);
8674 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8675 size = AOP_SIZE(right);
8677 if ( AOP_TYPE(result) == AOP_PCODE) {
8678 fprintf(stderr,"genDataPointerSet %s, %d\n",
8679 AOP(result)->aopu.pcop->name,
8680 PCOI(AOP(result)->aopu.pcop)->offset);
8684 // tsd, was l+1 - the underline `_' prefix was being stripped
8687 sprintf(buffer,"(%s + %d)",l,offset);
8688 fprintf(stderr,"oops %s\n",buffer);
8690 sprintf(buffer,"%s",l);
8692 if (AOP_TYPE(right) == AOP_LIT) {
8693 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8694 lit = lit >> (8*offset);
8696 pic16_emitcode("movlw","%d",lit);
8697 pic16_emitcode("movwf","%s",buffer);
8699 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8700 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8701 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8704 pic16_emitcode("clrf","%s",buffer);
8705 //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8706 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8709 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8710 pic16_emitcode("movwf","%s",buffer);
8712 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8713 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8714 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8721 pic16_freeAsmop(right,NULL,ic,TRUE);
8722 pic16_freeAsmop(result,NULL,ic,TRUE);
8725 /*-----------------------------------------------------------------*/
8726 /* genNearPointerSet - pic16_emitcode for near pointer put */
8727 /*-----------------------------------------------------------------*/
8728 static void genNearPointerSet (operand *right,
8735 sym_link *ptype = operandType(result);
8738 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8739 retype= getSpec(operandType(right));
8741 pic16_aopOp(result,ic,FALSE);
8744 /* if the result is rematerializable &
8745 in data space & not a bit variable */
8746 //if (AOP_TYPE(result) == AOP_IMMD &&
8747 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8748 DCL_TYPE(ptype) == POINTER &&
8749 !IS_BITVAR(retype)) {
8750 genDataPointerSet (right,result,ic);
8751 pic16_freeAsmop(result,NULL,ic,TRUE);
8755 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8756 pic16_aopOp(right,ic,FALSE);
8757 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8759 /* if the value is already in a pointer register
8760 then don't need anything more */
8761 if (!AOP_INPREG(AOP(result))) {
8762 /* otherwise get a free pointer register */
8763 //aop = newAsmop(0);
8764 //preg = getFreePtr(ic,&aop,FALSE);
8765 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8766 //pic16_emitcode("mov","%s,%s",
8768 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8769 //rname = preg->name ;
8770 //pic16_emitcode("movwf","fsr0");
8771 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8772 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8773 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8774 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8778 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8781 /* if bitfield then unpack the bits */
8782 if (IS_BITVAR(retype)) {
8783 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8784 "The programmer is obviously confused");
8785 //genPackBits (retype,right,rname,POINTER);
8789 /* we have can just get the values */
8790 int size = AOP_SIZE(right);
8793 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8795 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8798 //pic16_emitcode("mov","@%s,a",rname);
8799 pic16_emitcode("movf","indf0,w ;1");
8802 if (AOP_TYPE(right) == AOP_LIT) {
8803 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8805 pic16_emitcode("movlw","%s",l);
8806 pic16_emitcode("movwf","indf0 ;2");
8808 pic16_emitcode("clrf","indf0");
8810 pic16_emitcode("movf","%s,w",l);
8811 pic16_emitcode("movwf","indf0 ;2");
8813 //pic16_emitcode("mov","@%s,%s",rname,l);
8816 pic16_emitcode("incf","fsr0,f ;3");
8817 //pic16_emitcode("inc","%s",rname);
8822 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8823 /* now some housekeeping stuff */
8825 /* we had to allocate for this iCode */
8826 pic16_freeAsmop(NULL,aop,ic,TRUE);
8828 /* we did not allocate which means left
8829 already in a pointer register, then
8830 if size > 0 && this could be used again
8831 we have to point it back to where it
8833 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8834 if (AOP_SIZE(right) > 1 &&
8835 !OP_SYMBOL(result)->remat &&
8836 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8838 int size = AOP_SIZE(right) - 1;
8840 pic16_emitcode("decf","fsr0,f");
8841 //pic16_emitcode("dec","%s",rname);
8845 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8848 pic16_freeAsmop(right,NULL,ic,TRUE);
8849 pic16_freeAsmop(result,NULL,ic,TRUE);
8852 /*-----------------------------------------------------------------*/
8853 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8854 /*-----------------------------------------------------------------*/
8855 static void genPagedPointerSet (operand *right,
8864 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8866 retype= getSpec(operandType(right));
8868 pic16_aopOp(result,ic,FALSE);
8870 /* if the value is already in a pointer register
8871 then don't need anything more */
8872 if (!AOP_INPREG(AOP(result))) {
8873 /* otherwise get a free pointer register */
8875 preg = getFreePtr(ic,&aop,FALSE);
8876 pic16_emitcode("mov","%s,%s",
8878 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8879 rname = preg->name ;
8881 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8883 pic16_freeAsmop(result,NULL,ic,TRUE);
8884 pic16_aopOp (right,ic,FALSE);
8886 /* if bitfield then unpack the bits */
8887 if (IS_BITVAR(retype))
8888 genPackBits (retype,right,rname,PPOINTER);
8890 /* we have can just get the values */
8891 int size = AOP_SIZE(right);
8895 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8898 pic16_emitcode("movx","@%s,a",rname);
8901 pic16_emitcode("inc","%s",rname);
8907 /* now some housekeeping stuff */
8909 /* we had to allocate for this iCode */
8910 pic16_freeAsmop(NULL,aop,ic,TRUE);
8912 /* we did not allocate which means left
8913 already in a pointer register, then
8914 if size > 0 && this could be used again
8915 we have to point it back to where it
8917 if (AOP_SIZE(right) > 1 &&
8918 !OP_SYMBOL(result)->remat &&
8919 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8921 int size = AOP_SIZE(right) - 1;
8923 pic16_emitcode("dec","%s",rname);
8928 pic16_freeAsmop(right,NULL,ic,TRUE);
8933 /*-----------------------------------------------------------------*/
8934 /* genFarPointerSet - set value from far space */
8935 /*-----------------------------------------------------------------*/
8936 static void genFarPointerSet (operand *right,
8937 operand *result, iCode *ic)
8940 sym_link *retype = getSpec(operandType(right));
8942 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8943 pic16_aopOp(result,ic,FALSE);
8945 /* if the operand is already in dptr
8946 then we do nothing else we move the value to dptr */
8947 if (AOP_TYPE(result) != AOP_STR) {
8948 /* if this is remateriazable */
8949 if (AOP_TYPE(result) == AOP_IMMD)
8950 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8951 else { /* we need to get it byte by byte */
8952 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8953 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8954 if (options.model == MODEL_FLAT24)
8956 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8960 /* so dptr know contains the address */
8961 pic16_freeAsmop(result,NULL,ic,TRUE);
8962 pic16_aopOp(right,ic,FALSE);
8964 /* if bit then unpack */
8965 if (IS_BITVAR(retype))
8966 genPackBits(retype,right,"dptr",FPOINTER);
8968 size = AOP_SIZE(right);
8972 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8974 pic16_emitcode("movx","@dptr,a");
8976 pic16_emitcode("inc","dptr");
8980 pic16_freeAsmop(right,NULL,ic,TRUE);
8983 /*-----------------------------------------------------------------*/
8984 /* genGenPointerSet - set value from generic pointer space */
8985 /*-----------------------------------------------------------------*/
8986 static void genGenPointerSet (operand *right,
8987 operand *result, iCode *ic)
8990 sym_link *retype = getSpec(operandType(right));
8992 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8994 pic16_aopOp(result,ic,FALSE);
8995 pic16_aopOp(right,ic,FALSE);
8996 size = AOP_SIZE(right);
8998 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9000 /* if the operand is already in dptr
9001 then we do nothing else we move the value to dptr */
9002 if (AOP_TYPE(result) != AOP_STR) {
9003 /* if this is remateriazable */
9004 if (AOP_TYPE(result) == AOP_IMMD) {
9005 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9006 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
9008 else { /* we need to get it byte by byte */
9009 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
9010 size = AOP_SIZE(right);
9013 /* hack hack! see if this the FSR. If so don't load W */
9014 if(AOP_TYPE(right) != AOP_ACC) {
9017 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9018 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9020 if(AOP_SIZE(result) > 1) {
9021 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9022 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9023 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9028 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9030 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9031 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9035 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9036 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9039 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9046 if(aopIdx(AOP(result),0) != 4) {
9048 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9052 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9057 /* so dptr know contains the address */
9060 /* if bit then unpack */
9061 if (IS_BITVAR(retype))
9062 genPackBits(retype,right,"dptr",GPOINTER);
9064 size = AOP_SIZE(right);
9067 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9071 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9072 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9074 if (AOP_TYPE(right) == AOP_LIT)
9075 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9077 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9079 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9086 pic16_freeAsmop(right,NULL,ic,TRUE);
9087 pic16_freeAsmop(result,NULL,ic,TRUE);
9090 /*-----------------------------------------------------------------*/
9091 /* genPointerSet - stores the value into a pointer location */
9092 /*-----------------------------------------------------------------*/
9093 static void genPointerSet (iCode *ic)
9095 operand *right, *result ;
9096 sym_link *type, *etype;
9099 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9101 right = IC_RIGHT(ic);
9102 result = IC_RESULT(ic) ;
9104 /* depending on the type of pointer we need to
9105 move it to the correct pointer register */
9106 type = operandType(result);
9107 etype = getSpec(type);
9108 /* if left is of type of pointer then it is simple */
9109 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9110 p_type = DCL_TYPE(type);
9113 /* we have to go by the storage class */
9114 p_type = PTR_TYPE(SPEC_OCLS(etype));
9116 /* if (SPEC_OCLS(etype)->codesp ) { */
9117 /* p_type = CPOINTER ; */
9120 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9121 /* p_type = FPOINTER ; */
9123 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9124 /* p_type = PPOINTER ; */
9126 /* if (SPEC_OCLS(etype) == idata ) */
9127 /* p_type = IPOINTER ; */
9129 /* p_type = POINTER ; */
9132 /* now that we have the pointer type we assign
9133 the pointer values */
9138 genNearPointerSet (right,result,ic);
9142 genPagedPointerSet (right,result,ic);
9146 genFarPointerSet (right,result,ic);
9150 genGenPointerSet (right,result,ic);
9154 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9155 "genPointerSet: illegal pointer type");
9159 /*-----------------------------------------------------------------*/
9160 /* genIfx - generate code for Ifx statement */
9161 /*-----------------------------------------------------------------*/
9162 static void genIfx (iCode *ic, iCode *popIc)
9164 operand *cond = IC_COND(ic);
9167 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9169 pic16_aopOp(cond,ic,FALSE);
9171 /* get the value into acc */
9172 if (AOP_TYPE(cond) != AOP_CRY)
9173 pic16_toBoolean(cond);
9176 /* the result is now in the accumulator */
9177 pic16_freeAsmop(cond,NULL,ic,TRUE);
9179 /* if there was something to be popped then do it */
9183 /* if the condition is a bit variable */
9184 if (isbit && IS_ITEMP(cond) &&
9186 genIfxJump(ic,SPIL_LOC(cond)->rname);
9187 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9190 if (isbit && !IS_ITEMP(cond))
9191 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9199 /*-----------------------------------------------------------------*/
9200 /* genAddrOf - generates code for address of */
9201 /*-----------------------------------------------------------------*/
9202 static void genAddrOf (iCode *ic)
9204 operand *right, *result, *left;
9207 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9210 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9212 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9213 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9214 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9216 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9218 size = AOP_SIZE(IC_RESULT(ic));
9223 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9224 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9229 pic16_freeAsmop(left,NULL,ic,FALSE);
9230 pic16_freeAsmop(result,NULL,ic,TRUE);
9235 /*-----------------------------------------------------------------*/
9236 /* genFarFarAssign - assignment when both are in far space */
9237 /*-----------------------------------------------------------------*/
9238 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9240 int size = AOP_SIZE(right);
9243 /* first push the right side on to the stack */
9245 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9247 pic16_emitcode ("push","acc");
9250 pic16_freeAsmop(right,NULL,ic,FALSE);
9251 /* now assign DPTR to result */
9252 pic16_aopOp(result,ic,FALSE);
9253 size = AOP_SIZE(result);
9255 pic16_emitcode ("pop","acc");
9256 pic16_aopPut(AOP(result),"a",--offset);
9258 pic16_freeAsmop(result,NULL,ic,FALSE);
9263 /*-----------------------------------------------------------------*/
9264 /* genAssign - generate code for assignment */
9265 /*-----------------------------------------------------------------*/
9266 static void genAssign (iCode *ic)
9268 operand *result, *right;
9269 int size, offset,know_W;
9270 unsigned long lit = 0L;
9272 result = IC_RESULT(ic);
9273 right = IC_RIGHT(ic) ;
9275 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9277 /* if they are the same */
9278 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9281 pic16_aopOp(right,ic,FALSE);
9282 pic16_aopOp(result,ic,TRUE);
9284 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9286 /* if they are the same registers */
9287 if (pic16_sameRegs(AOP(right),AOP(result)))
9290 /* if the result is a bit */
9291 if (AOP_TYPE(result) == AOP_CRY) {
9292 /* if the right size is a literal then
9293 we know what the value is */
9294 if (AOP_TYPE(right) == AOP_LIT) {
9296 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9297 pic16_popGet(AOP(result),0));
9299 if (((int) operandLitValue(right)))
9300 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9301 AOP(result)->aopu.aop_dir,
9302 AOP(result)->aopu.aop_dir);
9304 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9305 AOP(result)->aopu.aop_dir,
9306 AOP(result)->aopu.aop_dir);
9310 /* the right is also a bit variable */
9311 if (AOP_TYPE(right) == AOP_CRY) {
9312 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9313 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9314 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9316 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9317 AOP(result)->aopu.aop_dir,
9318 AOP(result)->aopu.aop_dir);
9319 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9320 AOP(right)->aopu.aop_dir,
9321 AOP(right)->aopu.aop_dir);
9322 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9323 AOP(result)->aopu.aop_dir,
9324 AOP(result)->aopu.aop_dir);
9329 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9330 pic16_toBoolean(right);
9332 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9333 //pic16_aopPut(AOP(result),"a",0);
9337 /* bit variables done */
9339 size = AOP_SIZE(result);
9341 if(AOP_TYPE(right) == AOP_LIT)
9342 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9344 /* VR - What is this?! */
9345 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9346 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9347 if(aopIdx(AOP(result),0) == 4) {
9348 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9349 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9350 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9353 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9358 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9359 if(AOP_TYPE(right) == AOP_LIT) {
9361 if(know_W != (lit&0xff))
9362 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9364 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9366 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9370 } else if (AOP_TYPE(right) == AOP_CRY) {
9371 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9373 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9374 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9377 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9379 if(!options_no_movff) {
9381 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9382 normally should work, but mind that thw W register live range
9383 is not checked, so if the code generator assumes that the W
9384 is already loaded after such a pair, wrong code will be generated.
9386 Checking the live range is the next step.
9387 This is experimental code yet and has not been fully tested yet.
9388 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9389 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9392 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9394 /* This is the old code, which is assumed(?!) that works fine(!?) */
9396 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9397 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9406 pic16_freeAsmop (right,NULL,ic,FALSE);
9407 pic16_freeAsmop (result,NULL,ic,TRUE);
9410 /*-----------------------------------------------------------------*/
9411 /* genJumpTab - generates code for jump table */
9412 /*-----------------------------------------------------------------*/
9413 static void genJumpTab (iCode *ic)
9418 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9420 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9421 /* get the condition into accumulator */
9422 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9424 /* multiply by three */
9425 pic16_emitcode("add","a,acc");
9426 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9428 jtab = newiTempLabel(NULL);
9429 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9430 pic16_emitcode("jmp","@a+dptr");
9431 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9433 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9434 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9436 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9437 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9438 pic16_emitpLabel(jtab->key);
9440 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9442 /* now generate the jump labels */
9443 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9444 jtab = setNextItem(IC_JTLABELS(ic))) {
9445 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9446 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9452 /*-----------------------------------------------------------------*/
9453 /* genMixedOperation - gen code for operators between mixed types */
9454 /*-----------------------------------------------------------------*/
9456 TSD - Written for the PIC port - but this unfortunately is buggy.
9457 This routine is good in that it is able to efficiently promote
9458 types to different (larger) sizes. Unfortunately, the temporary
9459 variables that are optimized out by this routine are sometimes
9460 used in other places. So until I know how to really parse the
9461 iCode tree, I'm going to not be using this routine :(.
9463 static int genMixedOperation (iCode *ic)
9466 operand *result = IC_RESULT(ic);
9467 sym_link *ctype = operandType(IC_LEFT(ic));
9468 operand *right = IC_RIGHT(ic);
9474 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9476 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9482 nextright = IC_RIGHT(nextic);
9483 nextleft = IC_LEFT(nextic);
9484 nextresult = IC_RESULT(nextic);
9486 pic16_aopOp(right,ic,FALSE);
9487 pic16_aopOp(result,ic,FALSE);
9488 pic16_aopOp(nextright, nextic, FALSE);
9489 pic16_aopOp(nextleft, nextic, FALSE);
9490 pic16_aopOp(nextresult, nextic, FALSE);
9492 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9498 pic16_emitcode(";remove right +","");
9500 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9506 pic16_emitcode(";remove left +","");
9510 big = AOP_SIZE(nextleft);
9511 small = AOP_SIZE(nextright);
9513 switch(nextic->op) {
9516 pic16_emitcode(";optimize a +","");
9517 /* if unsigned or not an integral type */
9518 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9519 pic16_emitcode(";add a bit to something","");
9522 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9524 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9525 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9526 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9528 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9536 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9537 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9538 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9541 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9543 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9544 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9545 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9546 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9547 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9550 pic16_emitcode("rlf","known_zero,w");
9557 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9558 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9559 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9561 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9571 pic16_freeAsmop(right,NULL,ic,TRUE);
9572 pic16_freeAsmop(result,NULL,ic,TRUE);
9573 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9574 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9576 nextic->generated = 1;
9583 /*-----------------------------------------------------------------*/
9584 /* genCast - gen code for casting */
9585 /*-----------------------------------------------------------------*/
9586 static void genCast (iCode *ic)
9588 operand *result = IC_RESULT(ic);
9589 sym_link *ctype = operandType(IC_LEFT(ic));
9590 sym_link *rtype = operandType(IC_RIGHT(ic));
9591 operand *right = IC_RIGHT(ic);
9594 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9595 /* if they are equivalent then do nothing */
9596 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9599 pic16_aopOp(right,ic,FALSE) ;
9600 pic16_aopOp(result,ic,FALSE);
9602 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9604 /* if the result is a bit */
9605 if (AOP_TYPE(result) == AOP_CRY) {
9606 /* if the right size is a literal then
9607 we know what the value is */
9608 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9609 if (AOP_TYPE(right) == AOP_LIT) {
9611 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9612 pic16_popGet(AOP(result),0));
9614 if (((int) operandLitValue(right)))
9615 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9616 AOP(result)->aopu.aop_dir,
9617 AOP(result)->aopu.aop_dir);
9619 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9620 AOP(result)->aopu.aop_dir,
9621 AOP(result)->aopu.aop_dir);
9626 /* the right is also a bit variable */
9627 if (AOP_TYPE(right) == AOP_CRY) {
9630 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9632 pic16_emitcode("clrc","");
9633 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9634 AOP(right)->aopu.aop_dir,
9635 AOP(right)->aopu.aop_dir);
9636 pic16_aopPut(AOP(result),"c",0);
9641 if (AOP_TYPE(right) == AOP_REG) {
9642 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9643 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9644 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9646 pic16_toBoolean(right);
9647 pic16_aopPut(AOP(result),"a",0);
9651 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9653 size = AOP_SIZE(result);
9655 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9657 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9658 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9659 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9662 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9667 /* if they are the same size : or less */
9668 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9670 /* if they are in the same place */
9671 if (pic16_sameRegs(AOP(right),AOP(result)))
9674 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9675 if (IS_PTR_CONST(rtype))
9676 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9677 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9678 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9680 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9681 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9682 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9683 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9684 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9685 if(AOP_SIZE(result) <2)
9686 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9690 /* if they in different places then copy */
9691 size = AOP_SIZE(result);
9694 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9695 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9697 //pic16_aopPut(AOP(result),
9698 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9708 /* if the result is of type pointer */
9709 if (IS_PTR(ctype)) {
9712 sym_link *type = operandType(right);
9713 sym_link *etype = getSpec(type);
9714 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9716 /* pointer to generic pointer */
9717 if (IS_GENPTR(ctype)) {
9721 p_type = DCL_TYPE(type);
9723 /* we have to go by the storage class */
9724 p_type = PTR_TYPE(SPEC_OCLS(etype));
9726 /* if (SPEC_OCLS(etype)->codesp ) */
9727 /* p_type = CPOINTER ; */
9729 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9730 /* p_type = FPOINTER ; */
9732 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9733 /* p_type = PPOINTER; */
9735 /* if (SPEC_OCLS(etype) == idata ) */
9736 /* p_type = IPOINTER ; */
9738 /* p_type = POINTER ; */
9741 /* the first two bytes are known */
9742 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9743 size = GPTRSIZE - 1;
9746 if(offset < AOP_SIZE(right)) {
9747 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9748 if ((AOP_TYPE(right) == AOP_PCODE) &&
9749 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9750 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9751 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9753 pic16_aopPut(AOP(result),
9754 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9758 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9761 /* the last byte depending on type */
9765 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9768 pic16_emitcode(";BUG!? ","%d",__LINE__);
9772 pic16_emitcode(";BUG!? ","%d",__LINE__);
9776 pic16_emitcode(";BUG!? ","%d",__LINE__);
9781 /* this should never happen */
9782 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9783 "got unknown pointer type");
9786 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9790 /* just copy the pointers */
9791 size = AOP_SIZE(result);
9794 pic16_aopPut(AOP(result),
9795 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9804 /* so we now know that the size of destination is greater
9805 than the size of the source.
9806 Now, if the next iCode is an operator then we might be
9807 able to optimize the operation without performing a cast.
9809 if(genMixedOperation(ic))
9812 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9814 /* we move to result for the size of source */
9815 size = AOP_SIZE(right);
9818 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9819 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9823 /* now depending on the sign of the destination */
9824 size = AOP_SIZE(result) - AOP_SIZE(right);
9825 /* if unsigned or not an integral type */
9826 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9828 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9830 /* we need to extend the sign :{ */
9833 /* Save one instruction of casting char to int */
9834 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9835 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9836 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
9838 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9841 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9843 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9845 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9848 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
9853 pic16_freeAsmop(right,NULL,ic,TRUE);
9854 pic16_freeAsmop(result,NULL,ic,TRUE);
9858 /*-----------------------------------------------------------------*/
9859 /* genDjnz - generate decrement & jump if not zero instrucion */
9860 /*-----------------------------------------------------------------*/
9861 static int genDjnz (iCode *ic, iCode *ifx)
9864 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9869 /* if the if condition has a false label
9870 then we cannot save */
9874 /* if the minus is not of the form
9876 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9877 !IS_OP_LITERAL(IC_RIGHT(ic)))
9880 if (operandLitValue(IC_RIGHT(ic)) != 1)
9883 /* if the size of this greater than one then no
9885 if (getSize(operandType(IC_RESULT(ic))) > 1)
9888 /* otherwise we can save BIG */
9889 lbl = newiTempLabel(NULL);
9890 lbl1= newiTempLabel(NULL);
9892 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9894 if (IS_AOP_PREG(IC_RESULT(ic))) {
9895 pic16_emitcode("dec","%s",
9896 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9897 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9898 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9902 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9903 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9905 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9906 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9909 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9910 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9911 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9912 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9915 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9920 /*-----------------------------------------------------------------*/
9921 /* genReceive - generate code for a receive iCode */
9922 /*-----------------------------------------------------------------*/
9923 static void genReceive (iCode *ic)
9925 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9927 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9928 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9929 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9931 int size = getSize(operandType(IC_RESULT(ic)));
9932 int offset = pic16_fReturnSizePic - size;
9934 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9935 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9938 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9939 size = AOP_SIZE(IC_RESULT(ic));
9942 pic16_emitcode ("pop","acc");
9943 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9948 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9950 assignResultValue(IC_RESULT(ic));
9953 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9956 /*-----------------------------------------------------------------*/
9957 /* genpic16Code - generate code for pic16 based controllers */
9958 /*-----------------------------------------------------------------*/
9960 * At this point, ralloc.c has gone through the iCode and attempted
9961 * to optimize in a way suitable for a PIC. Now we've got to generate
9962 * PIC instructions that correspond to the iCode.
9964 * Once the instructions are generated, we'll pass through both the
9965 * peep hole optimizer and the pCode optimizer.
9966 *-----------------------------------------------------------------*/
9968 void genpic16Code (iCode *lic)
9973 lineHead = lineCurr = NULL;
9975 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9976 pic16_addpBlock(pb);
9979 /* if debug information required */
9980 if (options.debug && currFunc) {
9982 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9984 if (IS_STATIC(currFunc->etype)) {
9985 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9986 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9988 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9989 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
9996 for (ic = lic ; ic ; ic = ic->next ) {
9998 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
9999 // DEBUGpic16_emitcode("; VR", "");
10000 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10001 if ( cln != ic->lineno ) {
10002 if ( options.debug ) {
10004 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10005 FileBaseName(ic->filename),ic->lineno,
10006 ic->level,ic->block);
10010 pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
10011 pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
10012 printCLine(ic->filename, ic->lineno));
10014 pic16_addpCode2pBlock(pb,
10015 pic16_newpCodeCSource(ic->lineno,
10017 printCLine(ic->filename, ic->lineno)));
10021 /* if the result is marked as
10022 spilt and rematerializable or code for
10023 this has already been generated then
10025 if (resultRemat(ic) || ic->generated )
10028 /* depending on the operation */
10047 /* IPOP happens only when trying to restore a
10048 spilt live range, if there is an ifx statement
10049 following this pop then the if statement might
10050 be using some of the registers being popped which
10051 would destroy the contents of the register so
10052 we need to check for this condition and handle it */
10054 ic->next->op == IFX &&
10055 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10056 genIfx (ic->next,ic);
10074 genEndFunction (ic);
10090 pic16_genPlus (ic) ;
10094 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10095 pic16_genMinus (ic);
10111 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10115 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10122 /* note these two are xlated by algebraic equivalence
10123 during parsing SDCC.y */
10124 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10125 "got '>=' or '<=' shouldn't have come here");
10129 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10141 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10145 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10149 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10173 genRightShift (ic);
10176 case GET_VALUE_AT_ADDRESS:
10181 if (POINTER_SET(ic))
10208 addSet(&_G.sendSet,ic);
10217 /* now we are ready to call the
10218 peep hole optimizer */
10219 if (!options.nopeep) {
10220 peepHole (&lineHead);
10222 /* now do the actual printing */
10223 printLine (lineHead,codeOutFile);
10226 DFPRINTF((stderr,"printing pBlock\n\n"));
10227 pic16_printpBlock(stdout,pb);