1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic16
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;
65 /* max_key keeps track of the largest label number used in
66 a function. This is then used to adjust the label offset
67 for the next function.
70 static int GpsuedoStkPtr=0;
72 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index);
73 unsigned int pic16aopLiteral (value *val, int offset);
74 const char *pic16_AopType(short type);
75 static iCode *ifxForOp ( operand *op, iCode *ic );
77 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
79 /* this is the down and dirty file with all kinds of
80 kludgy & hacky stuff. This is what it is all about
81 CODE GENERATION for a specific MCU . some of the
82 routines may be reusable, will have to see */
84 static char *zero = "#0x00";
85 static char *one = "#0x01";
86 static char *spname = "sp";
88 char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" };
89 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
90 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
91 static char **fReturn = fReturnpic16;
93 static char *accUse[] = {"a","b"};
95 //static short rbank = -1;
107 /* Resolved ifx structure. This structure stores information
108 about an iCode ifx that makes it easier to generate code.
110 typedef struct resolvedIfx {
111 symbol *lbl; /* pointer to a label */
112 int condition; /* true or false ifx */
113 int generated; /* set true when the code associated with the ifx
117 extern int pic16_ptrRegReq ;
118 extern int pic16_nRegs;
119 extern FILE *codeOutFile;
120 static void saverbank (int, iCode *,bool);
122 static lineNode *lineHead = NULL;
123 static lineNode *lineCurr = NULL;
125 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
126 0xE0, 0xC0, 0x80, 0x00};
127 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
128 0x07, 0x03, 0x01, 0x00};
132 /*-----------------------------------------------------------------*/
133 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
134 /* exponent of 2 is returned, otherwise -1 is */
136 /* note that this is similar to the function `powof2' in SDCCsymt */
140 /*-----------------------------------------------------------------*/
141 static int my_powof2 (unsigned long num)
144 if( (num & (num-1)) == 0) {
157 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result)
160 DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
162 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
163 ((result) ? pic16_aopGet(AOP(result),0,TRUE,FALSE) : "-"),
164 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
165 ((left) ? pic16_aopGet(AOP(left),0,TRUE,FALSE) : "-"),
166 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
167 ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"),
168 ((result) ? AOP_SIZE(result) : 0));
172 void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
175 DEBUGpic16_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
177 ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"),
178 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
179 ((left) ? pic16_AopType(AOP_TYPE(left)) : "-"),
180 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
181 ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"),
182 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
186 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
189 char lb[INITIAL_INLINEASM];
192 if(!pic16_debug_verbose)
199 sprintf(lb,"%s\t",inst);
201 sprintf(lb,"%s",inst);
202 vsprintf(lb+(strlen(lb)),fmt,ap);
206 while (isspace(*lbp)) lbp++;
209 lineCurr = (lineCurr ?
210 connectLine(lineCurr,newLineNode(lb)) :
211 (lineHead = newLineNode(lb)));
212 lineCurr->isInline = _G.inLine;
213 lineCurr->isDebug = _G.debugLine;
215 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
218 // fprintf(stderr, "%s\n", lb);
222 void pic16_emitpLabel(int key)
224 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
227 void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
231 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop));
233 DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
235 // fprintf(stderr, "%s\n", pcop->name);
238 void pic16_emitpcodeNULLop(PIC_OPCODE poc)
241 pic16_addpCode2pBlock(pb,pic16_newpCode(poc,NULL));
245 /*-----------------------------------------------------------------*/
246 /* pic16_emitcode - writes the code into a file : for now it is simple */
247 /*-----------------------------------------------------------------*/
248 void pic16_emitcode (char *inst,char *fmt, ...)
251 char lb[INITIAL_INLINEASM];
258 sprintf(lb,"%s\t",inst);
260 sprintf(lb,"%s",inst);
261 vsprintf(lb+(strlen(lb)),fmt,ap);
265 while (isspace(*lbp)) lbp++;
268 lineCurr = (lineCurr ?
269 connectLine(lineCurr,newLineNode(lb)) :
270 (lineHead = newLineNode(lb)));
271 lineCurr->isInline = _G.inLine;
272 lineCurr->isDebug = _G.debugLine;
274 // VR fprintf(stderr, "lb = <%s>\n", lbp);
276 if(pic16_debug_verbose)
277 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
283 /*-----------------------------------------------------------------*/
284 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
285 /*-----------------------------------------------------------------*/
286 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
288 bool r0iu = FALSE , r1iu = FALSE;
289 bool r0ou = FALSE , r1ou = FALSE;
291 //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op);
293 /* the logic: if r0 & r1 used in the instruction
294 then we are in trouble otherwise */
296 /* first check if r0 & r1 are used by this
297 instruction, in which case we are in trouble */
298 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
299 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
304 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
305 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
307 /* if no usage of r0 then return it */
308 if (!r0iu && !r0ou) {
309 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
310 (*aopp)->type = AOP_R0;
312 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
315 /* if no usage of r1 then return it */
316 if (!r1iu && !r1ou) {
317 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
318 (*aopp)->type = AOP_R1;
320 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R1_IDX);
323 /* now we know they both have usage */
324 /* if r0 not used in this instruction */
326 /* push it if not already pushed */
328 //pic16_emitcode ("push","%s",
329 // pic16_regWithIdx(R0_IDX)->dname);
333 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
334 (*aopp)->type = AOP_R0;
336 return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX);
339 /* if r1 not used then */
342 /* push it if not already pushed */
344 //pic16_emitcode ("push","%s",
345 // pic16_regWithIdx(R1_IDX)->dname);
349 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
350 (*aopp)->type = AOP_R1;
351 return pic16_regWithIdx(R1_IDX);
355 /* I said end of world but not quite end of world yet */
356 /* if this is a result then we can push it on the stack*/
358 (*aopp)->type = AOP_STK;
362 /* other wise this is true end of the world */
363 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
364 "getFreePtr should never reach here");
368 /*-----------------------------------------------------------------*/
369 /* newAsmop - creates a new asmOp */
370 /*-----------------------------------------------------------------*/
371 static asmop *newAsmop (short type)
375 aop = Safe_calloc(1,sizeof(asmop));
380 static void genSetDPTR(int n)
384 pic16_emitcode(";", "Select standard DPTR");
385 pic16_emitcode("mov", "dps, #0x00");
389 pic16_emitcode(";", "Select alternate DPTR");
390 pic16_emitcode("mov", "dps, #0x01");
394 /*-----------------------------------------------------------------*/
395 /* resolveIfx - converts an iCode ifx into a form more useful for */
396 /* generating code */
397 /*-----------------------------------------------------------------*/
398 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
403 // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
405 resIfx->condition = 1; /* assume that the ifx is true */
406 resIfx->generated = 0; /* indicate that the ifx has not been used */
409 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
411 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
412 __FUNCTION__,__LINE__,resIfx->lbl->key);
416 resIfx->lbl = IC_TRUE(ifx);
418 resIfx->lbl = IC_FALSE(ifx);
419 resIfx->condition = 0;
423 DEBUGpic16_emitcode("; ***","ifx true is non-null");
425 DEBUGpic16_emitcode("; ***","ifx false is non-null");
429 // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
432 /*-----------------------------------------------------------------*/
433 /* pointerCode - returns the code for a pointer type */
434 /*-----------------------------------------------------------------*/
435 static int pointerCode (sym_link *etype)
438 return PTR_TYPE(SPEC_OCLS(etype));
442 /*-----------------------------------------------------------------*/
443 /* aopForSym - for a true symbol */
444 /*-----------------------------------------------------------------*/
445 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
448 memmap *space= SPEC_OCLS(sym->etype);
450 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
451 /* if already has one */
453 DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__);
457 /* assign depending on the storage class */
458 /* if it is on the stack or indirectly addressable */
459 /* space we need to assign either r0 or r1 to it */
460 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
461 sym->aop = aop = newAsmop(0);
462 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
463 aop->size = getSize(sym->type);
465 /* now assign the address of the variable to
466 the pointer register */
467 if (aop->type != AOP_STK) {
471 pic16_emitcode("push","acc");
473 pic16_emitcode("mov","a,_bp");
474 pic16_emitcode("add","a,#0x%02x",
476 ((char)(sym->stack - _G.nRegsSaved )) :
477 ((char)sym->stack)) & 0xff);
478 pic16_emitcode("mov","%s,a",
479 aop->aopu.aop_ptr->name);
482 pic16_emitcode("pop","acc");
484 pic16_emitcode("mov","%s,#%s",
485 aop->aopu.aop_ptr->name,
487 aop->paged = space->paged;
489 aop->aopu.aop_stk = sym->stack;
493 if (sym->onStack && options.stack10bit)
495 /* It's on the 10 bit stack, which is located in
499 //DEBUGpic16_emitcode(";","%d",__LINE__);
502 pic16_emitcode("push","acc");
504 pic16_emitcode("mov","a,_bp");
505 pic16_emitcode("add","a,#0x%02x",
507 ((char)(sym->stack - _G.nRegsSaved )) :
508 ((char)sym->stack)) & 0xff);
511 pic16_emitcode ("mov","dpx1,#0x40");
512 pic16_emitcode ("mov","dph1,#0x00");
513 pic16_emitcode ("mov","dpl1, a");
517 pic16_emitcode("pop","acc");
519 sym->aop = aop = newAsmop(AOP_DPTR2);
520 aop->size = getSize(sym->type);
524 //DEBUGpic16_emitcode(";","%d",__LINE__);
525 /* if in bit space */
526 if (IN_BITSPACE(space)) {
527 sym->aop = aop = newAsmop (AOP_CRY);
528 aop->aopu.aop_dir = sym->rname ;
529 aop->size = getSize(sym->type);
530 //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
533 /* if it is in direct space */
534 if (IN_DIRSPACE(space)) {
535 sym->aop = aop = newAsmop (AOP_DIR);
536 aop->aopu.aop_dir = sym->rname ;
537 aop->size = getSize(sym->type);
538 DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
542 /* special case for a function */
543 if (IS_FUNC(sym->type)) {
544 sym->aop = aop = newAsmop(AOP_IMMD);
545 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
546 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
547 strcpy(aop->aopu.aop_immd,sym->rname);
548 aop->size = FPTRSIZE;
549 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
554 /* only remaining is far space */
555 /* in which case DPTR gets the address */
556 sym->aop = aop = newAsmop(AOP_PCODE);
558 aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0);
559 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
560 PCOI(aop->aopu.pcop)->index = 0;
562 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
563 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
565 pic16_allocDirReg (IC_LEFT(ic));
567 aop->size = FPTRSIZE;
569 DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
570 sym->aop = aop = newAsmop(AOP_DPTR);
571 pic16_emitcode ("mov","dptr,#%s", sym->rname);
572 aop->size = getSize(sym->type);
574 DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size);
577 /* if it is in code space */
578 if (IN_CODESPACE(space))
584 /*-----------------------------------------------------------------*/
585 /* aopForRemat - rematerialzes an object */
586 /*-----------------------------------------------------------------*/
587 static asmop *aopForRemat (operand *op) // x symbol *sym)
589 symbol *sym = OP_SYMBOL(op);
591 asmop *aop = newAsmop(AOP_PCODE);
595 ic = sym->rematiCode;
597 DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__);
598 if(IS_OP_POINTER(op)) {
599 DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
603 val += (int) operandLitValue(IC_RIGHT(ic));
604 } else if (ic->op == '-') {
605 val -= (int) operandLitValue(IC_RIGHT(ic));
609 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
612 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
613 aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
615 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
617 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
619 PCOI(aop->aopu.pcop)->index = val;
621 DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d",
622 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
624 val, IS_PTR_CONST(operandType(op)));
626 val, IS_CODEPTR(operandType(op)));
629 // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic))));
631 pic16_allocDirReg (IC_LEFT(ic));
636 static int aopIdx (asmop *aop, int offset)
641 if(aop->type != AOP_REG)
644 return aop->aopu.aop_reg[offset]->rIdx;
647 /*-----------------------------------------------------------------*/
648 /* regsInCommon - two operands have some registers in common */
649 /*-----------------------------------------------------------------*/
650 static bool regsInCommon (operand *op1, operand *op2)
655 /* if they have registers in common */
656 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
659 sym1 = OP_SYMBOL(op1);
660 sym2 = OP_SYMBOL(op2);
662 if (sym1->nRegs == 0 || sym2->nRegs == 0)
665 for (i = 0 ; i < sym1->nRegs ; i++) {
670 for (j = 0 ; j < sym2->nRegs ;j++ ) {
674 if (sym2->regs[j] == sym1->regs[i])
682 /*-----------------------------------------------------------------*/
683 /* operandsEqu - equivalent */
684 /*-----------------------------------------------------------------*/
685 static bool operandsEqu ( operand *op1, operand *op2)
689 /* if they not symbols */
690 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
693 sym1 = OP_SYMBOL(op1);
694 sym2 = OP_SYMBOL(op2);
696 /* if both are itemps & one is spilt
697 and the other is not then false */
698 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
699 sym1->isspilt != sym2->isspilt )
702 /* if they are the same */
706 if (strcmp(sym1->rname,sym2->rname) == 0)
710 /* if left is a tmp & right is not */
714 (sym1->usl.spillLoc == sym2))
721 (sym2->usl.spillLoc == sym1))
727 /*-----------------------------------------------------------------*/
728 /* pic16_sameRegs - two asmops have the same registers */
729 /*-----------------------------------------------------------------*/
730 bool pic16_sameRegs (asmop *aop1, asmop *aop2 )
737 if (aop1->type != AOP_REG ||
738 aop2->type != AOP_REG )
741 if (aop1->size != aop2->size )
744 for (i = 0 ; i < aop1->size ; i++ )
745 if (aop1->aopu.aop_reg[i] !=
746 aop2->aopu.aop_reg[i] )
752 /*-----------------------------------------------------------------*/
753 /* pic16_aopOp - allocates an asmop for an operand : */
754 /*-----------------------------------------------------------------*/
755 void pic16_aopOp (operand *op, iCode *ic, bool result)
764 DEBUGpic16_emitcode(";","%d",__LINE__);
765 /* if this a literal */
766 if (IS_OP_LITERAL(op)) {
767 op->aop = aop = newAsmop(AOP_LIT);
768 aop->aopu.aop_lit = op->operand.valOperand;
769 aop->size = getSize(operandType(op));
774 sym_link *type = operandType(op);
776 if(IS_PTR_CONST(type))
780 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
783 /* if already has a asmop then continue */
787 /* if the underlying symbol has a aop */
788 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
789 DEBUGpic16_emitcode(";","%d has symbol",__LINE__);
790 op->aop = OP_SYMBOL(op)->aop;
794 /* if this is a true symbol */
795 if (IS_TRUE_SYMOP(op)) {
796 DEBUGpic16_emitcode(";","%d - true symop",__LINE__);
797 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
801 /* this is a temporary : this has
807 e) can be a return use only */
811 DEBUGpic16_emitcode("; ***", "%d: symbol name = %s", __LINE__, sym->name);
812 /* if the type is a conditional */
813 if (sym->regType == REG_CND) {
814 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
819 /* if it is spilt then two situations
821 b) has a spill location */
822 if (sym->isspilt || sym->nRegs == 0) {
824 DEBUGpic16_emitcode(";","%d",__LINE__);
825 /* rematerialize it NOW */
828 sym->aop = op->aop = aop =
830 aop->size = getSize(sym->type);
831 //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
837 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
838 aop->size = getSize(sym->type);
839 for ( i = 0 ; i < 2 ; i++ )
840 aop->aopu.aop_str[i] = accUse[i];
841 DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size);
847 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
848 aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
849 //pic16_allocDirReg (IC_LEFT(ic));
850 aop->size = getSize(sym->type);
855 aop = op->aop = sym->aop = newAsmop(AOP_STR);
856 aop->size = getSize(sym->type);
857 for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
858 aop->aopu.aop_str[i] = fReturn[i];
860 DEBUGpic16_emitcode(";","%d",__LINE__);
864 /* else spill location */
865 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
866 /* force a new aop if sizes differ */
867 sym->usl.spillLoc->aop = NULL;
869 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d",
870 __FUNCTION__,__LINE__,
871 sym->usl.spillLoc->rname,
872 sym->rname, sym->usl.spillLoc->offset);
874 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
875 //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
876 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
878 sym->usl.spillLoc->offset);
879 aop->size = getSize(sym->type);
885 sym_link *type = operandType(op);
887 if(IS_PTR_CONST(type))
891 DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__);
894 /* must be in a register */
895 DEBUGpic16_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
896 sym->aop = op->aop = aop = newAsmop(AOP_REG);
897 aop->size = sym->nRegs;
898 for ( i = 0 ; i < sym->nRegs ;i++)
899 aop->aopu.aop_reg[i] = sym->regs[i];
902 /*-----------------------------------------------------------------*/
903 /* pic16_freeAsmop - free up the asmop given to an operand */
904 /*----------------------------------------------------------------*/
905 void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
922 /* depending on the asmop type only three cases need work AOP_RO
923 , AOP_R1 && AOP_STK */
929 pic16_emitcode ("pop","ar0");
933 bitVectUnSetBit(ic->rUsed,R0_IDX);
939 pic16_emitcode ("pop","ar1");
943 bitVectUnSetBit(ic->rUsed,R1_IDX);
949 int stk = aop->aopu.aop_stk + aop->size;
950 bitVectUnSetBit(ic->rUsed,R0_IDX);
951 bitVectUnSetBit(ic->rUsed,R1_IDX);
953 getFreePtr(ic,&aop,FALSE);
955 if (options.stack10bit)
957 /* I'm not sure what to do here yet... */
960 "*** Warning: probably generating bad code for "
961 "10 bit stack mode.\n");
965 pic16_emitcode ("mov","a,_bp");
966 pic16_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
967 pic16_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
969 pic16_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
973 pic16_emitcode("pop","acc");
974 pic16_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
976 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
979 pic16_freeAsmop(op,NULL,ic,TRUE);
981 pic16_emitcode("pop","ar0");
986 pic16_emitcode("pop","ar1");
994 /* all other cases just dealloc */
998 OP_SYMBOL(op)->aop = NULL;
999 /* if the symbol has a spill */
1001 SPIL_LOC(op)->aop = NULL;
1006 /*-----------------------------------------------------------------*/
1007 /* pic16_aopGet - for fetching value of the aop */
1008 /*-----------------------------------------------------------------*/
1009 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
1014 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1015 /* offset is greater than
1017 if (offset > (aop->size - 1) &&
1018 aop->type != AOP_LIT)
1021 /* depending on type */
1022 switch (aop->type) {
1026 DEBUGpic16_emitcode(";","%d",__LINE__);
1027 /* if we need to increment it */
1028 while (offset > aop->coff) {
1029 pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1033 while (offset < aop->coff) {
1034 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1038 aop->coff = offset ;
1040 pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1041 return (dname ? "acc" : "a");
1043 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1044 rs = Safe_calloc(1,strlen(s)+1);
1050 DEBUGpic16_emitcode(";","%d",__LINE__);
1051 if (aop->type == AOP_DPTR2)
1056 while (offset > aop->coff) {
1057 pic16_emitcode ("inc","dptr");
1061 while (offset < aop->coff) {
1062 pic16_emitcode("lcall","__decdptr");
1068 pic16_emitcode("clr","a");
1069 pic16_emitcode("movc","a,@a+dptr");
1072 pic16_emitcode("movx","a,@dptr");
1075 if (aop->type == AOP_DPTR2)
1080 return (dname ? "acc" : "a");
1085 sprintf (s,"%s",aop->aopu.aop_immd);
1088 sprintf(s,"(%s >> %d)",
1093 aop->aopu.aop_immd);
1094 DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s);
1095 rs = Safe_calloc(1,strlen(s)+1);
1101 sprintf(s,"(%s + %d)",
1104 DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s);
1106 sprintf(s,"%s",aop->aopu.aop_dir);
1107 rs = Safe_calloc(1,strlen(s)+1);
1113 // return aop->aopu.aop_reg[offset]->dname;
1115 return aop->aopu.aop_reg[offset]->name;
1118 //pic16_emitcode(";","%d",__LINE__);
1119 return aop->aopu.aop_dir;
1122 DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1123 return "AOP_accumulator_bug";
1126 sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset));
1127 rs = Safe_calloc(1,strlen(s)+1);
1132 aop->coff = offset ;
1133 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1136 DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1138 return aop->aopu.aop_str[offset];
1142 pCodeOp *pcop = aop->aopu.pcop;
1143 DEBUGpic16_emitcode(";","%d: pic16_aopGet AOP_PCODE type %s",__LINE__,pic16_pCodeOpType(pcop));
1145 DEBUGpic16_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1146 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1147 sprintf(s,"%s", pcop->name);
1149 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1152 rs = Safe_calloc(1,strlen(s)+1);
1158 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1159 "aopget got unsupported aop->type");
1164 /*-----------------------------------------------------------------*/
1165 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1166 /*-----------------------------------------------------------------*/
1167 pCodeOp *pic16_popGetTempReg(void)
1172 pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
1173 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1174 PCOR(pcop)->r->wasUsed=1;
1175 PCOR(pcop)->r->isFree=0;
1181 /*-----------------------------------------------------------------*/
1182 /* pic16_popGetTempReg - create a new temporary pCodeOp */
1183 /*-----------------------------------------------------------------*/
1184 void pic16_popReleaseTempReg(pCodeOp *pcop)
1187 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1188 PCOR(pcop)->r->isFree = 1;
1191 /*-----------------------------------------------------------------*/
1192 /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */
1193 /*-----------------------------------------------------------------*/
1194 pCodeOp *pic16_popGetLabel(unsigned int key)
1197 DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1202 return pic16_newpCodeOpLabel(NULL,key+100+labelOffset);
1205 /*-----------------------------------------------------------------*/
1206 /* pic16_popCopyReg - copy a pcode operator */
1207 /*-----------------------------------------------------------------*/
1208 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc)
1212 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1213 pcor->pcop.type = pc->pcop.type;
1215 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1216 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1218 pcor->pcop.name = NULL;
1221 pcor->rIdx = pc->rIdx;
1224 //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1228 /*-----------------------------------------------------------------*/
1229 /* pic16_popGet - asm operator to pcode operator conversion */
1230 /*-----------------------------------------------------------------*/
1231 pCodeOp *pic16_popGetLit(unsigned int lit)
1234 return pic16_newpCodeOpLit(lit);
1238 /*-----------------------------------------------------------------*/
1239 /* pic16_popGetImmd - asm operator to pcode immediate conversion */
1240 /*-----------------------------------------------------------------*/
1241 pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index)
1244 return pic16_newpCodeOpImmd(name, offset,index, 0);
1248 /*-----------------------------------------------------------------*/
1249 /* pic16_popGet - asm operator to pcode operator conversion */
1250 /*-----------------------------------------------------------------*/
1251 pCodeOp *pic16_popGetWithString(char *str)
1257 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1261 pcop = pic16_newpCodeOp(str,PO_STR);
1266 /*-----------------------------------------------------------------*/
1267 /* popRegFromString - */
1268 /*-----------------------------------------------------------------*/
1269 static pCodeOp *popRegFromString(char *str, int size, int offset)
1272 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1273 pcop->type = PO_DIR;
1275 DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str);
1276 // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size);
1281 pcop->name = Safe_calloc(1,strlen(str)+1);
1282 strcpy(pcop->name,str);
1284 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1286 PCOR(pcop)->r = pic16_dirregWithName(pcop->name);
1287 if(PCOR(pcop)->r == NULL) {
1288 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1289 PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size);
1291 //fprintf(stderr, "allocating new register -> %s\n", str);
1293 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1295 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1297 PCOR(pcop)->instance = offset;
1302 static pCodeOp *popRegFromIdx(int rIdx)
1306 DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x",
1307 __FUNCTION__,__LINE__,rIdx);
1309 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1311 PCOR(pcop)->rIdx = rIdx;
1312 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1313 PCOR(pcop)->r->isFree = 0;
1314 PCOR(pcop)->r->wasUsed = 1;
1316 pcop->type = PCOR(pcop)->r->pc_type;
1322 /*---------------------------------------------------------------------------------*/
1323 /* pic16_popGet2 - a variant of pic16_popGet to handle two memory operand commands */
1325 /*---------------------------------------------------------------------------------*/
1326 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
1331 pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
1332 temp = pic16_popGet(aop_dst, offset);
1333 pcop2->pcop2 = temp;
1339 /*-----------------------------------------------------------------*/
1340 /* pic16_popGet - asm operator to pcode operator conversion */
1341 /*-----------------------------------------------------------------*/
1342 pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1344 //char *s = buffer ;
1349 //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1350 /* offset is greater than
1353 if (offset > (aop->size - 1) &&
1354 aop->type != AOP_LIT)
1355 return NULL; //zero;
1357 /* depending on type */
1358 switch (aop->type) {
1365 DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
1369 DEBUGpic16_emitcode(";","%d",__LINE__);
1370 return pic16_popGetImmd(aop->aopu.aop_immd,offset,0);
1373 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1376 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1377 pcop->type = PO_DIR;
1381 sprintf(s,"(%s + %d)",
1385 sprintf(s,"%s",aop->aopu.aop_dir);
1386 pcop->name = Safe_calloc(1,strlen(s)+1);
1387 strcpy(pcop->name,s);
1389 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1390 strcpy(pcop->name,aop->aopu.aop_dir);
1391 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1392 if(PCOR(pcop)->r == NULL) {
1393 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1394 PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size);
1395 DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1397 DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1399 PCOR(pcop)->instance = offset;
1406 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1408 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1409 PCOR(pcop)->rIdx = rIdx;
1410 PCOR(pcop)->r = pic16_regWithIdx(rIdx);
1411 PCOR(pcop)->r->wasUsed=1;
1412 PCOR(pcop)->r->isFree=0;
1414 PCOR(pcop)->instance = offset;
1415 pcop->type = PCOR(pcop)->r->pc_type;
1416 //rs = aop->aopu.aop_reg[offset]->name;
1417 //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1422 pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1423 PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir);
1424 //if(PCOR(pcop)->r == NULL)
1425 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1429 return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset));
1432 DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1433 return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1435 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1436 PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]);
1437 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1438 pcop->type = PCOR(pcop)->r->pc_type;
1439 pcop->name = PCOR(pcop)->r->name;
1445 DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop),
1447 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1448 pcop = pic16_pCodeOpCopy(aop->aopu.pcop);
1449 PCOI(pcop)->offset = offset;
1453 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1454 "pic16_popGet got unsupported aop->type");
1457 /*-----------------------------------------------------------------*/
1458 /* pic16_aopPut - puts a string for a aop */
1459 /*-----------------------------------------------------------------*/
1460 void pic16_aopPut (asmop *aop, char *s, int offset)
1465 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1467 if (aop->size && offset > ( aop->size - 1)) {
1468 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1469 "pic16_aopPut got offset > aop->size");
1473 /* will assign value to value */
1474 /* depending on where it is ofcourse */
1475 switch (aop->type) {
1478 sprintf(d,"(%s + %d)",
1479 aop->aopu.aop_dir,offset);
1480 fprintf(stderr,"oops pic16_aopPut:AOP_DIR did this %s\n",s);
1483 sprintf(d,"%s",aop->aopu.aop_dir);
1486 DEBUGpic16_emitcode(";","%d",__LINE__);
1488 pic16_emitcode("movf","%s,w",s);
1489 pic16_emitcode("movwf","%s",d);
1492 pic16_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1493 if(offset >= aop->size) {
1494 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1497 pic16_emitpcode(POC_MOVLW,pic16_popGetImmd(s,offset,0));
1500 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1507 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1508 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1511 strcmp(s,"r0") == 0 ||
1512 strcmp(s,"r1") == 0 ||
1513 strcmp(s,"r2") == 0 ||
1514 strcmp(s,"r3") == 0 ||
1515 strcmp(s,"r4") == 0 ||
1516 strcmp(s,"r5") == 0 ||
1517 strcmp(s,"r6") == 0 ||
1518 strcmp(s,"r7") == 0 )
1519 pic16_emitcode("mov","%s,%s ; %d",
1520 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1524 if(strcmp(s,"W")==0 )
1525 pic16_emitcode("movf","%s,w ; %d",s,__LINE__);
1527 pic16_emitcode("movwf","%s",
1528 aop->aopu.aop_reg[offset]->name);
1530 if(strcmp(s,zero)==0) {
1531 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1533 } else if(strcmp(s,"W")==0) {
1534 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1535 pcop->type = PO_GPR_REGISTER;
1537 PCOR(pcop)->rIdx = -1;
1538 PCOR(pcop)->r = NULL;
1540 DEBUGpic16_emitcode(";","%d",__LINE__);
1541 pcop->name = Safe_strdup(s);
1542 pic16_emitpcode(POC_MOVFW,pcop);
1543 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1544 } else if(strcmp(s,one)==0) {
1545 pic16_emitpcode(POC_CLRF,pic16_popGet(aop,offset));
1546 pic16_emitpcode(POC_INCF,pic16_popGet(aop,offset));
1548 pic16_emitpcode(POC_MOVWF,pic16_popGet(aop,offset));
1556 if (aop->type == AOP_DPTR2)
1562 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1563 "pic16_aopPut writting to code space");
1567 while (offset > aop->coff) {
1569 pic16_emitcode ("inc","dptr");
1572 while (offset < aop->coff) {
1574 pic16_emitcode("lcall","__decdptr");
1579 /* if not in accumulater */
1582 pic16_emitcode ("movx","@dptr,a");
1584 if (aop->type == AOP_DPTR2)
1592 while (offset > aop->coff) {
1594 pic16_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1596 while (offset < aop->coff) {
1598 pic16_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1604 pic16_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1609 pic16_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1611 if (strcmp(s,"r0") == 0 ||
1612 strcmp(s,"r1") == 0 ||
1613 strcmp(s,"r2") == 0 ||
1614 strcmp(s,"r3") == 0 ||
1615 strcmp(s,"r4") == 0 ||
1616 strcmp(s,"r5") == 0 ||
1617 strcmp(s,"r6") == 0 ||
1618 strcmp(s,"r7") == 0 ) {
1620 sprintf(buffer,"a%s",s);
1621 pic16_emitcode("mov","@%s,%s",
1622 aop->aopu.aop_ptr->name,buffer);
1624 pic16_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1629 if (strcmp(s,"a") == 0)
1630 pic16_emitcode("push","acc");
1632 pic16_emitcode("push","%s",s);
1637 /* if bit variable */
1638 if (!aop->aopu.aop_dir) {
1639 pic16_emitcode("clr","a");
1640 pic16_emitcode("rlc","a");
1643 pic16_emitcode("clr","%s",aop->aopu.aop_dir);
1646 pic16_emitcode("setb","%s",aop->aopu.aop_dir);
1649 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1651 lbl = newiTempLabel(NULL);
1653 if (strcmp(s,"a")) {
1656 pic16_emitcode("clr","c");
1657 pic16_emitcode("jz","%05d_DS_",lbl->key+100);
1658 pic16_emitcode("cpl","c");
1659 pic16_emitcode("","%05d_DS_:",lbl->key+100);
1660 pic16_emitcode("mov","%s,c",aop->aopu.aop_dir);
1667 if (strcmp(aop->aopu.aop_str[offset],s))
1668 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1673 if (!offset && (strcmp(s,"acc") == 0))
1676 if (strcmp(aop->aopu.aop_str[offset],s))
1677 pic16_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1681 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1682 "pic16_aopPut got unsupported aop->type");
1688 /*-----------------------------------------------------------------*/
1689 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1690 /*-----------------------------------------------------------------*/
1691 static void mov2w (asmop *aop, int offset)
1697 DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1699 if ( aop->type == AOP_PCODE ||
1700 aop->type == AOP_LIT )
1701 pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset));
1703 pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset));
1707 /*-----------------------------------------------------------------*/
1708 /* reAdjustPreg - points a register back to where it should */
1709 /*-----------------------------------------------------------------*/
1710 static void reAdjustPreg (asmop *aop)
1714 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1716 if ((size = aop->size) <= 1)
1719 switch (aop->type) {
1723 pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1727 if (aop->type == AOP_DPTR2)
1733 pic16_emitcode("lcall","__decdptr");
1736 if (aop->type == AOP_DPTR2)
1748 /*-----------------------------------------------------------------*/
1749 /* opIsGptr: returns non-zero if the passed operand is */
1750 /* a generic pointer type. */
1751 /*-----------------------------------------------------------------*/
1752 static int opIsGptr(operand *op)
1754 sym_link *type = operandType(op);
1756 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1757 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1765 /*-----------------------------------------------------------------*/
1766 /* pic16_getDataSize - get the operand data size */
1767 /*-----------------------------------------------------------------*/
1768 int pic16_getDataSize(operand *op)
1770 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1773 return AOP_SIZE(op);
1775 // tsd- in the pic port, the genptr size is 1, so this code here
1776 // fails. ( in the 8051 port, the size was 4).
1779 size = AOP_SIZE(op);
1780 if (size == GPTRSIZE)
1782 sym_link *type = operandType(op);
1783 if (IS_GENPTR(type))
1785 /* generic pointer; arithmetic operations
1786 * should ignore the high byte (pointer type).
1789 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1796 /*-----------------------------------------------------------------*/
1797 /* pic16_outAcc - output Acc */
1798 /*-----------------------------------------------------------------*/
1799 void pic16_outAcc(operand *result)
1802 DEBUGpic16_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1803 DEBUGpic16_pic16_AopType(__LINE__,NULL,NULL,result);
1806 size = pic16_getDataSize(result);
1808 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
1811 /* unsigned or positive */
1813 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset++));
1818 /*-----------------------------------------------------------------*/
1819 /* pic16_outBitC - output a bit C */
1820 /*-----------------------------------------------------------------*/
1821 void pic16_outBitC(operand *result)
1824 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1825 /* if the result is bit */
1826 if (AOP_TYPE(result) == AOP_CRY)
1827 pic16_aopPut(AOP(result),"c",0);
1829 pic16_emitcode("clr","a ; %d", __LINE__);
1830 pic16_emitcode("rlc","a");
1831 pic16_outAcc(result);
1835 /*-----------------------------------------------------------------*/
1836 /* pic16_toBoolean - emit code for orl a,operator(sizeop) */
1837 /*-----------------------------------------------------------------*/
1838 void pic16_toBoolean(operand *oper)
1840 int size = AOP_SIZE(oper) - 1;
1843 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1845 if ( AOP_TYPE(oper) != AOP_ACC) {
1846 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(oper),0));
1849 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(oper),offset++));
1854 /*-----------------------------------------------------------------*/
1855 /* genNot - generate code for ! operation */
1856 /*-----------------------------------------------------------------*/
1857 static void genNot (iCode *ic)
1862 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1863 /* assign asmOps to operand & result */
1864 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1865 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1867 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1868 /* if in bit space then a special case */
1869 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1870 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1871 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1872 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1874 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1875 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
1876 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1881 size = AOP_SIZE(IC_LEFT(ic));
1883 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
1884 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
1885 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
1888 pic16_toBoolean(IC_LEFT(ic));
1890 tlbl = newiTempLabel(NULL);
1891 pic16_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1892 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
1893 pic16_outBitC(IC_RESULT(ic));
1896 /* release the aops */
1897 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1898 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1902 /*-----------------------------------------------------------------*/
1903 /* genCpl - generate code for complement */
1904 /*-----------------------------------------------------------------*/
1905 static void genCpl (iCode *ic)
1911 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1912 /* assign asmOps to operand & result */
1913 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
1914 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
1916 /* if both are in bit space then
1918 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1919 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1921 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1922 pic16_emitcode("cpl","c");
1923 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1927 size = AOP_SIZE(IC_RESULT(ic));
1930 char *l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1932 pic16_emitcode("cpl","a");
1933 pic16_aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1935 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
1936 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
1938 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
1939 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
1947 /* release the aops */
1948 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1949 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1952 /*-----------------------------------------------------------------*/
1953 /* genUminusFloat - unary minus for floating points */
1954 /*-----------------------------------------------------------------*/
1955 static void genUminusFloat(operand *op,operand *result)
1957 int size ,offset =0 ;
1960 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1961 /* for this we just need to flip the
1962 first it then copy the rest in place */
1963 size = AOP_SIZE(op) - 1;
1964 l = pic16_aopGet(AOP(op),3,FALSE,FALSE);
1968 pic16_emitcode("cpl","acc.7");
1969 pic16_aopPut(AOP(result),"a",3);
1972 pic16_aopPut(AOP(result),
1973 pic16_aopGet(AOP(op),offset,FALSE,FALSE),
1979 /*-----------------------------------------------------------------*/
1980 /* genUminus - unary minus code generation */
1981 /*-----------------------------------------------------------------*/
1982 static void genUminus (iCode *ic)
1985 sym_link *optype, *rtype;
1988 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1990 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
1991 pic16_aopOp(IC_RESULT(ic),ic,TRUE);
1993 /* if both in bit space then special
1995 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1996 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1998 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
1999 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0));
2000 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2005 optype = operandType(IC_LEFT(ic));
2006 rtype = operandType(IC_RESULT(ic));
2008 /* if float then do float stuff */
2009 if (IS_FLOAT(optype)) {
2010 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2014 /* otherwise subtract from zero by taking the 2's complement */
2015 size = AOP_SIZE(IC_LEFT(ic));
2017 for(i=0; i<size; i++) {
2018 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2019 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)),i));
2021 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),i));
2022 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2026 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),0));
2027 for(i=1; i<size; i++) {
2029 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)),i));
2033 /* release the aops */
2034 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2035 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2038 /*-----------------------------------------------------------------*/
2039 /* saveRegisters - will look for a call and save the registers */
2040 /*-----------------------------------------------------------------*/
2041 static void saveRegisters(iCode *lic)
2048 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2050 for (ic = lic ; ic ; ic = ic->next)
2051 if (ic->op == CALL || ic->op == PCALL)
2055 fprintf(stderr,"found parameter push with no function call\n");
2059 /* if the registers have been saved already then
2061 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2064 /* find the registers in use at this time
2065 and push them away to safety */
2066 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2070 if (options.useXstack) {
2071 if (bitVectBitValue(rsave,R0_IDX))
2072 pic16_emitcode("mov","b,r0");
2073 pic16_emitcode("mov","r0,%s",spname);
2074 for (i = 0 ; i < pic16_nRegs ; i++) {
2075 if (bitVectBitValue(rsave,i)) {
2077 pic16_emitcode("mov","a,b");
2079 pic16_emitcode("mov","a,%s",pic16_regWithIdx(i)->name);
2080 pic16_emitcode("movx","@r0,a");
2081 pic16_emitcode("inc","r0");
2084 pic16_emitcode("mov","%s,r0",spname);
2085 if (bitVectBitValue(rsave,R0_IDX))
2086 pic16_emitcode("mov","r0,b");
2088 //for (i = 0 ; i < pic16_nRegs ; i++) {
2089 // if (bitVectBitValue(rsave,i))
2090 // pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2093 dtype = operandType(IC_LEFT(ic));
2094 if (currFunc && dtype &&
2095 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2096 IFFUNC_ISISR(currFunc->type) &&
2099 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2102 /*-----------------------------------------------------------------*/
2103 /* unsaveRegisters - pop the pushed registers */
2104 /*-----------------------------------------------------------------*/
2105 static void unsaveRegisters (iCode *ic)
2110 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2111 /* find the registers in use at this time
2112 and push them away to safety */
2113 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2116 if (options.useXstack) {
2117 pic16_emitcode("mov","r0,%s",spname);
2118 for (i = pic16_nRegs ; i >= 0 ; i--) {
2119 if (bitVectBitValue(rsave,i)) {
2120 pic16_emitcode("dec","r0");
2121 pic16_emitcode("movx","a,@r0");
2123 pic16_emitcode("mov","b,a");
2125 pic16_emitcode("mov","%s,a",pic16_regWithIdx(i)->name);
2129 pic16_emitcode("mov","%s,r0",spname);
2130 if (bitVectBitValue(rsave,R0_IDX))
2131 pic16_emitcode("mov","r0,b");
2133 //for (i = pic16_nRegs ; i >= 0 ; i--) {
2134 // if (bitVectBitValue(rsave,i))
2135 // pic16_emitcode("pop","%s",pic16_regWithIdx(i)->dname);
2141 /*-----------------------------------------------------------------*/
2143 /*-----------------------------------------------------------------*/
2144 static void pushSide(operand * oper, int size)
2148 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2150 char *l = pic16_aopGet(AOP(oper),offset++,FALSE,TRUE);
2151 if (AOP_TYPE(oper) != AOP_REG &&
2152 AOP_TYPE(oper) != AOP_DIR &&
2154 pic16_emitcode("mov","a,%s",l);
2155 pic16_emitcode("push","acc");
2157 pic16_emitcode("push","%s",l);
2162 /*-----------------------------------------------------------------*/
2163 /* assignResultValue - */
2164 /*-----------------------------------------------------------------*/
2165 static void assignResultValue(operand * oper)
2167 int size = AOP_SIZE(oper);
2169 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2171 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL);
2173 if(!GpsuedoStkPtr) {
2174 /* The last byte in the assignment is in W */
2176 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2181 pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
2183 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size));
2188 /*-----------------------------------------------------------------*/
2189 /* genIpush - genrate code for pushing this gets a little complex */
2190 /*-----------------------------------------------------------------*/
2191 static void genIpush (iCode *ic)
2194 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2196 int size, offset = 0 ;
2200 /* if this is not a parm push : ie. it is spill push
2201 and spill push is always done on the local stack */
2202 if (!ic->parmPush) {
2204 /* and the item is spilt then do nothing */
2205 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2208 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2209 size = AOP_SIZE(IC_LEFT(ic));
2210 /* push it on the stack */
2212 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2217 pic16_emitcode("push","%s",l);
2222 /* this is a paramter push: in this case we call
2223 the routine to find the call and save those
2224 registers that need to be saved */
2227 /* then do the push */
2228 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2231 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2232 size = AOP_SIZE(IC_LEFT(ic));
2235 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2236 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2237 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2239 pic16_emitcode("mov","a,%s",l);
2240 pic16_emitcode("push","acc");
2242 pic16_emitcode("push","%s",l);
2245 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2249 /*-----------------------------------------------------------------*/
2250 /* genIpop - recover the registers: can happen only for spilling */
2251 /*-----------------------------------------------------------------*/
2252 static void genIpop (iCode *ic)
2254 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2259 /* if the temp was not pushed then */
2260 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2263 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2264 size = AOP_SIZE(IC_LEFT(ic));
2267 pic16_emitcode("pop","%s",pic16_aopGet(AOP(IC_LEFT(ic)),offset--,
2270 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2274 /*-----------------------------------------------------------------*/
2275 /* unsaverbank - restores the resgister bank from stack */
2276 /*-----------------------------------------------------------------*/
2277 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2279 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2287 if (options.useXstack) {
2289 r = getFreePtr(ic,&aop,FALSE);
2292 pic16_emitcode("mov","%s,_spx",r->name);
2293 pic16_emitcode("movx","a,@%s",r->name);
2294 pic16_emitcode("mov","psw,a");
2295 pic16_emitcode("dec","%s",r->name);
2298 pic16_emitcode ("pop","psw");
2301 for (i = (pic16_nRegs - 1) ; i >= 0 ;i--) {
2302 if (options.useXstack) {
2303 pic16_emitcode("movx","a,@%s",r->name);
2304 //pic16_emitcode("mov","(%s+%d),a",
2305 // regspic16[i].base,8*bank+regspic16[i].offset);
2306 pic16_emitcode("dec","%s",r->name);
2309 pic16_emitcode("pop",""); //"(%s+%d)",
2310 //regspic16[i].base,8*bank); //+regspic16[i].offset);
2313 if (options.useXstack) {
2315 pic16_emitcode("mov","_spx,%s",r->name);
2316 pic16_freeAsmop(NULL,aop,ic,TRUE);
2322 /*-----------------------------------------------------------------*/
2323 /* saverbank - saves an entire register bank on the stack */
2324 /*-----------------------------------------------------------------*/
2325 static void saverbank (int bank, iCode *ic, bool pushPsw)
2327 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2333 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2334 if (options.useXstack) {
2337 r = getFreePtr(ic,&aop,FALSE);
2338 pic16_emitcode("mov","%s,_spx",r->name);
2342 for (i = 0 ; i < pic16_nRegs ;i++) {
2343 if (options.useXstack) {
2344 pic16_emitcode("inc","%s",r->name);
2345 //pic16_emitcode("mov","a,(%s+%d)",
2346 // regspic16[i].base,8*bank+regspic16[i].offset);
2347 pic16_emitcode("movx","@%s,a",r->name);
2349 pic16_emitcode("push","");// "(%s+%d)",
2350 //regspic16[i].base,8*bank+regspic16[i].offset);
2354 if (options.useXstack) {
2355 pic16_emitcode("mov","a,psw");
2356 pic16_emitcode("movx","@%s,a",r->name);
2357 pic16_emitcode("inc","%s",r->name);
2358 pic16_emitcode("mov","_spx,%s",r->name);
2359 pic16_freeAsmop (NULL,aop,ic,TRUE);
2362 pic16_emitcode("push","psw");
2364 pic16_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2370 /*-----------------------------------------------------------------*/
2371 /* genCall - generates a call statement */
2372 /*-----------------------------------------------------------------*/
2373 static void genCall (iCode *ic)
2377 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2379 /* if caller saves & we have not saved then */
2383 /* if we are calling a function that is not using
2384 the same register bank then we need to save the
2385 destination registers on the stack */
2386 dtype = operandType(IC_LEFT(ic));
2387 if (currFunc && dtype &&
2388 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2389 IFFUNC_ISISR(currFunc->type) &&
2392 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2394 /* if send set is not empty the assign */
2397 /* For the Pic port, there is no data stack.
2398 * So parameters passed to functions are stored
2399 * in registers. (The pCode optimizer will get
2400 * rid of most of these :).
2402 int psuedoStkPtr=-1;
2403 int firstTimeThruLoop = 1;
2405 _G.sendSet = reverseSet(_G.sendSet);
2407 /* First figure how many parameters are getting passed */
2408 for (sic = setFirstItem(_G.sendSet) ; sic ;
2409 sic = setNextItem(_G.sendSet)) {
2411 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2412 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2413 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2416 for (sic = setFirstItem(_G.sendSet) ; sic ;
2417 sic = setNextItem(_G.sendSet)) {
2418 int size, offset = 0;
2420 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2421 size = AOP_SIZE(IC_LEFT(sic));
2424 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2425 pic16_AopType(AOP_TYPE(IC_LEFT(sic))));
2427 if(!firstTimeThruLoop) {
2428 /* If this is not the first time we've been through the loop
2429 * then we need to save the parameter in a temporary
2430 * register. The last byte of the last parameter is
2432 pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
2435 firstTimeThruLoop=0;
2437 //if (strcmp(l,fReturn[offset])) {
2438 mov2w (AOP(IC_LEFT(sic)), offset);
2440 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2441 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2442 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2444 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset));
2449 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2454 pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2455 OP_SYMBOL(IC_LEFT(ic))->rname :
2456 OP_SYMBOL(IC_LEFT(ic))->name));
2459 /* if we need assign a result value */
2460 if ((IS_ITEMP(IC_RESULT(ic)) &&
2461 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2462 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2463 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2466 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2469 assignResultValue(IC_RESULT(ic));
2471 DEBUGpic16_emitcode ("; ","%d left %s",__LINE__,
2472 pic16_AopType(AOP_TYPE(IC_RESULT(ic))));
2474 pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2477 /* adjust the stack for parameters if
2479 if (ic->parmBytes) {
2481 if (ic->parmBytes > 3) {
2482 pic16_emitcode("mov","a,%s",spname);
2483 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2484 pic16_emitcode("mov","%s,a",spname);
2486 for ( i = 0 ; i < ic->parmBytes ;i++)
2487 pic16_emitcode("dec","%s",spname);
2491 /* if register bank was saved then pop them */
2493 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2495 /* if we hade saved some registers then unsave them */
2496 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2497 unsaveRegisters (ic);
2502 /*-----------------------------------------------------------------*/
2503 /* genPcall - generates a call by pointer statement */
2504 /*-----------------------------------------------------------------*/
2505 static void genPcall (iCode *ic)
2508 symbol *rlbl = newiTempLabel(NULL);
2511 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2512 /* if caller saves & we have not saved then */
2516 /* if we are calling a function that is not using
2517 the same register bank then we need to save the
2518 destination registers on the stack */
2519 dtype = operandType(IC_LEFT(ic));
2520 if (currFunc && dtype &&
2521 IFFUNC_ISISR(currFunc->type) &&
2522 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2523 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2526 /* push the return address on to the stack */
2527 pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2528 pic16_emitcode("push","acc");
2529 pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2530 pic16_emitcode("push","acc");
2532 if (options.model == MODEL_FLAT24)
2534 pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2535 pic16_emitcode("push","acc");
2538 /* now push the calling address */
2539 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
2541 pushSide(IC_LEFT(ic), FPTRSIZE);
2543 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2545 /* if send set is not empty the assign */
2549 for (sic = setFirstItem(_G.sendSet) ; sic ;
2550 sic = setNextItem(_G.sendSet)) {
2551 int size, offset = 0;
2552 pic16_aopOp(IC_LEFT(sic),sic,FALSE);
2553 size = AOP_SIZE(IC_LEFT(sic));
2555 char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset,
2557 if (strcmp(l,fReturn[offset]))
2558 pic16_emitcode("mov","%s,%s",
2563 pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2568 pic16_emitcode("ret","");
2569 pic16_emitcode("","%05d_DS_:",(rlbl->key+100));
2572 /* if we need assign a result value */
2573 if ((IS_ITEMP(IC_RESULT(ic)) &&
2574 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2575 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2576 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2579 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
2582 assignResultValue(IC_RESULT(ic));
2584 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2587 /* adjust the stack for parameters if
2589 if (ic->parmBytes) {
2591 if (ic->parmBytes > 3) {
2592 pic16_emitcode("mov","a,%s",spname);
2593 pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2594 pic16_emitcode("mov","%s,a",spname);
2596 for ( i = 0 ; i < ic->parmBytes ;i++)
2597 pic16_emitcode("dec","%s",spname);
2601 /* if register bank was saved then unsave them */
2602 if (currFunc && dtype &&
2603 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2604 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2606 /* if we hade saved some registers then
2609 unsaveRegisters (ic);
2613 /*-----------------------------------------------------------------*/
2614 /* resultRemat - result is rematerializable */
2615 /*-----------------------------------------------------------------*/
2616 static int resultRemat (iCode *ic)
2618 // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2619 if (SKIP_IC(ic) || ic->op == IFX)
2622 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2623 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2624 if (sym->remat && !POINTER_SET(ic))
2631 #if defined(__BORLANDC__) || defined(_MSC_VER)
2632 #define STRCASECMP stricmp
2634 #define STRCASECMP strcasecmp
2638 /*-----------------------------------------------------------------*/
2639 /* inExcludeList - return 1 if the string is in exclude Reg list */
2640 /*-----------------------------------------------------------------*/
2641 static bool inExcludeList(char *s)
2643 DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2646 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2647 if (options.excludeRegs[i] &&
2648 STRCASECMP(options.excludeRegs[i],"none") == 0)
2651 for ( i = 0 ; options.excludeRegs[i]; i++) {
2652 if (options.excludeRegs[i] &&
2653 STRCASECMP(s,options.excludeRegs[i]) == 0)
2660 /*-----------------------------------------------------------------*/
2661 /* genFunction - generated code for function entry */
2662 /*-----------------------------------------------------------------*/
2663 static void genFunction (iCode *ic)
2668 DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2670 labelOffset += (max_key+4);
2674 /* create the function header */
2675 pic16_emitcode(";","-----------------------------------------");
2676 pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2677 pic16_emitcode(";","-----------------------------------------");
2679 pic16_emitcode("","%s:",sym->rname);
2680 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
2682 ftype = operandType(IC_LEFT(ic));
2684 /* if critical function then turn interrupts off */
2685 if (IFFUNC_ISCRITICAL(ftype))
2686 pic16_emitcode("clr","ea");
2688 /* here we need to generate the equates for the
2689 register bank if required */
2691 if (FUNC_REGBANK(ftype) != rbank) {
2694 rbank = FUNC_REGBANK(ftype);
2695 for ( i = 0 ; i < pic16_nRegs ; i++ ) {
2696 if (strcmp(regspic16[i].base,"0") == 0)
2697 pic16_emitcode("","%s = 0x%02x",
2699 8*rbank+regspic16[i].offset);
2701 pic16_emitcode ("","%s = %s + 0x%02x",
2704 8*rbank+regspic16[i].offset);
2709 /* if this is an interrupt service routine then
2710 save acc, b, dpl, dph */
2711 if (IFFUNC_ISISR(sym->type)) {
2714 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
2716 /* what is the reason of having these 3 NOPS? VR - 030701 */
2717 pic16_emitpcodeNULLop(POC_NOP);
2718 pic16_emitpcodeNULLop(POC_NOP);
2719 pic16_emitpcodeNULLop(POC_NOP);
2722 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave));
2723 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
2724 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2725 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave));
2727 pic16_pBlockConvert2ISR(pb);
2729 if (!inExcludeList("acc"))
2730 pic16_emitcode ("push","acc");
2731 if (!inExcludeList("b"))
2732 pic16_emitcode ("push","b");
2733 if (!inExcludeList("dpl"))
2734 pic16_emitcode ("push","dpl");
2735 if (!inExcludeList("dph"))
2736 pic16_emitcode ("push","dph");
2737 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2739 pic16_emitcode ("push", "dpx");
2740 /* Make sure we're using standard DPTR */
2741 pic16_emitcode ("push", "dps");
2742 pic16_emitcode ("mov", "dps, #0x00");
2743 if (options.stack10bit)
2745 /* This ISR could conceivably use DPTR2. Better save it. */
2746 pic16_emitcode ("push", "dpl1");
2747 pic16_emitcode ("push", "dph1");
2748 pic16_emitcode ("push", "dpx1");
2751 /* if this isr has no bank i.e. is going to
2752 run with bank 0 , then we need to save more
2754 if (!FUNC_REGBANK(sym->type)) {
2756 /* if this function does not call any other
2757 function then we can be economical and
2758 save only those registers that are used */
2759 if (! IFFUNC_HASFCALL(sym->type)) {
2762 /* if any registers used */
2763 if (sym->regsUsed) {
2764 /* save the registers used */
2765 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2766 if (bitVectBitValue(sym->regsUsed,i) ||
2767 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2768 pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);
2773 /* this function has a function call cannot
2774 determines register usage so we will have the
2776 saverbank(0,ic,FALSE);
2781 /* if callee-save to be used for this function
2782 then save the registers being used in this function */
2783 if (IFFUNC_CALLEESAVES(sym->type)) {
2786 /* if any registers used */
2787 if (sym->regsUsed) {
2788 /* save the registers used */
2789 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2790 if (bitVectBitValue(sym->regsUsed,i) ||
2791 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2792 //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
2800 /* set the register bank to the desired value */
2801 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2802 pic16_emitcode("push","psw");
2803 pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2806 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2808 if (options.useXstack) {
2809 pic16_emitcode("mov","r0,%s",spname);
2810 pic16_emitcode("mov","a,_bp");
2811 pic16_emitcode("movx","@r0,a");
2812 pic16_emitcode("inc","%s",spname);
2816 /* set up the stack */
2817 pic16_emitcode ("push","_bp"); /* save the callers stack */
2819 pic16_emitcode ("mov","_bp,%s",spname);
2822 /* adjust the stack for the function */
2827 werror(W_STACK_OVERFLOW,sym->name);
2829 if (i > 3 && sym->recvSize < 4) {
2831 pic16_emitcode ("mov","a,sp");
2832 pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2833 pic16_emitcode ("mov","sp,a");
2838 pic16_emitcode("inc","sp");
2843 pic16_emitcode ("mov","a,_spx");
2844 pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2845 pic16_emitcode ("mov","_spx,a");
2850 /*-----------------------------------------------------------------*/
2851 /* genEndFunction - generates epilogue for functions */
2852 /*-----------------------------------------------------------------*/
2853 static void genEndFunction (iCode *ic)
2855 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2857 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2859 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2861 pic16_emitcode ("mov","%s,_bp",spname);
2864 /* if use external stack but some variables were
2865 added to the local stack then decrement the
2867 if (options.useXstack && sym->stack) {
2868 pic16_emitcode("mov","a,sp");
2869 pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2870 pic16_emitcode("mov","sp,a");
2874 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2875 if (options.useXstack) {
2876 pic16_emitcode("mov","r0,%s",spname);
2877 pic16_emitcode("movx","a,@r0");
2878 pic16_emitcode("mov","_bp,a");
2879 pic16_emitcode("dec","%s",spname);
2883 pic16_emitcode ("pop","_bp");
2887 /* restore the register bank */
2888 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2889 pic16_emitcode ("pop","psw");
2891 if (IFFUNC_ISISR(sym->type)) {
2893 /* now we need to restore the registers */
2894 /* if this isr has no bank i.e. is going to
2895 run with bank 0 , then we need to save more
2897 if (!FUNC_REGBANK(sym->type)) {
2899 /* if this function does not call any other
2900 function then we can be economical and
2901 save only those registers that are used */
2902 if (! IFFUNC_HASFCALL(sym->type)) {
2905 /* if any registers used */
2906 if (sym->regsUsed) {
2907 /* save the registers used */
2908 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2909 if (bitVectBitValue(sym->regsUsed,i) ||
2910 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2911 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2916 /* this function has a function call cannot
2917 determines register usage so we will have the
2919 unsaverbank(0,ic,FALSE);
2923 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2925 if (options.stack10bit)
2927 pic16_emitcode ("pop", "dpx1");
2928 pic16_emitcode ("pop", "dph1");
2929 pic16_emitcode ("pop", "dpl1");
2931 pic16_emitcode ("pop", "dps");
2932 pic16_emitcode ("pop", "dpx");
2934 if (!inExcludeList("dph"))
2935 pic16_emitcode ("pop","dph");
2936 if (!inExcludeList("dpl"))
2937 pic16_emitcode ("pop","dpl");
2938 if (!inExcludeList("b"))
2939 pic16_emitcode ("pop","b");
2940 if (!inExcludeList("acc"))
2941 pic16_emitcode ("pop","acc");
2943 if (IFFUNC_ISCRITICAL(sym->type))
2944 pic16_emitcode("setb","ea");
2947 /* if debug then send end of function */
2948 /* if (options.debug && currFunc) { */
2951 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2952 FileBaseName(ic->filename),currFunc->lastLine,
2953 ic->level,ic->block);
2954 if (IS_STATIC(currFunc->etype))
2955 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2957 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2961 // pic16_emitcode ("reti","");
2963 pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status));
2964 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
2965 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status));
2966 pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave));
2967 pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
2970 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1));
2973 pic16_emitpcodeNULLop(POC_RETFIE);
2977 if (IFFUNC_ISCRITICAL(sym->type))
2978 pic16_emitcode("setb","ea");
2980 if (IFFUNC_CALLEESAVES(sym->type)) {
2983 /* if any registers used */
2984 if (sym->regsUsed) {
2985 /* save the registers used */
2986 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2987 if (bitVectBitValue(sym->regsUsed,i) ||
2988 (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2989 pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
2995 /* if debug then send end of function */
2998 pic16_emitcode(";","C$%s$%d$%d$%d ==.",
2999 FileBaseName(ic->filename),currFunc->lastLine,
3000 ic->level,ic->block);
3001 if (IS_STATIC(currFunc->etype))
3002 pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3004 pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3008 pic16_emitcode ("return","");
3009 pic16_emitpcodeNULLop(POC_RETURN);
3011 /* Mark the end of a function */
3012 pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
3017 /*-----------------------------------------------------------------*/
3018 /* genRet - generate code for return statement */
3019 /*-----------------------------------------------------------------*/
3020 static void genRet (iCode *ic)
3022 int size,offset = 0 , pushed = 0;
3024 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3025 /* if we have no return value then
3026 just generate the "ret" */
3030 /* we have something to return then
3031 move the return value into place */
3032 pic16_aopOp(IC_LEFT(ic),ic,FALSE);
3033 size = AOP_SIZE(IC_LEFT(ic));
3037 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3039 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,
3041 pic16_emitcode("push","%s",l);
3044 l = pic16_aopGet(AOP(IC_LEFT(ic)),offset,
3046 if (strcmp(fReturn[offset],l)) {
3047 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3048 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3049 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3051 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
3054 pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
3064 if (strcmp(fReturn[pushed],"a"))
3065 pic16_emitcode("pop",fReturn[pushed]);
3067 pic16_emitcode("pop","acc");
3070 pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3073 /* generate a jump to the return label
3074 if the next is not the return statement */
3075 if (!(ic->next && ic->next->op == LABEL &&
3076 IC_LABEL(ic->next) == returnLabel)) {
3078 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key));
3079 pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3084 /*-----------------------------------------------------------------*/
3085 /* genLabel - generates a label */
3086 /*-----------------------------------------------------------------*/
3087 static void genLabel (iCode *ic)
3089 /* special case never generate */
3090 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3091 if (IC_LABEL(ic) == entryLabel)
3094 pic16_emitpLabel(IC_LABEL(ic)->key);
3095 pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3098 /*-----------------------------------------------------------------*/
3099 /* genGoto - generates a goto */
3100 /*-----------------------------------------------------------------*/
3102 static void genGoto (iCode *ic)
3104 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key));
3105 pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3109 /*-----------------------------------------------------------------*/
3110 /* genMultbits :- multiplication of bits */
3111 /*-----------------------------------------------------------------*/
3112 static void genMultbits (operand *left,
3116 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3118 if(!pic16_sameRegs(AOP(result),AOP(right)))
3119 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
3121 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
3122 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(left),0));
3123 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
3128 /*-----------------------------------------------------------------*/
3129 /* genMultOneByte : 8 bit multiplication & division */
3130 /*-----------------------------------------------------------------*/
3131 static void genMultOneByte (operand *left,
3135 sym_link *opetype = operandType(result);
3140 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3141 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3142 DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
3144 /* (if two literals, the value is computed before) */
3145 /* if one literal, literal on the right */
3146 if (AOP_TYPE(left) == AOP_LIT){
3152 size = AOP_SIZE(result);
3155 if (AOP_TYPE(right) == AOP_LIT){
3156 pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3157 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3158 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3159 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3160 pic16_emitcode("call","genMultLit");
3162 pic16_emitcode("multiply ","variable :%s by variable %s and store in %s",
3163 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3164 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3165 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3166 pic16_emitcode("call","pic16_genMult8X8_8");
3169 pic16_genMult8X8_8 (left, right,result);
3172 /* signed or unsigned */
3173 //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3174 //l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3176 //pic16_emitcode("mul","ab");
3177 /* if result size = 1, mul signed = mul unsigned */
3178 //pic16_aopPut(AOP(result),"a",0);
3180 } else { // (size > 1)
3182 pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3183 pic16_aopGet(AOP(right),0,FALSE,FALSE),
3184 pic16_aopGet(AOP(left),0,FALSE,FALSE),
3185 pic16_aopGet(AOP(result),0,FALSE,FALSE));
3187 if (SPEC_USIGN(opetype)){
3188 pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3189 pic16_genUMult8X8_16 (left, right, result, NULL);
3192 /* for filling the MSBs */
3193 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2));
3194 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3));
3198 pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3200 pic16_emitcode("mov","a,b");
3202 /* adjust the MSB if left or right neg */
3204 /* if one literal */
3205 if (AOP_TYPE(right) == AOP_LIT){
3206 pic16_emitcode("multiply ","right is a lit");
3207 /* AND literal negative */
3208 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3209 /* adjust MSB (c==0 after mul) */
3210 pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE));
3214 pic16_genSMult8X8_16 (left, right, result, NULL);
3218 pic16_emitcode("multiply ","size is greater than 2, so propogate sign");
3220 pic16_emitcode("rlc","a");
3221 pic16_emitcode("subb","a,acc");
3229 pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
3230 //pic16_aopPut(AOP(result),"a",offset++);
3234 /*-----------------------------------------------------------------*/
3235 /* genMult - generates code for multiplication */
3236 /*-----------------------------------------------------------------*/
3237 static void genMult (iCode *ic)
3239 operand *left = IC_LEFT(ic);
3240 operand *right = IC_RIGHT(ic);
3241 operand *result= IC_RESULT(ic);
3243 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3244 /* assign the amsops */
3245 pic16_aopOp (left,ic,FALSE);
3246 pic16_aopOp (right,ic,FALSE);
3247 pic16_aopOp (result,ic,TRUE);
3249 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3251 /* special cases first */
3253 if (AOP_TYPE(left) == AOP_CRY &&
3254 AOP_TYPE(right)== AOP_CRY) {
3255 genMultbits(left,right,result);
3259 /* if both are of size == 1 */
3260 if (AOP_SIZE(left) == 1 &&
3261 AOP_SIZE(right) == 1 ) {
3262 genMultOneByte(left,right,result);
3266 pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3268 /* should have been converted to function call */
3272 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3273 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3274 pic16_freeAsmop(result,NULL,ic,TRUE);
3277 /*-----------------------------------------------------------------*/
3278 /* genDivbits :- division of bits */
3279 /*-----------------------------------------------------------------*/
3280 static void genDivbits (operand *left,
3287 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3288 /* the result must be bit */
3289 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3290 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3294 pic16_emitcode("div","ab");
3295 pic16_emitcode("rrc","a");
3296 pic16_aopPut(AOP(result),"c",0);
3299 /*-----------------------------------------------------------------*/
3300 /* genDivOneByte : 8 bit division */
3301 /*-----------------------------------------------------------------*/
3302 static void genDivOneByte (operand *left,
3306 sym_link *opetype = operandType(result);
3311 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3312 size = AOP_SIZE(result) - 1;
3314 /* signed or unsigned */
3315 if (SPEC_USIGN(opetype)) {
3316 /* unsigned is easy */
3317 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3318 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3320 pic16_emitcode("div","ab");
3321 pic16_aopPut(AOP(result),"a",0);
3323 pic16_aopPut(AOP(result),zero,offset++);
3327 /* signed is a little bit more difficult */
3329 /* save the signs of the operands */
3330 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3332 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,TRUE));
3333 pic16_emitcode("push","acc"); /* save it on the stack */
3335 /* now sign adjust for both left & right */
3336 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3338 lbl = newiTempLabel(NULL);
3339 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3340 pic16_emitcode("cpl","a");
3341 pic16_emitcode("inc","a");
3342 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3343 pic16_emitcode("mov","b,a");
3345 /* sign adjust left side */
3346 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3349 lbl = newiTempLabel(NULL);
3350 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3351 pic16_emitcode("cpl","a");
3352 pic16_emitcode("inc","a");
3353 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3355 /* now the division */
3356 pic16_emitcode("div","ab");
3357 /* we are interested in the lower order
3359 pic16_emitcode("mov","b,a");
3360 lbl = newiTempLabel(NULL);
3361 pic16_emitcode("pop","acc");
3362 /* if there was an over flow we don't
3363 adjust the sign of the result */
3364 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3365 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3367 pic16_emitcode("clr","a");
3368 pic16_emitcode("subb","a,b");
3369 pic16_emitcode("mov","b,a");
3370 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3372 /* now we are done */
3373 pic16_aopPut(AOP(result),"b",0);
3375 pic16_emitcode("mov","c,b.7");
3376 pic16_emitcode("subb","a,acc");
3379 pic16_aopPut(AOP(result),"a",offset++);
3383 /*-----------------------------------------------------------------*/
3384 /* genDiv - generates code for division */
3385 /*-----------------------------------------------------------------*/
3386 static void genDiv (iCode *ic)
3388 operand *left = IC_LEFT(ic);
3389 operand *right = IC_RIGHT(ic);
3390 operand *result= IC_RESULT(ic);
3392 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3393 /* assign the amsops */
3394 pic16_aopOp (left,ic,FALSE);
3395 pic16_aopOp (right,ic,FALSE);
3396 pic16_aopOp (result,ic,TRUE);
3398 /* special cases first */
3400 if (AOP_TYPE(left) == AOP_CRY &&
3401 AOP_TYPE(right)== AOP_CRY) {
3402 genDivbits(left,right,result);
3406 /* if both are of size == 1 */
3407 if (AOP_SIZE(left) == 1 &&
3408 AOP_SIZE(right) == 1 ) {
3409 genDivOneByte(left,right,result);
3413 /* should have been converted to function call */
3416 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3417 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3418 pic16_freeAsmop(result,NULL,ic,TRUE);
3421 /*-----------------------------------------------------------------*/
3422 /* genModbits :- modulus of bits */
3423 /*-----------------------------------------------------------------*/
3424 static void genModbits (operand *left,
3431 /* the result must be bit */
3432 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3433 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3437 pic16_emitcode("div","ab");
3438 pic16_emitcode("mov","a,b");
3439 pic16_emitcode("rrc","a");
3440 pic16_aopPut(AOP(result),"c",0);
3443 /*-----------------------------------------------------------------*/
3444 /* genModOneByte : 8 bit modulus */
3445 /*-----------------------------------------------------------------*/
3446 static void genModOneByte (operand *left,
3450 sym_link *opetype = operandType(result);
3454 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3455 /* signed or unsigned */
3456 if (SPEC_USIGN(opetype)) {
3457 /* unsigned is easy */
3458 pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE));
3459 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3461 pic16_emitcode("div","ab");
3462 pic16_aopPut(AOP(result),"b",0);
3466 /* signed is a little bit more difficult */
3468 /* save the signs of the operands */
3469 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3472 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
3473 pic16_emitcode("push","acc"); /* save it on the stack */
3475 /* now sign adjust for both left & right */
3476 l = pic16_aopGet(AOP(right),0,FALSE,FALSE);
3479 lbl = newiTempLabel(NULL);
3480 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3481 pic16_emitcode("cpl","a");
3482 pic16_emitcode("inc","a");
3483 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3484 pic16_emitcode("mov","b,a");
3486 /* sign adjust left side */
3487 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
3490 lbl = newiTempLabel(NULL);
3491 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3492 pic16_emitcode("cpl","a");
3493 pic16_emitcode("inc","a");
3494 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3496 /* now the multiplication */
3497 pic16_emitcode("div","ab");
3498 /* we are interested in the lower order
3500 lbl = newiTempLabel(NULL);
3501 pic16_emitcode("pop","acc");
3502 /* if there was an over flow we don't
3503 adjust the sign of the result */
3504 pic16_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3505 pic16_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3507 pic16_emitcode("clr","a");
3508 pic16_emitcode("subb","a,b");
3509 pic16_emitcode("mov","b,a");
3510 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
3512 /* now we are done */
3513 pic16_aopPut(AOP(result),"b",0);
3517 /*-----------------------------------------------------------------*/
3518 /* genMod - generates code for division */
3519 /*-----------------------------------------------------------------*/
3520 static void genMod (iCode *ic)
3522 operand *left = IC_LEFT(ic);
3523 operand *right = IC_RIGHT(ic);
3524 operand *result= IC_RESULT(ic);
3526 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3527 /* assign the amsops */
3528 pic16_aopOp (left,ic,FALSE);
3529 pic16_aopOp (right,ic,FALSE);
3530 pic16_aopOp (result,ic,TRUE);
3532 /* special cases first */
3534 if (AOP_TYPE(left) == AOP_CRY &&
3535 AOP_TYPE(right)== AOP_CRY) {
3536 genModbits(left,right,result);
3540 /* if both are of size == 1 */
3541 if (AOP_SIZE(left) == 1 &&
3542 AOP_SIZE(right) == 1 ) {
3543 genModOneByte(left,right,result);
3547 /* should have been converted to function call */
3551 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3552 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3553 pic16_freeAsmop(result,NULL,ic,TRUE);
3556 /*-----------------------------------------------------------------*/
3557 /* genIfxJump :- will create a jump depending on the ifx */
3558 /*-----------------------------------------------------------------*/
3560 note: May need to add parameter to indicate when a variable is in bit space.
3562 static void genIfxJump (iCode *ic, char *jval)
3565 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3566 /* if true label then we jump if condition
3568 if ( IC_TRUE(ic) ) {
3570 if(strcmp(jval,"a") == 0)
3572 else if (strcmp(jval,"c") == 0)
3575 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3576 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1));
3579 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
3580 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3584 /* false label is present */
3585 if(strcmp(jval,"a") == 0)
3587 else if (strcmp(jval,"c") == 0)
3590 DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3591 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1));
3594 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
3595 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3600 /* mark the icode as generated */
3604 /*-----------------------------------------------------------------*/
3606 /*-----------------------------------------------------------------*/
3607 static void genSkip(iCode *ifx,int status_bit)
3612 if ( IC_TRUE(ifx) ) {
3613 switch(status_bit) {
3628 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3629 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3633 switch(status_bit) {
3647 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3648 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3654 /*-----------------------------------------------------------------*/
3656 /*-----------------------------------------------------------------*/
3657 static void genSkipc(resolvedIfx *rifx)
3667 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3668 rifx->generated = 1;
3671 /*-----------------------------------------------------------------*/
3673 /*-----------------------------------------------------------------*/
3674 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3679 if( (rifx->condition ^ invert_condition) & 1)
3684 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3685 rifx->generated = 1;
3688 /*-----------------------------------------------------------------*/
3690 /*-----------------------------------------------------------------*/
3691 static void genSkipz(iCode *ifx, int condition)
3702 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
3704 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
3707 pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3709 pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3712 /*-----------------------------------------------------------------*/
3714 /*-----------------------------------------------------------------*/
3715 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3721 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3723 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3726 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
3727 rifx->generated = 1;
3731 /*-----------------------------------------------------------------*/
3732 /* genChkZeroes :- greater or less than comparison */
3733 /* For each byte in a literal that is zero, inclusive or the */
3734 /* the corresponding byte in the operand with W */
3735 /* returns true if any of the bytes are zero */
3736 /*-----------------------------------------------------------------*/
3737 static int genChkZeroes(operand *op, int lit, int size)
3744 i = (lit >> (size*8)) & 0xff;
3748 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op),size));
3750 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(op),size));
3759 /*-----------------------------------------------------------------*/
3760 /* genCmp :- greater or less than comparison */
3761 /*-----------------------------------------------------------------*/
3762 static void genCmp (operand *left,operand *right,
3763 operand *result, iCode *ifx, int sign)
3765 int size; //, offset = 0 ;
3766 unsigned long lit = 0L,i = 0;
3767 resolvedIfx rFalseIfx;
3768 // resolvedIfx rTrueIfx;
3770 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3773 DEBUGpic16_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3774 DEBUGpic16_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3778 resolveIfx(&rFalseIfx,ifx);
3779 truelbl = newiTempLabel(NULL);
3780 size = max(AOP_SIZE(left),AOP_SIZE(right));
3782 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
3786 /* if literal is on the right then swap with left */
3787 if ((AOP_TYPE(right) == AOP_LIT)) {
3788 operand *tmp = right ;
3789 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3790 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3793 lit = (lit - 1) & mask;
3796 rFalseIfx.condition ^= 1;
3799 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3800 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3804 //if(IC_TRUE(ifx) == NULL)
3805 /* if left & right are bit variables */
3806 if (AOP_TYPE(left) == AOP_CRY &&
3807 AOP_TYPE(right) == AOP_CRY ) {
3808 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3809 pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3811 /* subtract right from left if at the
3812 end the carry flag is set then we know that
3813 left is greater than right */
3817 symbol *lbl = newiTempLabel(NULL);
3820 if(AOP_TYPE(right) == AOP_LIT) {
3822 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3824 DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3831 genSkipCond(&rFalseIfx,left,size-1,7);
3833 /* no need to compare to 0...*/
3834 /* NOTE: this is a de-generate compare that most certainly
3835 * creates some dead code. */
3836 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
3838 if(ifx) ifx->generated = 1;
3845 //i = (lit >> (size*8)) & 0xff;
3846 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3848 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3850 i = ((0-lit) & 0xff);
3853 /* lit is 0x7f, all signed chars are less than
3854 * this except for 0x7f itself */
3855 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
3856 genSkipz2(&rFalseIfx,0);
3858 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
3859 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i^0x80));
3860 genSkipc(&rFalseIfx);
3865 genSkipz2(&rFalseIfx,1);
3867 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(i));
3868 genSkipc(&rFalseIfx);
3872 if(ifx) ifx->generated = 1;
3876 /* chars are out of the way. now do ints and longs */
3879 DEBUGpic16_emitcode(";right lit","line = %d",__LINE__);
3886 genSkipCond(&rFalseIfx,left,size,7);
3887 if(ifx) ifx->generated = 1;
3892 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3894 //rFalseIfx.condition ^= 1;
3895 //genSkipCond(&rFalseIfx,left,size,7);
3896 //rFalseIfx.condition ^= 1;
3898 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3899 if(rFalseIfx.condition)
3900 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3902 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3904 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x100-lit));
3905 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3906 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
3909 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
3911 if(rFalseIfx.condition) {
3913 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3919 genSkipc(&rFalseIfx);
3920 pic16_emitpLabel(truelbl->key);
3921 if(ifx) ifx->generated = 1;
3928 if( (lit & 0xff) == 0) {
3929 /* lower byte is zero */
3930 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3931 i = ((lit >> 8) & 0xff) ^0x80;
3932 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3933 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3934 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3935 genSkipc(&rFalseIfx);
3938 if(ifx) ifx->generated = 1;
3943 /* Special cases for signed longs */
3944 if( (lit & 0xffffff) == 0) {
3945 /* lower byte is zero */
3946 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3947 i = ((lit >> 8*3) & 0xff) ^0x80;
3948 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
3949 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
3950 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
3951 genSkipc(&rFalseIfx);
3954 if(ifx) ifx->generated = 1;
3962 if(lit & (0x80 << (size*8))) {
3963 /* lit is negative */
3964 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3966 //genSkipCond(&rFalseIfx,left,size,7);
3968 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3970 if(rFalseIfx.condition)
3971 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3973 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3977 /* lit is positive */
3978 DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3979 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0));
3980 if(rFalseIfx.condition)
3981 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
3983 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
3988 This works, but is only good for ints.
3989 It also requires a "known zero" register.
3990 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
3991 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
3992 pic16_emitpcode(POC_RLCFW, pic16_popCopyReg(&pic16_pc_kzero));
3993 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
3994 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
3995 genSkipc(&rFalseIfx);
3997 pic16_emitpLabel(truelbl->key);
3998 if(ifx) ifx->generated = 1;
4002 /* There are no more special cases, so perform a general compare */
4004 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4005 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4009 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
4011 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4013 //rFalseIfx.condition ^= 1;
4014 genSkipc(&rFalseIfx);
4016 pic16_emitpLabel(truelbl->key);
4018 if(ifx) ifx->generated = 1;
4025 /* sign is out of the way. So now do an unsigned compare */
4026 DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4029 /* General case - compare to an unsigned literal on the right.*/
4031 i = (lit >> (size*8)) & 0xff;
4032 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4033 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4035 i = (lit >> (size*8)) & 0xff;
4038 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4040 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4042 /* this byte of the lit is zero,
4043 *if it's not the last then OR in the variable */
4045 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
4050 pic16_emitpLabel(lbl->key);
4051 //if(emitFinalCheck)
4052 genSkipc(&rFalseIfx);
4054 pic16_emitpLabel(truelbl->key);
4056 if(ifx) ifx->generated = 1;
4063 if(AOP_TYPE(left) == AOP_LIT) {
4064 //symbol *lbl = newiTempLabel(NULL);
4066 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4069 DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4072 if((lit == 0) && (sign == 0)){
4075 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4077 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
4079 genSkipz2(&rFalseIfx,0);
4080 if(ifx) ifx->generated = 1;
4087 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4088 /* degenerate compare can never be true */
4089 if(rFalseIfx.condition == 0)
4090 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
4092 if(ifx) ifx->generated = 1;
4097 /* signed comparisons to a literal byte */
4099 int lp1 = (lit+1) & 0xff;
4101 DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4104 rFalseIfx.condition ^= 1;
4105 genSkipCond(&rFalseIfx,right,0,7);
4108 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4109 pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
4110 genSkipz2(&rFalseIfx,1);
4113 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4114 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4115 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4116 rFalseIfx.condition ^= 1;
4117 genSkipc(&rFalseIfx);
4121 /* unsigned comparisons to a literal byte */
4123 switch(lit & 0xff ) {
4125 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4126 genSkipz2(&rFalseIfx,0);
4129 rFalseIfx.condition ^= 1;
4130 genSkipCond(&rFalseIfx,right,0,7);
4134 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
4135 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4136 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4137 rFalseIfx.condition ^= 1;
4138 if (AOP_TYPE(result) == AOP_CRY)
4139 genSkipc(&rFalseIfx);
4141 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4142 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4148 if(ifx) ifx->generated = 1;
4154 /* Size is greater than 1 */
4162 /* this means lit = 0xffffffff, or -1 */
4165 DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
4166 rFalseIfx.condition ^= 1;
4167 genSkipCond(&rFalseIfx,right,size,7);
4168 if(ifx) ifx->generated = 1;
4175 if(rFalseIfx.condition) {
4176 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4177 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4180 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4182 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4186 if(rFalseIfx.condition) {
4187 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4188 pic16_emitpLabel(truelbl->key);
4190 rFalseIfx.condition ^= 1;
4191 genSkipCond(&rFalseIfx,right,s,7);
4194 if(ifx) ifx->generated = 1;
4198 if((size == 1) && (0 == (lp1&0xff))) {
4199 /* lower byte of signed word is zero */
4200 DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4201 i = ((lp1 >> 8) & 0xff) ^0x80;
4202 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4203 pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
4204 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
4205 rFalseIfx.condition ^= 1;
4206 genSkipc(&rFalseIfx);
4209 if(ifx) ifx->generated = 1;
4213 if(lit & (0x80 << (size*8))) {
4214 /* Lit is less than zero */
4215 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4216 //rFalseIfx.condition ^= 1;
4217 //genSkipCond(&rFalseIfx,left,size,7);
4218 //rFalseIfx.condition ^= 1;
4219 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4220 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4222 if(rFalseIfx.condition)
4223 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4225 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4229 /* Lit is greater than or equal to zero */
4230 DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4231 //rFalseIfx.condition ^= 1;
4232 //genSkipCond(&rFalseIfx,right,size,7);
4233 //rFalseIfx.condition ^= 1;
4235 //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4236 //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4238 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
4239 if(rFalseIfx.condition)
4240 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4242 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4247 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4248 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4252 pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
4254 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4256 rFalseIfx.condition ^= 1;
4257 //rFalseIfx.condition = 1;
4258 genSkipc(&rFalseIfx);
4260 pic16_emitpLabel(truelbl->key);
4262 if(ifx) ifx->generated = 1;
4267 /* compare word or long to an unsigned literal on the right.*/
4272 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4275 break; /* handled above */
4278 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4280 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4281 genSkipz2(&rFalseIfx,0);
4285 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4287 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4290 if(rFalseIfx.condition)
4291 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
4293 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
4296 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
4297 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
4299 rFalseIfx.condition ^= 1;
4300 genSkipc(&rFalseIfx);
4303 pic16_emitpLabel(truelbl->key);
4305 if(ifx) ifx->generated = 1;
4311 DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4312 i = (lit >> (size*8)) & 0xff;
4314 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4315 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4318 i = (lit >> (size*8)) & 0xff;
4321 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
4323 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
4325 /* this byte of the lit is zero,
4326 *if it's not the last then OR in the variable */
4328 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
4333 pic16_emitpLabel(lbl->key);
4335 rFalseIfx.condition ^= 1;
4336 genSkipc(&rFalseIfx);
4340 pic16_emitpLabel(truelbl->key);
4341 if(ifx) ifx->generated = 1;
4345 /* Compare two variables */
4347 DEBUGpic16_emitcode(";sign","%d",sign);
4351 /* Sigh. thus sucks... */
4353 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
4354 pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
4355 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
4356 pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
4357 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
4358 pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
4360 /* Signed char comparison */
4361 /* Special thanks to Nikolai Golovchenko for this snippet */
4362 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
4363 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
4364 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
4365 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
4366 pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
4367 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
4369 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4370 genSkipc(&rFalseIfx);
4372 if(ifx) ifx->generated = 1;
4378 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4379 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4383 /* The rest of the bytes of a multi-byte compare */
4387 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
4390 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
4391 pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
4396 pic16_emitpLabel(lbl->key);
4398 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4399 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4400 (AOP_TYPE(result) == AOP_REG)) {
4401 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
4402 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
4404 genSkipc(&rFalseIfx);
4406 //genSkipc(&rFalseIfx);
4407 if(ifx) ifx->generated = 1;
4414 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4415 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4416 pic16_outBitC(result);
4418 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4419 /* if the result is used in the next
4420 ifx conditional branch then generate
4421 code a little differently */
4423 genIfxJump (ifx,"c");
4425 pic16_outBitC(result);
4426 /* leave the result in acc */
4431 /*-----------------------------------------------------------------*/
4432 /* genCmpGt :- greater than comparison */
4433 /*-----------------------------------------------------------------*/
4434 static void genCmpGt (iCode *ic, iCode *ifx)
4436 operand *left, *right, *result;
4437 sym_link *letype , *retype;
4440 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4442 right= IC_RIGHT(ic);
4443 result = IC_RESULT(ic);
4445 letype = getSpec(operandType(left));
4446 retype =getSpec(operandType(right));
4447 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4448 /* assign the amsops */
4449 pic16_aopOp (left,ic,FALSE);
4450 pic16_aopOp (right,ic,FALSE);
4451 pic16_aopOp (result,ic,TRUE);
4453 genCmp(right, left, result, ifx, sign);
4455 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4456 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4457 pic16_freeAsmop(result,NULL,ic,TRUE);
4460 /*-----------------------------------------------------------------*/
4461 /* genCmpLt - less than comparisons */
4462 /*-----------------------------------------------------------------*/
4463 static void genCmpLt (iCode *ic, iCode *ifx)
4465 operand *left, *right, *result;
4466 sym_link *letype , *retype;
4469 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4471 right= IC_RIGHT(ic);
4472 result = IC_RESULT(ic);
4474 letype = getSpec(operandType(left));
4475 retype =getSpec(operandType(right));
4476 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4478 /* assign the amsops */
4479 pic16_aopOp (left,ic,FALSE);
4480 pic16_aopOp (right,ic,FALSE);
4481 pic16_aopOp (result,ic,TRUE);
4483 genCmp(left, right, result, ifx, sign);
4485 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4486 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4487 pic16_freeAsmop(result,NULL,ic,TRUE);
4490 /*-----------------------------------------------------------------*/
4491 /* genc16bit2lit - compare a 16 bit value to a literal */
4492 /*-----------------------------------------------------------------*/
4493 static void genc16bit2lit(operand *op, int lit, int offset)
4497 DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4498 if( (lit&0xff) == 0)
4503 switch( BYTEofLONG(lit,i)) {
4505 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4508 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
4511 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
4514 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
4515 pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4520 switch( BYTEofLONG(lit,i)) {
4522 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
4526 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_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
4535 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
4541 /*-----------------------------------------------------------------*/
4542 /* gencjneshort - compare and jump if not equal */
4543 /*-----------------------------------------------------------------*/
4544 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4546 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4548 int res_offset = 0; /* the result may be a different size then left or right */
4549 int res_size = AOP_SIZE(result);
4553 unsigned long lit = 0L;
4554 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4555 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4557 DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4558 resolveIfx(&rIfx,ifx);
4559 lbl = newiTempLabel(NULL);
4562 /* if the left side is a literal or
4563 if the right is in a pointer register and left
4565 if ((AOP_TYPE(left) == AOP_LIT) ||
4566 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4571 if(AOP_TYPE(right) == AOP_LIT)
4572 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4574 /* if the right side is a literal then anything goes */
4575 if (AOP_TYPE(right) == AOP_LIT &&
4576 AOP_TYPE(left) != AOP_DIR ) {
4579 genc16bit2lit(left, lit, 0);
4581 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4586 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4587 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4589 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4593 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4595 if(res_offset < res_size-1)
4603 /* if the right side is in a register or in direct space or
4604 if the left is a pointer register & right is not */
4605 else if (AOP_TYPE(right) == AOP_REG ||
4606 AOP_TYPE(right) == AOP_DIR ||
4607 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4608 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4609 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4610 int lbl_key = lbl->key;
4613 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
4614 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4616 DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4617 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4618 __FUNCTION__,__LINE__);
4622 /* switch(size) { */
4624 /* genc16bit2lit(left, lit, 0); */
4626 /* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
4631 if((AOP_TYPE(left) == AOP_DIR) &&
4632 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4634 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4635 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4637 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4639 switch (lit & 0xff) {
4641 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4644 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4645 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4646 //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
4650 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4651 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4652 //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4653 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4657 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4658 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4663 pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
4666 if(AOP_TYPE(result) == AOP_CRY) {
4667 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4672 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4674 /* fix me. probably need to check result size too */
4675 //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
4680 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
4681 //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4688 if(res_offset < res_size-1)
4693 } else if(AOP_TYPE(right) == AOP_REG &&
4694 AOP_TYPE(left) != AOP_DIR){
4697 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4698 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4699 pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4704 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4706 if(res_offset < res_size-1)
4711 /* right is a pointer reg need both a & b */
4713 char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
4715 pic16_emitcode("mov","b,%s",l);
4716 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
4717 pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4722 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
4724 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
4726 pic16_emitpLabel(lbl->key);
4728 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4735 /*-----------------------------------------------------------------*/
4736 /* gencjne - compare and jump if not equal */
4737 /*-----------------------------------------------------------------*/
4738 static void gencjne(operand *left, operand *right, iCode *ifx)
4740 symbol *tlbl = newiTempLabel(NULL);
4742 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4743 gencjneshort(left, right, lbl);
4745 pic16_emitcode("mov","a,%s",one);
4746 pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4747 pic16_emitcode("","%05d_DS_:",lbl->key+100);
4748 pic16_emitcode("clr","a");
4749 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
4751 pic16_emitpLabel(lbl->key);
4752 pic16_emitpLabel(tlbl->key);
4757 /*-----------------------------------------------------------------*/
4758 /* genCmpEq - generates code for equal to */
4759 /*-----------------------------------------------------------------*/
4760 static void genCmpEq (iCode *ic, iCode *ifx)
4762 operand *left, *right, *result;
4763 unsigned long lit = 0L;
4766 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4769 DEBUGpic16_emitcode ("; ifx is non-null","");
4771 DEBUGpic16_emitcode ("; ifx is null","");
4773 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
4774 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4775 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
4777 size = max(AOP_SIZE(left),AOP_SIZE(right));
4779 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
4781 /* if literal, literal on the right or
4782 if the right is in a pointer register and left
4784 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4785 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4786 operand *tmp = right ;
4792 if(ifx && !AOP_SIZE(result)){
4794 /* if they are both bit variables */
4795 if (AOP_TYPE(left) == AOP_CRY &&
4796 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4797 if(AOP_TYPE(right) == AOP_LIT){
4798 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4800 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4801 pic16_emitcode("cpl","c");
4802 } else if(lit == 1L) {
4803 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4805 pic16_emitcode("clr","c");
4807 /* AOP_TYPE(right) == AOP_CRY */
4809 symbol *lbl = newiTempLabel(NULL);
4810 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4811 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4812 pic16_emitcode("cpl","c");
4813 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
4815 /* if true label then we jump if condition
4817 tlbl = newiTempLabel(NULL);
4818 if ( IC_TRUE(ifx) ) {
4819 pic16_emitcode("jnc","%05d_DS_",tlbl->key+100);
4820 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4822 pic16_emitcode("jc","%05d_DS_",tlbl->key+100);
4823 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4825 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4828 /* left and right are both bit variables, result is carry */
4831 resolveIfx(&rIfx,ifx);
4833 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0));
4834 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0));
4835 pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0));
4836 pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0));
4841 /* They're not both bit variables. Is the right a literal? */
4842 if(AOP_TYPE(right) == AOP_LIT) {
4843 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4848 switch(lit & 0xff) {
4850 if ( IC_TRUE(ifx) ) {
4851 pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset));
4853 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4855 pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
4856 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4860 if ( IC_TRUE(ifx) ) {
4861 pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset));
4863 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4865 pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
4866 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4870 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4872 pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
4877 /* end of size == 1 */
4881 genc16bit2lit(left,lit,offset);
4884 /* end of size == 2 */
4889 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
4890 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1));
4891 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4892 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4896 /* search for patterns that can be optimized */
4898 genc16bit2lit(left,lit,0);
4901 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4903 genc16bit2lit(left,lit,2);
4905 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2));
4906 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3));
4919 } else if(AOP_TYPE(right) == AOP_CRY ) {
4920 /* we know the left is not a bit, but that the right is */
4921 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4922 pic16_emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4923 pic16_popGet(AOP(right),offset));
4924 pic16_emitpcode(POC_XORLW,pic16_popGetLit(1));
4926 /* if the two are equal, then W will be 0 and the Z bit is set
4927 * we could test Z now, or go ahead and check the high order bytes if
4928 * the variable we're comparing is larger than a byte. */
4931 pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),offset));
4933 if ( IC_TRUE(ifx) ) {
4935 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4936 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4939 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4940 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4944 /* They're both variables that are larger than bits */
4947 tlbl = newiTempLabel(NULL);
4950 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
4951 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
4953 if ( IC_TRUE(ifx) ) {
4956 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
4957 pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4960 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
4961 pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4965 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
4966 pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4970 if(s>1 && IC_TRUE(ifx)) {
4971 pic16_emitpLabel(tlbl->key);
4972 pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4976 /* mark the icode as generated */
4981 /* if they are both bit variables */
4982 if (AOP_TYPE(left) == AOP_CRY &&
4983 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4984 if(AOP_TYPE(right) == AOP_LIT){
4985 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4987 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4988 pic16_emitcode("cpl","c");
4989 } else if(lit == 1L) {
4990 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4992 pic16_emitcode("clr","c");
4994 /* AOP_TYPE(right) == AOP_CRY */
4996 symbol *lbl = newiTempLabel(NULL);
4997 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4998 pic16_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4999 pic16_emitcode("cpl","c");
5000 pic16_emitcode("","%05d_DS_:",(lbl->key+100));
5003 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5004 pic16_outBitC(result);
5008 genIfxJump (ifx,"c");
5011 /* if the result is used in an arithmetic operation
5012 then put the result in place */
5013 pic16_outBitC(result);
5016 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5017 gencjne(left,right,result,ifx);
5020 gencjne(left,right,newiTempLabel(NULL));
5022 if(IC_TRUE(ifx)->key)
5023 gencjne(left,right,IC_TRUE(ifx)->key);
5025 gencjne(left,right,IC_FALSE(ifx)->key);
5029 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5030 pic16_aopPut(AOP(result),"a",0);
5035 genIfxJump (ifx,"a");
5039 /* if the result is used in an arithmetic operation
5040 then put the result in place */
5042 if (AOP_TYPE(result) != AOP_CRY)
5043 pic16_outAcc(result);
5045 /* leave the result in acc */
5049 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5050 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5051 pic16_freeAsmop(result,NULL,ic,TRUE);
5054 /*-----------------------------------------------------------------*/
5055 /* ifxForOp - returns the icode containing the ifx for operand */
5056 /*-----------------------------------------------------------------*/
5057 static iCode *ifxForOp ( operand *op, iCode *ic )
5059 /* if true symbol then needs to be assigned */
5060 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5061 if (IS_TRUE_SYMOP(op))
5064 /* if this has register type condition and
5065 the next instruction is ifx with the same operand
5066 and live to of the operand is upto the ifx only then */
5068 ic->next->op == IFX &&
5069 IC_COND(ic->next)->key == op->key &&
5070 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5074 ic->next->op == IFX &&
5075 IC_COND(ic->next)->key == op->key) {
5076 DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5080 DEBUGpic16_emitcode ("; NULL :(","%d",__LINE__);
5082 ic->next->op == IFX)
5083 DEBUGpic16_emitcode ("; ic-next"," is an IFX");
5086 ic->next->op == IFX &&
5087 IC_COND(ic->next)->key == op->key) {
5088 DEBUGpic16_emitcode ("; "," key is okay");
5089 DEBUGpic16_emitcode ("; "," key liveTo %d, next->seq = %d",
5090 OP_SYMBOL(op)->liveTo,
5097 /*-----------------------------------------------------------------*/
5098 /* genAndOp - for && operation */
5099 /*-----------------------------------------------------------------*/
5100 static void genAndOp (iCode *ic)
5102 operand *left,*right, *result;
5105 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5106 /* note here that && operations that are in an
5107 if statement are taken away by backPatchLabels
5108 only those used in arthmetic operations remain */
5109 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5110 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5111 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5113 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5115 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
5116 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),0));
5117 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
5119 /* if both are bit variables */
5120 /* if (AOP_TYPE(left) == AOP_CRY && */
5121 /* AOP_TYPE(right) == AOP_CRY ) { */
5122 /* pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5123 /* pic16_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5124 /* pic16_outBitC(result); */
5126 /* tlbl = newiTempLabel(NULL); */
5127 /* pic16_toBoolean(left); */
5128 /* pic16_emitcode("jz","%05d_DS_",tlbl->key+100); */
5129 /* pic16_toBoolean(right); */
5130 /* pic16_emitcode("","%05d_DS_:",tlbl->key+100); */
5131 /* pic16_outBitAcc(result); */
5134 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5135 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5136 pic16_freeAsmop(result,NULL,ic,TRUE);
5140 /*-----------------------------------------------------------------*/
5141 /* genOrOp - for || operation */
5142 /*-----------------------------------------------------------------*/
5145 modified this code, but it doesn't appear to ever get called
5148 static void genOrOp (iCode *ic)
5150 operand *left,*right, *result;
5153 /* note here that || operations that are in an
5154 if statement are taken away by backPatchLabels
5155 only those used in arthmetic operations remain */
5156 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5157 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
5158 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5159 pic16_aopOp((result=IC_RESULT(ic)),ic,FALSE);
5161 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5163 /* if both are bit variables */
5164 if (AOP_TYPE(left) == AOP_CRY &&
5165 AOP_TYPE(right) == AOP_CRY ) {
5166 pic16_emitcode("clrc","");
5167 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5168 AOP(left)->aopu.aop_dir,
5169 AOP(left)->aopu.aop_dir);
5170 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5171 AOP(right)->aopu.aop_dir,
5172 AOP(right)->aopu.aop_dir);
5173 pic16_emitcode("setc","");
5176 tlbl = newiTempLabel(NULL);
5177 pic16_toBoolean(left);
5179 pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5180 pic16_toBoolean(right);
5181 pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5183 pic16_outBitAcc(result);
5186 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5187 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5188 pic16_freeAsmop(result,NULL,ic,TRUE);
5191 /*-----------------------------------------------------------------*/
5192 /* isLiteralBit - test if lit == 2^n */
5193 /*-----------------------------------------------------------------*/
5194 static int isLiteralBit(unsigned long lit)
5196 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5197 0x100L,0x200L,0x400L,0x800L,
5198 0x1000L,0x2000L,0x4000L,0x8000L,
5199 0x10000L,0x20000L,0x40000L,0x80000L,
5200 0x100000L,0x200000L,0x400000L,0x800000L,
5201 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5202 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5205 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5206 for(idx = 0; idx < 32; idx++)
5212 /*-----------------------------------------------------------------*/
5213 /* continueIfTrue - */
5214 /*-----------------------------------------------------------------*/
5215 static void continueIfTrue (iCode *ic)
5217 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5219 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5223 /*-----------------------------------------------------------------*/
5225 /*-----------------------------------------------------------------*/
5226 static void jumpIfTrue (iCode *ic)
5228 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5230 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5234 /*-----------------------------------------------------------------*/
5235 /* jmpTrueOrFalse - */
5236 /*-----------------------------------------------------------------*/
5237 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5239 // ugly but optimized by peephole
5240 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5242 symbol *nlbl = newiTempLabel(NULL);
5243 pic16_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5244 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5245 pic16_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5246 pic16_emitcode("","%05d_DS_:",nlbl->key+100);
5249 pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5250 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5255 /*-----------------------------------------------------------------*/
5256 /* genAnd - code for and */
5257 /*-----------------------------------------------------------------*/
5258 static void genAnd (iCode *ic, iCode *ifx)
5260 operand *left, *right, *result;
5262 unsigned long lit = 0L;
5267 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5268 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5269 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5270 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5272 resolveIfx(&rIfx,ifx);
5274 /* if left is a literal & right is not then exchange them */
5275 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5276 AOP_NEEDSACC(left)) {
5277 operand *tmp = right ;
5282 /* if result = right then exchange them */
5283 if(pic16_sameRegs(AOP(result),AOP(right))){
5284 operand *tmp = right ;
5289 /* if right is bit then exchange them */
5290 if (AOP_TYPE(right) == AOP_CRY &&
5291 AOP_TYPE(left) != AOP_CRY){
5292 operand *tmp = right ;
5296 if(AOP_TYPE(right) == AOP_LIT)
5297 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5299 size = AOP_SIZE(result);
5301 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5304 // result = bit & yy;
5305 if (AOP_TYPE(left) == AOP_CRY){
5306 // c = bit & literal;
5307 if(AOP_TYPE(right) == AOP_LIT){
5309 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5312 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5315 if(size && (AOP_TYPE(result) == AOP_CRY)){
5316 pic16_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5319 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5323 pic16_emitcode("clr","c");
5326 if (AOP_TYPE(right) == AOP_CRY){
5328 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5329 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5332 MOVA(pic16_aopGet(AOP(right),0,FALSE,FALSE));
5334 pic16_emitcode("rrc","a");
5335 pic16_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5341 pic16_outBitC(result);
5343 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5344 genIfxJump(ifx, "c");
5348 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5349 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5350 if((AOP_TYPE(right) == AOP_LIT) &&
5351 (AOP_TYPE(result) == AOP_CRY) &&
5352 (AOP_TYPE(left) != AOP_CRY)){
5353 int posbit = isLiteralBit(lit);
5357 //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5360 pic16_emitcode("mov","c,acc.%d",posbit&0x07);
5366 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5367 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key));
5369 pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5370 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key));
5373 pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5374 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5375 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
5382 symbol *tlbl = newiTempLabel(NULL);
5383 int sizel = AOP_SIZE(left);
5385 pic16_emitcode("setb","c");
5387 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5388 MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5390 if((posbit = isLiteralBit(bytelit)) != 0)
5391 pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5393 if(bytelit != 0x0FFL)
5394 pic16_emitcode("anl","a,%s",
5395 pic16_aopGet(AOP(right),offset,FALSE,TRUE));
5396 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5401 // bit = left & literal
5403 pic16_emitcode("clr","c");
5404 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5406 // if(left & literal)
5409 jmpTrueOrFalse(ifx, tlbl);
5413 pic16_outBitC(result);
5417 /* if left is same as result */
5418 if(pic16_sameRegs(AOP(result),AOP(left))){
5420 for(;size--; offset++,lit>>=8) {
5421 if(AOP_TYPE(right) == AOP_LIT){
5422 switch(lit & 0xff) {
5424 /* and'ing with 0 has clears the result */
5425 // pic16_emitcode("clrf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5426 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5429 /* and'ing with 0xff is a nop when the result and left are the same */
5434 int p = my_powof2( (~lit) & 0xff );
5436 /* only one bit is set in the literal, so use a bcf instruction */
5437 // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p);
5438 pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5441 pic16_emitcode("movlw","0x%x", (lit & 0xff));
5442 pic16_emitcode("andwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5443 if(know_W != (lit&0xff))
5444 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5446 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5451 if (AOP_TYPE(left) == AOP_ACC) {
5452 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5454 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5455 pic16_emitpcode(POC_ANDWF,pic16_popGet(AOP(left),offset));
5462 // left & result in different registers
5463 if(AOP_TYPE(result) == AOP_CRY){
5465 // if(size), result in bit
5466 // if(!size && ifx), conditional oper: if(left & right)
5467 symbol *tlbl = newiTempLabel(NULL);
5468 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5470 pic16_emitcode("setb","c");
5472 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5473 pic16_emitcode("anl","a,%s",
5474 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5475 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5480 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5481 pic16_outBitC(result);
5483 jmpTrueOrFalse(ifx, tlbl);
5485 for(;(size--);offset++) {
5487 // result = left & right
5488 if(AOP_TYPE(right) == AOP_LIT){
5489 int t = (lit >> (offset*8)) & 0x0FFL;
5492 pic16_emitcode("clrf","%s",
5493 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5494 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
5497 pic16_emitcode("movf","%s,w",
5498 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5499 pic16_emitcode("movwf","%s",
5500 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5501 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
5502 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5505 pic16_emitcode("movlw","0x%x",t);
5506 pic16_emitcode("andwf","%s,w",
5507 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5508 pic16_emitcode("movwf","%s",
5509 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5511 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5512 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5513 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5518 if (AOP_TYPE(left) == AOP_ACC) {
5519 pic16_emitcode("andwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5520 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(right),offset));
5522 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5523 pic16_emitcode("andwf","%s,w",
5524 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5525 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5526 pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),offset));
5528 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5529 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
5535 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5536 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5537 pic16_freeAsmop(result,NULL,ic,TRUE);
5540 /*-----------------------------------------------------------------*/
5541 /* genOr - code for or */
5542 /*-----------------------------------------------------------------*/
5543 static void genOr (iCode *ic, iCode *ifx)
5545 operand *left, *right, *result;
5547 unsigned long lit = 0L;
5549 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5551 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5552 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5553 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5555 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5557 /* if left is a literal & right is not then exchange them */
5558 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5559 AOP_NEEDSACC(left)) {
5560 operand *tmp = right ;
5565 /* if result = right then exchange them */
5566 if(pic16_sameRegs(AOP(result),AOP(right))){
5567 operand *tmp = right ;
5572 /* if right is bit then exchange them */
5573 if (AOP_TYPE(right) == AOP_CRY &&
5574 AOP_TYPE(left) != AOP_CRY){
5575 operand *tmp = right ;
5580 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
5582 if(AOP_TYPE(right) == AOP_LIT)
5583 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5585 size = AOP_SIZE(result);
5589 if (AOP_TYPE(left) == AOP_CRY){
5590 if(AOP_TYPE(right) == AOP_LIT){
5591 // c = bit & literal;
5593 // lit != 0 => result = 1
5594 if(AOP_TYPE(result) == AOP_CRY){
5596 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5597 //pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5598 // AOP(result)->aopu.aop_dir,
5599 // AOP(result)->aopu.aop_dir);
5601 continueIfTrue(ifx);
5605 // lit == 0 => result = left
5606 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5608 pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5611 if (AOP_TYPE(right) == AOP_CRY){
5612 if(pic16_sameRegs(AOP(result),AOP(left))){
5614 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5615 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
5616 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5618 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5619 AOP(result)->aopu.aop_dir,
5620 AOP(result)->aopu.aop_dir);
5621 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5622 AOP(right)->aopu.aop_dir,
5623 AOP(right)->aopu.aop_dir);
5624 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5625 AOP(result)->aopu.aop_dir,
5626 AOP(result)->aopu.aop_dir);
5628 if( AOP_TYPE(result) == AOP_ACC) {
5629 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
5630 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5631 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5632 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1));
5636 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5637 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
5638 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5639 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5641 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
5642 AOP(result)->aopu.aop_dir,
5643 AOP(result)->aopu.aop_dir);
5644 pic16_emitcode("btfss","(%s >> 3), (%s & 7)",
5645 AOP(right)->aopu.aop_dir,
5646 AOP(right)->aopu.aop_dir);
5647 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
5648 AOP(left)->aopu.aop_dir,
5649 AOP(left)->aopu.aop_dir);
5650 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
5651 AOP(result)->aopu.aop_dir,
5652 AOP(result)->aopu.aop_dir);
5657 symbol *tlbl = newiTempLabel(NULL);
5658 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5661 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
5662 if( AOP_TYPE(right) == AOP_ACC) {
5663 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0));
5665 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0));
5666 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
5671 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5672 pic16_emitcode(";XXX setb","c");
5673 pic16_emitcode(";XXX jb","%s,%05d_DS_",
5674 AOP(left)->aopu.aop_dir,tlbl->key+100);
5675 pic16_toBoolean(right);
5676 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5677 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5678 jmpTrueOrFalse(ifx, tlbl);
5682 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5689 pic16_outBitC(result);
5691 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5692 genIfxJump(ifx, "c");
5696 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5697 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5698 if((AOP_TYPE(right) == AOP_LIT) &&
5699 (AOP_TYPE(result) == AOP_CRY) &&
5700 (AOP_TYPE(left) != AOP_CRY)){
5702 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5705 pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5707 continueIfTrue(ifx);
5710 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5711 // lit = 0, result = boolean(left)
5713 pic16_emitcode(";XXX setb","c");
5714 pic16_toBoolean(right);
5716 symbol *tlbl = newiTempLabel(NULL);
5717 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5719 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5721 genIfxJump (ifx,"a");
5725 pic16_outBitC(result);
5729 /* if left is same as result */
5730 if(pic16_sameRegs(AOP(result),AOP(left))){
5732 for(;size--; offset++,lit>>=8) {
5733 if(AOP_TYPE(right) == AOP_LIT){
5734 if((lit & 0xff) == 0)
5735 /* or'ing with 0 has no effect */
5738 int p = my_powof2(lit & 0xff);
5740 /* only one bit is set in the literal, so use a bsf instruction */
5741 pic16_emitpcode(POC_BSF,
5742 pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5744 if(know_W != (lit & 0xff))
5745 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff));
5746 know_W = lit & 0xff;
5747 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5752 if (AOP_TYPE(left) == AOP_ACC) {
5753 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset));
5754 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5756 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5757 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset));
5759 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5760 pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5766 // left & result in different registers
5767 if(AOP_TYPE(result) == AOP_CRY){
5769 // if(size), result in bit
5770 // if(!size && ifx), conditional oper: if(left | right)
5771 symbol *tlbl = newiTempLabel(NULL);
5772 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5773 pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5777 pic16_emitcode(";XXX setb","c");
5779 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5780 pic16_emitcode(";XXX orl","a,%s",
5781 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5782 pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5787 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
5788 pic16_outBitC(result);
5790 jmpTrueOrFalse(ifx, tlbl);
5791 } else for(;(size--);offset++){
5793 // result = left & right
5794 if(AOP_TYPE(right) == AOP_LIT){
5795 int t = (lit >> (offset*8)) & 0x0FFL;
5798 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
5799 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5801 pic16_emitcode("movf","%s,w",
5802 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5803 pic16_emitcode("movwf","%s",
5804 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5807 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5808 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5809 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5811 pic16_emitcode("movlw","0x%x",t);
5812 pic16_emitcode("iorwf","%s,w",
5813 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5814 pic16_emitcode("movwf","%s",
5815 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5821 // faster than result <- left, anl result,right
5822 // and better if result is SFR
5823 if (AOP_TYPE(left) == AOP_ACC) {
5824 pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset));
5825 pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5827 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
5828 pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset));
5830 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5831 pic16_emitcode("iorwf","%s,w",
5832 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
5834 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
5835 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
5840 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5841 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5842 pic16_freeAsmop(result,NULL,ic,TRUE);
5845 /*-----------------------------------------------------------------*/
5846 /* genXor - code for xclusive or */
5847 /*-----------------------------------------------------------------*/
5848 static void genXor (iCode *ic, iCode *ifx)
5850 operand *left, *right, *result;
5852 unsigned long lit = 0L;
5854 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5856 pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE);
5857 pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5858 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
5860 /* if left is a literal & right is not ||
5861 if left needs acc & right does not */
5862 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5863 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5864 operand *tmp = right ;
5869 /* if result = right then exchange them */
5870 if(pic16_sameRegs(AOP(result),AOP(right))){
5871 operand *tmp = right ;
5876 /* if right is bit then exchange them */
5877 if (AOP_TYPE(right) == AOP_CRY &&
5878 AOP_TYPE(left) != AOP_CRY){
5879 operand *tmp = right ;
5883 if(AOP_TYPE(right) == AOP_LIT)
5884 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5886 size = AOP_SIZE(result);
5890 if (AOP_TYPE(left) == AOP_CRY){
5891 if(AOP_TYPE(right) == AOP_LIT){
5892 // c = bit & literal;
5894 // lit>>1 != 0 => result = 1
5895 if(AOP_TYPE(result) == AOP_CRY){
5897 {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset));
5898 pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5900 continueIfTrue(ifx);
5903 pic16_emitcode("setb","c");
5907 // lit == 0, result = left
5908 if(size && pic16_sameRegs(AOP(result),AOP(left)))
5910 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5912 // lit == 1, result = not(left)
5913 if(size && pic16_sameRegs(AOP(result),AOP(left))){
5914 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset));
5915 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset));
5916 pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5919 pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5920 pic16_emitcode("cpl","c");
5927 symbol *tlbl = newiTempLabel(NULL);
5928 if (AOP_TYPE(right) == AOP_CRY){
5930 pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5933 int sizer = AOP_SIZE(right);
5935 // if val>>1 != 0, result = 1
5936 pic16_emitcode("setb","c");
5938 MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE));
5940 // test the msb of the lsb
5941 pic16_emitcode("anl","a,#0xfe");
5942 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
5946 pic16_emitcode("rrc","a");
5948 pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5949 pic16_emitcode("cpl","c");
5950 pic16_emitcode("","%05d_DS_:",(tlbl->key+100));
5955 pic16_outBitC(result);
5957 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5958 genIfxJump(ifx, "c");
5962 if(pic16_sameRegs(AOP(result),AOP(left))){
5963 /* if left is same as result */
5964 for(;size--; offset++) {
5965 if(AOP_TYPE(right) == AOP_LIT){
5966 int t = (lit >> (offset*8)) & 0x0FFL;
5970 if (IS_AOP_PREG(left)) {
5971 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5972 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5973 pic16_aopPut(AOP(result),"a",offset);
5975 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
5976 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5977 pic16_emitcode("xrl","%s,%s",
5978 pic16_aopGet(AOP(left),offset,FALSE,TRUE),
5979 pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5982 if (AOP_TYPE(left) == AOP_ACC)
5983 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
5985 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
5986 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset));
5988 if (IS_AOP_PREG(left)) {
5989 pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5990 pic16_aopPut(AOP(result),"a",offset);
5992 pic16_emitcode("xrl","%s,a",
5993 pic16_aopGet(AOP(left),offset,FALSE,TRUE));
5999 // left & result in different registers
6000 if(AOP_TYPE(result) == AOP_CRY){
6002 // if(size), result in bit
6003 // if(!size && ifx), conditional oper: if(left ^ right)
6004 symbol *tlbl = newiTempLabel(NULL);
6005 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6007 pic16_emitcode("setb","c");
6009 if((AOP_TYPE(right) == AOP_LIT) &&
6010 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6011 MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6013 MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6014 pic16_emitcode("xrl","a,%s",
6015 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6017 pic16_emitcode("jnz","%05d_DS_",tlbl->key+100);
6022 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6023 pic16_outBitC(result);
6025 jmpTrueOrFalse(ifx, tlbl);
6026 } else for(;(size--);offset++){
6028 // result = left & right
6029 if(AOP_TYPE(right) == AOP_LIT){
6030 int t = (lit >> (offset*8)) & 0x0FFL;
6033 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
6034 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6035 pic16_emitcode("movf","%s,w",
6036 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6037 pic16_emitcode("movwf","%s",
6038 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6041 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset));
6042 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6043 pic16_emitcode("comf","%s,w",
6044 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6045 pic16_emitcode("movwf","%s",
6046 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6049 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t));
6050 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6051 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6052 pic16_emitcode("movlw","0x%x",t);
6053 pic16_emitcode("xorwf","%s,w",
6054 pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6055 pic16_emitcode("movwf","%s",
6056 pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6062 // faster than result <- left, anl result,right
6063 // and better if result is SFR
6064 if (AOP_TYPE(left) == AOP_ACC) {
6065 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
6066 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6068 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset));
6069 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset));
6070 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
6071 pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
6073 if ( AOP_TYPE(result) != AOP_ACC){
6074 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset));
6075 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE));
6081 pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6082 pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6083 pic16_freeAsmop(result,NULL,ic,TRUE);
6086 /*-----------------------------------------------------------------*/
6087 /* genInline - write the inline code out */
6088 /*-----------------------------------------------------------------*/
6089 static void genInline (iCode *ic)
6091 char *buffer, *bp, *bp1;
6093 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6095 _G.inLine += (!options.asmpeep);
6097 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6098 strcpy(buffer,IC_INLINE(ic));
6100 /* emit each line as a code */
6106 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6113 pic16_emitcode(bp1,"");
6119 if ((bp1 != bp) && *bp1)
6120 pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
6124 _G.inLine -= (!options.asmpeep);
6127 /*-----------------------------------------------------------------*/
6128 /* genRRC - rotate right with carry */
6129 /*-----------------------------------------------------------------*/
6130 static void genRRC (iCode *ic)
6132 operand *left , *result ;
6133 int size, offset = 0, same;
6135 /* rotate right with carry */
6137 result=IC_RESULT(ic);
6138 pic16_aopOp (left,ic,FALSE);
6139 pic16_aopOp (result,ic,FALSE);
6141 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6143 same = pic16_sameRegs(AOP(result),AOP(left));
6145 size = AOP_SIZE(result);
6147 /* get the lsb and put it into the carry */
6148 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1));
6155 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(left),offset));
6157 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offset));
6158 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6164 pic16_freeAsmop(left,NULL,ic,TRUE);
6165 pic16_freeAsmop(result,NULL,ic,TRUE);
6168 /*-----------------------------------------------------------------*/
6169 /* genRLC - generate code for rotate left with carry */
6170 /*-----------------------------------------------------------------*/
6171 static void genRLC (iCode *ic)
6173 operand *left , *result ;
6174 int size, offset = 0;
6177 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6178 /* rotate right with carry */
6180 result=IC_RESULT(ic);
6181 pic16_aopOp (left,ic,FALSE);
6182 pic16_aopOp (result,ic,FALSE);
6184 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
6186 same = pic16_sameRegs(AOP(result),AOP(left));
6188 /* move it to the result */
6189 size = AOP_SIZE(result);
6191 /* get the msb and put it into the carry */
6192 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),size-1));
6199 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),offset));
6201 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offset));
6202 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
6209 pic16_freeAsmop(left,NULL,ic,TRUE);
6210 pic16_freeAsmop(result,NULL,ic,TRUE);
6213 /*-----------------------------------------------------------------*/
6214 /* genGetHbit - generates code get highest order bit */
6215 /*-----------------------------------------------------------------*/
6216 static void genGetHbit (iCode *ic)
6218 operand *left, *result;
6220 result=IC_RESULT(ic);
6221 pic16_aopOp (left,ic,FALSE);
6222 pic16_aopOp (result,ic,FALSE);
6224 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6225 /* get the highest order byte into a */
6226 MOVA(pic16_aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6227 if(AOP_TYPE(result) == AOP_CRY){
6228 pic16_emitcode("rlc","a");
6229 pic16_outBitC(result);
6232 pic16_emitcode("rl","a");
6233 pic16_emitcode("anl","a,#0x01");
6234 pic16_outAcc(result);
6238 pic16_freeAsmop(left,NULL,ic,TRUE);
6239 pic16_freeAsmop(result,NULL,ic,TRUE);
6242 /*-----------------------------------------------------------------*/
6243 /* AccRol - rotate left accumulator by known count */
6244 /*-----------------------------------------------------------------*/
6245 static void AccRol (int shCount)
6247 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6248 shCount &= 0x0007; // shCount : 0..7
6253 pic16_emitcode("rl","a");
6256 pic16_emitcode("rl","a");
6257 pic16_emitcode("rl","a");
6260 pic16_emitcode("swap","a");
6261 pic16_emitcode("rr","a");
6264 pic16_emitcode("swap","a");
6267 pic16_emitcode("swap","a");
6268 pic16_emitcode("rl","a");
6271 pic16_emitcode("rr","a");
6272 pic16_emitcode("rr","a");
6275 pic16_emitcode("rr","a");
6280 /*-----------------------------------------------------------------*/
6281 /* AccLsh - left shift accumulator by known count */
6282 /*-----------------------------------------------------------------*/
6283 static void AccLsh (int shCount)
6285 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6288 pic16_emitcode("add","a,acc");
6291 pic16_emitcode("add","a,acc");
6292 pic16_emitcode("add","a,acc");
6294 /* rotate left accumulator */
6296 /* and kill the lower order bits */
6297 pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6302 /*-----------------------------------------------------------------*/
6303 /* AccRsh - right shift accumulator by known count */
6304 /*-----------------------------------------------------------------*/
6305 static void AccRsh (int shCount)
6307 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6311 pic16_emitcode("rrc","a");
6313 /* rotate right accumulator */
6314 AccRol(8 - shCount);
6315 /* and kill the higher order bits */
6316 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6322 /*-----------------------------------------------------------------*/
6323 /* AccSRsh - signed right shift accumulator by known count */
6324 /*-----------------------------------------------------------------*/
6325 static void AccSRsh (int shCount)
6328 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6331 pic16_emitcode("mov","c,acc.7");
6332 pic16_emitcode("rrc","a");
6333 } else if(shCount == 2){
6334 pic16_emitcode("mov","c,acc.7");
6335 pic16_emitcode("rrc","a");
6336 pic16_emitcode("mov","c,acc.7");
6337 pic16_emitcode("rrc","a");
6339 tlbl = newiTempLabel(NULL);
6340 /* rotate right accumulator */
6341 AccRol(8 - shCount);
6342 /* and kill the higher order bits */
6343 pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6344 pic16_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6345 pic16_emitcode("orl","a,#0x%02x",
6346 (unsigned char)~SRMask[shCount]);
6347 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
6352 /*-----------------------------------------------------------------*/
6353 /* shiftR1Left2Result - shift right one byte from left to result */
6354 /*-----------------------------------------------------------------*/
6355 static void shiftR1Left2ResultSigned (operand *left, int offl,
6356 operand *result, int offr,
6361 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6363 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6367 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6369 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6371 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6372 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6378 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6380 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6382 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6383 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6385 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6386 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6392 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6394 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6395 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6398 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6399 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6400 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6402 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6403 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0));
6405 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6409 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6410 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6411 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6412 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0));
6413 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6417 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6419 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6420 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6422 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6423 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07));
6424 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6425 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8));
6426 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6431 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6432 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6433 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe));
6434 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6435 pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01));
6436 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6438 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6439 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6440 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6441 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6442 pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6448 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00));
6449 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6450 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
6451 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6453 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6454 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6455 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr));
6463 /*-----------------------------------------------------------------*/
6464 /* shiftR1Left2Result - shift right one byte from left to result */
6465 /*-----------------------------------------------------------------*/
6466 static void shiftR1Left2Result (operand *left, int offl,
6467 operand *result, int offr,
6468 int shCount, int sign)
6472 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6474 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6476 /* Copy the msb into the carry if signed. */
6478 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6488 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6490 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6491 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6497 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6499 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6500 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6503 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6508 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6510 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6511 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6514 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6515 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6516 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f));
6517 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6521 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6522 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6523 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6527 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl));
6528 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6529 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6531 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6536 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6537 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80));
6538 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6539 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6540 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6545 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6546 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6547 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6556 /*-----------------------------------------------------------------*/
6557 /* shiftL1Left2Result - shift left one byte from left to result */
6558 /*-----------------------------------------------------------------*/
6559 static void shiftL1Left2Result (operand *left, int offl,
6560 operand *result, int offr, int shCount)
6565 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6567 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6568 DEBUGpic16_emitcode ("; ***","same = %d",same);
6569 // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6571 /* shift left accumulator */
6572 //AccLsh(shCount); // don't comment out just yet...
6573 // pic16_aopPut(AOP(result),"a",offr);
6577 /* Shift left 1 bit position */
6578 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6580 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),offl));
6582 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offl));
6583 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6587 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6588 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x7e));
6589 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6590 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6593 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6594 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x3e));
6595 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6596 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6597 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6600 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6601 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6602 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6605 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6606 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6607 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6608 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6611 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6612 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x30));
6613 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6614 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6615 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6618 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6619 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6620 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6624 DEBUGpic16_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6629 /*-----------------------------------------------------------------*/
6630 /* movLeft2Result - move byte from left to result */
6631 /*-----------------------------------------------------------------*/
6632 static void movLeft2Result (operand *left, int offl,
6633 operand *result, int offr)
6636 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6637 if(!pic16_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6638 l = pic16_aopGet(AOP(left),offl,FALSE,FALSE);
6640 if (*l == '@' && (IS_AOP_PREG(result))) {
6641 pic16_emitcode("mov","a,%s",l);
6642 pic16_aopPut(AOP(result),"a",offr);
6644 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6645 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6650 /*-----------------------------------------------------------------*/
6651 /* shiftL2Left2Result - shift left two bytes from left to result */
6652 /*-----------------------------------------------------------------*/
6653 static void shiftL2Left2Result (operand *left, int offl,
6654 operand *result, int offr, int shCount)
6658 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6660 if(pic16_sameRegs(AOP(result), AOP(left))) {
6668 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offr));
6669 pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),offr));
6670 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6674 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6675 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6681 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0f));
6682 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr+MSB16));
6683 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6684 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6685 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr));
6686 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6687 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6689 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6690 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6694 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6695 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6696 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6697 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6698 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6699 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6700 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6701 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6702 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6703 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6706 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6707 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr));
6708 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6709 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6710 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6720 /* note, use a mov/add for the shift since the mov has a
6721 chance of getting optimized out */
6722 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offl));
6723 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6724 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6725 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6726 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6730 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6731 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6737 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6738 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6739 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6740 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6741 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6742 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0));
6743 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr));
6744 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6748 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6749 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6753 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6754 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6755 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offl));
6756 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6758 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6759 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6760 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr+MSB16));
6761 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0xc0));
6762 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6763 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr));
6764 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr));
6765 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6768 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6769 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6770 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6771 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr));
6772 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6777 /*-----------------------------------------------------------------*/
6778 /* shiftR2Left2Result - shift right two bytes from left to result */
6779 /*-----------------------------------------------------------------*/
6780 static void shiftR2Left2Result (operand *left, int offl,
6781 operand *result, int offr,
6782 int shCount, int sign)
6786 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6787 same = pic16_sameRegs(AOP(result), AOP(left));
6789 if(same && ((offl + MSB16) == offr)){
6791 /* don't crash result[offr] */
6792 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6793 pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6796 movLeft2Result(left,offl, result, offr);
6797 MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6800 /* a:x >> shCount (x = lsb(result))*/
6803 AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6805 AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6814 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6819 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6820 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6822 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl+MSB16));
6823 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6824 pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),offl));
6825 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6830 pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16));
6833 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16));
6834 pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr));
6841 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0));
6842 pic16_emitpcode(POC_ANDWF, pic16_popGet(AOP(result),offr));
6843 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr));
6845 pic16_emitpcode(POC_SWAPF, pic16_popGet(AOP(result),offr+MSB16));
6846 pic16_emitpcode(POC_ANDFW, pic16_popGet(AOP(result),offr+MSB16));
6847 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6848 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6850 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl));
6851 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f));
6852 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr));
6854 pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl+MSB16));
6855 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16));
6856 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
6857 pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr+MSB16));
6858 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr));
6862 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr+MSB16));
6863 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr));
6867 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 ));
6868 pic16_emitpcode(POC_BTFSC,
6869 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6870 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16));
6878 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6879 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6881 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6882 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6883 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr));
6884 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6886 pic16_emitpcode(POC_BTFSC,
6887 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6888 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6890 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6891 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(result),offr+MSB16));
6892 pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16));
6893 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6895 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6896 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6897 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6898 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6899 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6900 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6901 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr+MSB16));
6902 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03));
6904 pic16_emitpcode(POC_BTFSC,
6905 pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6906 pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc));
6908 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16));
6909 //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr));
6916 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl));
6917 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl+MSB16));
6918 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr));
6919 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr+MSB16));
6922 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr+MSB16));
6924 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16));
6929 /*-----------------------------------------------------------------*/
6930 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6931 /*-----------------------------------------------------------------*/
6932 static void shiftLLeftOrResult (operand *left, int offl,
6933 operand *result, int offr, int shCount)
6935 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6936 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6937 /* shift left accumulator */
6939 /* or with result */
6940 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6941 /* back to result */
6942 pic16_aopPut(AOP(result),"a",offr);
6945 /*-----------------------------------------------------------------*/
6946 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6947 /*-----------------------------------------------------------------*/
6948 static void shiftRLeftOrResult (operand *left, int offl,
6949 operand *result, int offr, int shCount)
6951 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6952 MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE));
6953 /* shift right accumulator */
6955 /* or with result */
6956 pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE));
6957 /* back to result */
6958 pic16_aopPut(AOP(result),"a",offr);
6961 /*-----------------------------------------------------------------*/
6962 /* genlshOne - left shift a one byte quantity by known count */
6963 /*-----------------------------------------------------------------*/
6964 static void genlshOne (operand *result, operand *left, int shCount)
6966 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6967 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6970 /*-----------------------------------------------------------------*/
6971 /* genlshTwo - left shift two bytes by known amount != 0 */
6972 /*-----------------------------------------------------------------*/
6973 static void genlshTwo (operand *result,operand *left, int shCount)
6977 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6978 size = pic16_getDataSize(result);
6980 /* if shCount >= 8 */
6986 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6988 movLeft2Result(left, LSB, result, MSB16);
6990 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB));
6993 /* 1 <= shCount <= 7 */
6996 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6998 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7002 /*-----------------------------------------------------------------*/
7003 /* shiftLLong - shift left one long from left to result */
7004 /* offl = LSB or MSB16 */
7005 /*-----------------------------------------------------------------*/
7006 static void shiftLLong (operand *left, operand *result, int offr )
7009 int size = AOP_SIZE(result);
7011 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7012 if(size >= LSB+offr){
7013 l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE);
7015 pic16_emitcode("add","a,acc");
7016 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7017 size >= MSB16+offr && offr != LSB )
7018 pic16_emitcode("xch","a,%s",
7019 pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7021 pic16_aopPut(AOP(result),"a",LSB+offr);
7024 if(size >= MSB16+offr){
7025 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7026 l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE);
7029 pic16_emitcode("rlc","a");
7030 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7031 size >= MSB24+offr && offr != LSB)
7032 pic16_emitcode("xch","a,%s",
7033 pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7035 pic16_aopPut(AOP(result),"a",MSB16+offr);
7038 if(size >= MSB24+offr){
7039 if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7040 l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE);
7043 pic16_emitcode("rlc","a");
7044 if (pic16_sameRegs(AOP(left),AOP(result)) &&
7045 size >= MSB32+offr && offr != LSB )
7046 pic16_emitcode("xch","a,%s",
7047 pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7049 pic16_aopPut(AOP(result),"a",MSB24+offr);
7052 if(size > MSB32+offr){
7053 if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7054 l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE);
7057 pic16_emitcode("rlc","a");
7058 pic16_aopPut(AOP(result),"a",MSB32+offr);
7061 pic16_aopPut(AOP(result),zero,LSB);
7064 /*-----------------------------------------------------------------*/
7065 /* genlshFour - shift four byte by a known amount != 0 */
7066 /*-----------------------------------------------------------------*/
7067 static void genlshFour (operand *result, operand *left, int shCount)
7071 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7072 size = AOP_SIZE(result);
7074 /* if shifting more that 3 bytes */
7075 if (shCount >= 24 ) {
7078 /* lowest order of left goes to the highest
7079 order of the destination */
7080 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7082 movLeft2Result(left, LSB, result, MSB32);
7083 pic16_aopPut(AOP(result),zero,LSB);
7084 pic16_aopPut(AOP(result),zero,MSB16);
7085 pic16_aopPut(AOP(result),zero,MSB32);
7089 /* more than two bytes */
7090 else if ( shCount >= 16 ) {
7091 /* lower order two bytes goes to higher order two bytes */
7093 /* if some more remaining */
7095 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7097 movLeft2Result(left, MSB16, result, MSB32);
7098 movLeft2Result(left, LSB, result, MSB24);
7100 pic16_aopPut(AOP(result),zero,MSB16);
7101 pic16_aopPut(AOP(result),zero,LSB);
7105 /* if more than 1 byte */
7106 else if ( shCount >= 8 ) {
7107 /* lower order three bytes goes to higher order three bytes */
7111 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7113 movLeft2Result(left, LSB, result, MSB16);
7115 else{ /* size = 4 */
7117 movLeft2Result(left, MSB24, result, MSB32);
7118 movLeft2Result(left, MSB16, result, MSB24);
7119 movLeft2Result(left, LSB, result, MSB16);
7120 pic16_aopPut(AOP(result),zero,LSB);
7122 else if(shCount == 1)
7123 shiftLLong(left, result, MSB16);
7125 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7126 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7127 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7128 pic16_aopPut(AOP(result),zero,LSB);
7133 /* 1 <= shCount <= 7 */
7134 else if(shCount <= 2){
7135 shiftLLong(left, result, LSB);
7137 shiftLLong(result, result, LSB);
7139 /* 3 <= shCount <= 7, optimize */
7141 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7142 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7143 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7147 /*-----------------------------------------------------------------*/
7148 /* genLeftShiftLiteral - left shifting by known count */
7149 /*-----------------------------------------------------------------*/
7150 static void genLeftShiftLiteral (operand *left,
7155 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7158 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7159 pic16_freeAsmop(right,NULL,ic,TRUE);
7161 pic16_aopOp(left,ic,FALSE);
7162 pic16_aopOp(result,ic,FALSE);
7164 size = getSize(operandType(result));
7167 pic16_emitcode("; shift left ","result %d, left %d",size,
7171 /* I suppose that the left size >= result size */
7174 movLeft2Result(left, size, result, size);
7178 else if(shCount >= (size * 8))
7180 pic16_aopPut(AOP(result),zero,size);
7184 genlshOne (result,left,shCount);
7189 genlshTwo (result,left,shCount);
7193 genlshFour (result,left,shCount);
7197 pic16_freeAsmop(left,NULL,ic,TRUE);
7198 pic16_freeAsmop(result,NULL,ic,TRUE);
7201 /*-----------------------------------------------------------------*
7202 * genMultiAsm - repeat assembly instruction for size of register.
7203 * if endian == 1, then the high byte (i.e base address + size of
7204 * register) is used first else the low byte is used first;
7205 *-----------------------------------------------------------------*/
7206 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7211 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7224 pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset));
7229 /*-----------------------------------------------------------------*/
7230 /* genLeftShift - generates code for left shifting */
7231 /*-----------------------------------------------------------------*/
7232 static void genLeftShift (iCode *ic)
7234 operand *left,*right, *result;
7237 symbol *tlbl , *tlbl1;
7240 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7242 right = IC_RIGHT(ic);
7244 result = IC_RESULT(ic);
7246 pic16_aopOp(right,ic,FALSE);
7248 /* if the shift count is known then do it
7249 as efficiently as possible */
7250 if (AOP_TYPE(right) == AOP_LIT) {
7251 genLeftShiftLiteral (left,right,result,ic);
7255 /* shift count is unknown then we have to form
7256 a loop get the loop count in B : Note: we take
7257 only the lower order byte since shifting
7258 more that 32 bits make no sense anyway, ( the
7259 largest size of an object can be only 32 bits ) */
7262 pic16_aopOp(left,ic,FALSE);
7263 pic16_aopOp(result,ic,FALSE);
7265 /* now move the left to the result if they are not the
7267 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7268 AOP_SIZE(result) > 1) {
7270 size = AOP_SIZE(result);
7273 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7274 if (*l == '@' && (IS_AOP_PREG(result))) {
7276 pic16_emitcode("mov","a,%s",l);
7277 pic16_aopPut(AOP(result),"a",offset);
7279 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7280 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7281 //pic16_aopPut(AOP(result),l,offset);
7287 size = AOP_SIZE(result);
7289 /* if it is only one byte then */
7291 if(optimized_for_speed) {
7292 pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
7293 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0));
7294 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0));
7295 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7296 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7297 pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
7298 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7299 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0));
7300 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe));
7301 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0));
7302 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0));
7303 pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
7306 tlbl = newiTempLabel(NULL);
7307 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7308 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7309 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7312 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7313 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7314 pic16_emitpLabel(tlbl->key);
7315 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7316 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7318 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7323 if (pic16_sameRegs(AOP(left),AOP(result))) {
7325 tlbl = newiTempLabel(NULL);
7326 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7327 genMultiAsm(POC_RRCF, result, size,1);
7328 pic16_emitpLabel(tlbl->key);
7329 genMultiAsm(POC_RLCF, result, size,0);
7330 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7332 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7336 //tlbl = newiTempLabel(NULL);
7338 //tlbl1 = newiTempLabel(NULL);
7340 //reAdjustPreg(AOP(result));
7342 //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7343 //pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7344 //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7346 //pic16_emitcode("add","a,acc");
7347 //pic16_aopPut(AOP(result),"a",offset++);
7349 // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7351 // pic16_emitcode("rlc","a");
7352 // pic16_aopPut(AOP(result),"a",offset++);
7354 //reAdjustPreg(AOP(result));
7356 //pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7357 //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7360 tlbl = newiTempLabel(NULL);
7361 tlbl1= newiTempLabel(NULL);
7363 size = AOP_SIZE(result);
7366 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7368 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7370 /* offset should be 0, 1 or 3 */
7371 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7373 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7375 pic16_emitpcode(POC_MOVWF, pctemp);
7378 pic16_emitpLabel(tlbl->key);
7381 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7383 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++));
7385 pic16_emitpcode(POC_DECFSZ, pctemp);
7386 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7387 pic16_emitpLabel(tlbl1->key);
7389 pic16_popReleaseTempReg(pctemp);
7393 pic16_freeAsmop (right,NULL,ic,TRUE);
7394 pic16_freeAsmop(left,NULL,ic,TRUE);
7395 pic16_freeAsmop(result,NULL,ic,TRUE);
7398 /*-----------------------------------------------------------------*/
7399 /* genrshOne - right shift a one byte quantity by known count */
7400 /*-----------------------------------------------------------------*/
7401 static void genrshOne (operand *result, operand *left,
7402 int shCount, int sign)
7404 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7405 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7408 /*-----------------------------------------------------------------*/
7409 /* genrshTwo - right shift two bytes by known amount != 0 */
7410 /*-----------------------------------------------------------------*/
7411 static void genrshTwo (operand *result,operand *left,
7412 int shCount, int sign)
7414 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7415 /* if shCount >= 8 */
7419 shiftR1Left2Result(left, MSB16, result, LSB,
7422 movLeft2Result(left, MSB16, result, LSB);
7424 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16));
7427 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7428 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16));
7432 /* 1 <= shCount <= 7 */
7434 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7437 /*-----------------------------------------------------------------*/
7438 /* shiftRLong - shift right one long from left to result */
7439 /* offl = LSB or MSB16 */
7440 /*-----------------------------------------------------------------*/
7441 static void shiftRLong (operand *left, int offl,
7442 operand *result, int sign)
7444 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7446 pic16_emitcode("clr","c");
7447 MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE));
7449 pic16_emitcode("mov","c,acc.7");
7450 pic16_emitcode("rrc","a");
7451 pic16_aopPut(AOP(result),"a",MSB32-offl);
7453 /* add sign of "a" */
7454 pic16_addSign(result, MSB32, sign);
7456 MOVA(pic16_aopGet(AOP(left),MSB24,FALSE,FALSE));
7457 pic16_emitcode("rrc","a");
7458 pic16_aopPut(AOP(result),"a",MSB24-offl);
7460 MOVA(pic16_aopGet(AOP(left),MSB16,FALSE,FALSE));
7461 pic16_emitcode("rrc","a");
7462 pic16_aopPut(AOP(result),"a",MSB16-offl);
7465 MOVA(pic16_aopGet(AOP(left),LSB,FALSE,FALSE));
7466 pic16_emitcode("rrc","a");
7467 pic16_aopPut(AOP(result),"a",LSB);
7471 /*-----------------------------------------------------------------*/
7472 /* genrshFour - shift four byte by a known amount != 0 */
7473 /*-----------------------------------------------------------------*/
7474 static void genrshFour (operand *result, operand *left,
7475 int shCount, int sign)
7477 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7478 /* if shifting more that 3 bytes */
7479 if(shCount >= 24 ) {
7482 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7484 movLeft2Result(left, MSB32, result, LSB);
7486 pic16_addSign(result, MSB16, sign);
7488 else if(shCount >= 16){
7491 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7493 movLeft2Result(left, MSB24, result, LSB);
7494 movLeft2Result(left, MSB32, result, MSB16);
7496 pic16_addSign(result, MSB24, sign);
7498 else if(shCount >= 8){
7501 shiftRLong(left, MSB16, result, sign);
7502 else if(shCount == 0){
7503 movLeft2Result(left, MSB16, result, LSB);
7504 movLeft2Result(left, MSB24, result, MSB16);
7505 movLeft2Result(left, MSB32, result, MSB24);
7506 pic16_addSign(result, MSB32, sign);
7509 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7510 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7511 /* the last shift is signed */
7512 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7513 pic16_addSign(result, MSB32, sign);
7516 else{ /* 1 <= shCount <= 7 */
7518 shiftRLong(left, LSB, result, sign);
7520 shiftRLong(result, LSB, result, sign);
7523 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7524 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7525 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7530 /*-----------------------------------------------------------------*/
7531 /* genRightShiftLiteral - right shifting by known count */
7532 /*-----------------------------------------------------------------*/
7533 static void genRightShiftLiteral (operand *left,
7539 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7542 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7543 pic16_freeAsmop(right,NULL,ic,TRUE);
7545 pic16_aopOp(left,ic,FALSE);
7546 pic16_aopOp(result,ic,FALSE);
7549 pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7553 lsize = pic16_getDataSize(left);
7554 res_size = pic16_getDataSize(result);
7555 /* test the LEFT size !!! */
7557 /* I suppose that the left size >= result size */
7560 movLeft2Result(left, lsize, result, res_size);
7563 else if(shCount >= (lsize * 8)){
7566 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB));
7568 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7569 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB));
7574 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0));
7575 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7576 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
7578 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size));
7583 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),res_size));
7590 genrshOne (result,left,shCount,sign);
7594 genrshTwo (result,left,shCount,sign);
7598 genrshFour (result,left,shCount,sign);
7606 pic16_freeAsmop(left,NULL,ic,TRUE);
7607 pic16_freeAsmop(result,NULL,ic,TRUE);
7610 /*-----------------------------------------------------------------*/
7611 /* genSignedRightShift - right shift of signed number */
7612 /*-----------------------------------------------------------------*/
7613 static void genSignedRightShift (iCode *ic)
7615 operand *right, *left, *result;
7618 symbol *tlbl, *tlbl1 ;
7621 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7623 /* we do it the hard way put the shift count in b
7624 and loop thru preserving the sign */
7625 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7627 right = IC_RIGHT(ic);
7629 result = IC_RESULT(ic);
7631 pic16_aopOp(right,ic,FALSE);
7632 pic16_aopOp(left,ic,FALSE);
7633 pic16_aopOp(result,ic,FALSE);
7636 if ( AOP_TYPE(right) == AOP_LIT) {
7637 genRightShiftLiteral (left,right,result,ic,1);
7640 /* shift count is unknown then we have to form
7641 a loop get the loop count in B : Note: we take
7642 only the lower order byte since shifting
7643 more that 32 bits make no sense anyway, ( the
7644 largest size of an object can be only 32 bits ) */
7646 //pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7647 //pic16_emitcode("inc","b");
7648 //pic16_freeAsmop (right,NULL,ic,TRUE);
7649 //pic16_aopOp(left,ic,FALSE);
7650 //pic16_aopOp(result,ic,FALSE);
7652 /* now move the left to the result if they are not the
7654 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7655 AOP_SIZE(result) > 1) {
7657 size = AOP_SIZE(result);
7661 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7662 if (*l == '@' && IS_AOP_PREG(result)) {
7664 pic16_emitcode("mov","a,%s",l);
7665 pic16_aopPut(AOP(result),"a",offset);
7667 pic16_aopPut(AOP(result),l,offset);
7669 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset));
7670 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
7676 /* mov the highest order bit to OVR */
7677 tlbl = newiTempLabel(NULL);
7678 tlbl1= newiTempLabel(NULL);
7680 size = AOP_SIZE(result);
7683 pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */
7685 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
7687 /* offset should be 0, 1 or 3 */
7688 pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3)));
7690 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key));
7692 pic16_emitpcode(POC_MOVWF, pctemp);
7695 pic16_emitpLabel(tlbl->key);
7697 pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offset));
7698 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offset));
7701 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),--offset));
7704 pic16_emitpcode(POC_DECFSZ, pctemp);
7705 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7706 pic16_emitpLabel(tlbl1->key);
7708 pic16_popReleaseTempReg(pctemp);
7710 size = AOP_SIZE(result);
7712 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(left),offset,FALSE,FALSE));
7713 pic16_emitcode("rlc","a");
7714 pic16_emitcode("mov","ov,c");
7715 /* if it is only one byte then */
7717 l = pic16_aopGet(AOP(left),0,FALSE,FALSE);
7719 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7720 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7721 pic16_emitcode("mov","c,ov");
7722 pic16_emitcode("rrc","a");
7723 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7724 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7725 pic16_aopPut(AOP(result),"a",0);
7729 reAdjustPreg(AOP(result));
7730 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7731 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7732 pic16_emitcode("mov","c,ov");
7734 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7736 pic16_emitcode("rrc","a");
7737 pic16_aopPut(AOP(result),"a",offset--);
7739 reAdjustPreg(AOP(result));
7740 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7741 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7746 pic16_freeAsmop(left,NULL,ic,TRUE);
7747 pic16_freeAsmop(result,NULL,ic,TRUE);
7748 pic16_freeAsmop(right,NULL,ic,TRUE);
7751 /*-----------------------------------------------------------------*/
7752 /* genRightShift - generate code for right shifting */
7753 /*-----------------------------------------------------------------*/
7754 static void genRightShift (iCode *ic)
7756 operand *right, *left, *result;
7760 symbol *tlbl, *tlbl1 ;
7762 /* if signed then we do it the hard way preserve the
7763 sign bit moving it inwards */
7764 retype = getSpec(operandType(IC_RESULT(ic)));
7765 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7767 if (!SPEC_USIGN(retype)) {
7768 genSignedRightShift (ic);
7772 /* signed & unsigned types are treated the same : i.e. the
7773 signed is NOT propagated inwards : quoting from the
7774 ANSI - standard : "for E1 >> E2, is equivalent to division
7775 by 2**E2 if unsigned or if it has a non-negative value,
7776 otherwise the result is implementation defined ", MY definition
7777 is that the sign does not get propagated */
7779 right = IC_RIGHT(ic);
7781 result = IC_RESULT(ic);
7783 pic16_aopOp(right,ic,FALSE);
7785 /* if the shift count is known then do it
7786 as efficiently as possible */
7787 if (AOP_TYPE(right) == AOP_LIT) {
7788 genRightShiftLiteral (left,right,result,ic, 0);
7792 /* shift count is unknown then we have to form
7793 a loop get the loop count in B : Note: we take
7794 only the lower order byte since shifting
7795 more that 32 bits make no sense anyway, ( the
7796 largest size of an object can be only 32 bits ) */
7798 pic16_emitcode("mov","b,%s",pic16_aopGet(AOP(right),0,FALSE,FALSE));
7799 pic16_emitcode("inc","b");
7800 pic16_aopOp(left,ic,FALSE);
7801 pic16_aopOp(result,ic,FALSE);
7803 /* now move the left to the result if they are not the
7805 if (!pic16_sameRegs(AOP(left),AOP(result)) &&
7806 AOP_SIZE(result) > 1) {
7808 size = AOP_SIZE(result);
7811 l = pic16_aopGet(AOP(left),offset,FALSE,TRUE);
7812 if (*l == '@' && IS_AOP_PREG(result)) {
7814 pic16_emitcode("mov","a,%s",l);
7815 pic16_aopPut(AOP(result),"a",offset);
7817 pic16_aopPut(AOP(result),l,offset);
7822 tlbl = newiTempLabel(NULL);
7823 tlbl1= newiTempLabel(NULL);
7824 size = AOP_SIZE(result);
7827 /* if it is only one byte then */
7830 tlbl = newiTempLabel(NULL);
7831 if (!pic16_sameRegs(AOP(left),AOP(result))) {
7832 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7833 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
7836 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0));
7837 pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
7838 pic16_emitpLabel(tlbl->key);
7839 pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0));
7840 pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1));
7842 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key));
7847 reAdjustPreg(AOP(result));
7848 pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7849 pic16_emitcode("","%05d_DS_:",tlbl->key+100);
7852 l = pic16_aopGet(AOP(result),offset,FALSE,FALSE);
7854 pic16_emitcode("rrc","a");
7855 pic16_aopPut(AOP(result),"a",offset--);
7857 reAdjustPreg(AOP(result));
7859 pic16_emitcode("","%05d_DS_:",tlbl1->key+100);
7860 pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7863 pic16_freeAsmop(left,NULL,ic,TRUE);
7864 pic16_freeAsmop (right,NULL,ic,TRUE);
7865 pic16_freeAsmop(result,NULL,ic,TRUE);
7868 /*-----------------------------------------------------------------*/
7869 /* genUnpackBits - generates code for unpacking bits */
7870 /*-----------------------------------------------------------------*/
7871 static void genUnpackBits (operand *result, char *rname, int ptype)
7878 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7879 etype = getSpec(operandType(result));
7881 /* read the first byte */
7886 pic16_emitcode("mov","a,@%s",rname);
7890 pic16_emitcode("movx","a,@%s",rname);
7894 pic16_emitcode("movx","a,@dptr");
7898 pic16_emitcode("clr","a");
7899 pic16_emitcode("movc","a","@a+dptr");
7903 pic16_emitcode("lcall","__gptrget");
7907 /* if we have bitdisplacement then it fits */
7908 /* into this byte completely or if length is */
7909 /* less than a byte */
7910 if ((shCnt = SPEC_BSTR(etype)) ||
7911 (SPEC_BLEN(etype) <= 8)) {
7913 /* shift right acc */
7916 pic16_emitcode("anl","a,#0x%02x",
7917 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7918 pic16_aopPut(AOP(result),"a",offset);
7922 /* bit field did not fit in a byte */
7923 rlen = SPEC_BLEN(etype) - 8;
7924 pic16_aopPut(AOP(result),"a",offset++);
7931 pic16_emitcode("inc","%s",rname);
7932 pic16_emitcode("mov","a,@%s",rname);
7936 pic16_emitcode("inc","%s",rname);
7937 pic16_emitcode("movx","a,@%s",rname);
7941 pic16_emitcode("inc","dptr");
7942 pic16_emitcode("movx","a,@dptr");
7946 pic16_emitcode("clr","a");
7947 pic16_emitcode("inc","dptr");
7948 pic16_emitcode("movc","a","@a+dptr");
7952 pic16_emitcode("inc","dptr");
7953 pic16_emitcode("lcall","__gptrget");
7958 /* if we are done */
7962 pic16_aopPut(AOP(result),"a",offset++);
7967 pic16_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7968 pic16_aopPut(AOP(result),"a",offset);
7975 /*-----------------------------------------------------------------*/
7976 /* genDataPointerGet - generates code when ptr offset is known */
7977 /*-----------------------------------------------------------------*/
7978 static void genDataPointerGet (operand *left,
7982 int size , offset = 0;
7985 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7988 /* optimization - most of the time, left and result are the same
7989 * address, but different types. for the pic code, we could omit
7993 pic16_aopOp(result,ic,TRUE);
7995 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
7997 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
7999 size = AOP_SIZE(result);
8002 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
8006 pic16_freeAsmop(left,NULL,ic,TRUE);
8007 pic16_freeAsmop(result,NULL,ic,TRUE);
8010 /*-----------------------------------------------------------------*/
8011 /* genNearPointerGet - pic16_emitcode for near pointer fetch */
8012 /*-----------------------------------------------------------------*/
8013 static void genNearPointerGet (operand *left,
8018 //regs *preg = NULL ;
8020 sym_link *rtype, *retype;
8021 sym_link *ltype = operandType(left);
8024 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8026 rtype = operandType(result);
8027 retype= getSpec(rtype);
8029 pic16_aopOp(left,ic,FALSE);
8031 /* if left is rematerialisable and
8032 result is not bit variable type and
8033 the left is pointer to data space i.e
8034 lower 128 bytes of space */
8035 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8036 !IS_BITVAR(retype) &&
8037 DCL_TYPE(ltype) == POINTER) {
8038 //genDataPointerGet (left,result,ic);
8042 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8044 /* if the value is already in a pointer register
8045 then don't need anything more */
8046 if (!AOP_INPREG(AOP(left))) {
8047 /* otherwise get a free pointer register */
8048 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8051 preg = getFreePtr(ic,&aop,FALSE);
8052 pic16_emitcode("mov","%s,%s",
8054 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8055 rname = preg->name ;
8059 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8061 pic16_aopOp (result,ic,FALSE);
8063 /* if bitfield then unpack the bits */
8064 if (IS_BITVAR(retype))
8065 genUnpackBits (result,rname,POINTER);
8067 /* we have can just get the values */
8068 int size = AOP_SIZE(result);
8071 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8073 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8074 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8076 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8077 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8079 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8083 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8085 pic16_emitcode("mov","a,@%s",rname);
8086 pic16_aopPut(AOP(result),"a",offset);
8088 sprintf(buffer,"@%s",rname);
8089 pic16_aopPut(AOP(result),buffer,offset);
8093 pic16_emitcode("inc","%s",rname);
8098 /* now some housekeeping stuff */
8100 /* we had to allocate for this iCode */
8101 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8102 pic16_freeAsmop(NULL,aop,ic,TRUE);
8104 /* we did not allocate which means left
8105 already in a pointer register, then
8106 if size > 0 && this could be used again
8107 we have to point it back to where it
8109 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8110 if (AOP_SIZE(result) > 1 &&
8111 !OP_SYMBOL(left)->remat &&
8112 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8114 int size = AOP_SIZE(result) - 1;
8116 pic16_emitcode("dec","%s",rname);
8121 pic16_freeAsmop(left,NULL,ic,TRUE);
8122 pic16_freeAsmop(result,NULL,ic,TRUE);
8126 /*-----------------------------------------------------------------*/
8127 /* genPagedPointerGet - pic16_emitcode for paged pointer fetch */
8128 /*-----------------------------------------------------------------*/
8129 static void genPagedPointerGet (operand *left,
8136 sym_link *rtype, *retype;
8138 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8140 rtype = operandType(result);
8141 retype= getSpec(rtype);
8143 pic16_aopOp(left,ic,FALSE);
8145 /* if the value is already in a pointer register
8146 then don't need anything more */
8147 if (!AOP_INPREG(AOP(left))) {
8148 /* otherwise get a free pointer register */
8150 preg = getFreePtr(ic,&aop,FALSE);
8151 pic16_emitcode("mov","%s,%s",
8153 pic16_aopGet(AOP(left),0,FALSE,TRUE));
8154 rname = preg->name ;
8156 rname = pic16_aopGet(AOP(left),0,FALSE,FALSE);
8158 pic16_freeAsmop(left,NULL,ic,TRUE);
8159 pic16_aopOp (result,ic,FALSE);
8161 /* if bitfield then unpack the bits */
8162 if (IS_BITVAR(retype))
8163 genUnpackBits (result,rname,PPOINTER);
8165 /* we have can just get the values */
8166 int size = AOP_SIZE(result);
8171 pic16_emitcode("movx","a,@%s",rname);
8172 pic16_aopPut(AOP(result),"a",offset);
8177 pic16_emitcode("inc","%s",rname);
8181 /* now some housekeeping stuff */
8183 /* we had to allocate for this iCode */
8184 pic16_freeAsmop(NULL,aop,ic,TRUE);
8186 /* we did not allocate which means left
8187 already in a pointer register, then
8188 if size > 0 && this could be used again
8189 we have to point it back to where it
8191 if (AOP_SIZE(result) > 1 &&
8192 !OP_SYMBOL(left)->remat &&
8193 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8195 int size = AOP_SIZE(result) - 1;
8197 pic16_emitcode("dec","%s",rname);
8202 pic16_freeAsmop(result,NULL,ic,TRUE);
8207 /*-----------------------------------------------------------------*/
8208 /* genFarPointerGet - gget value from far space */
8209 /*-----------------------------------------------------------------*/
8210 static void genFarPointerGet (operand *left,
8211 operand *result, iCode *ic)
8214 sym_link *retype = getSpec(operandType(result));
8216 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8218 pic16_aopOp(left,ic,FALSE);
8220 /* if the operand is already in dptr
8221 then we do nothing else we move the value to dptr */
8222 if (AOP_TYPE(left) != AOP_STR) {
8223 /* if this is remateriazable */
8224 if (AOP_TYPE(left) == AOP_IMMD)
8225 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8226 else { /* we need to get it byte by byte */
8227 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8228 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8229 if (options.model == MODEL_FLAT24)
8231 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8235 /* so dptr know contains the address */
8236 pic16_freeAsmop(left,NULL,ic,TRUE);
8237 pic16_aopOp(result,ic,FALSE);
8239 /* if bit then unpack */
8240 if (IS_BITVAR(retype))
8241 genUnpackBits(result,"dptr",FPOINTER);
8243 size = AOP_SIZE(result);
8247 pic16_emitcode("movx","a,@dptr");
8248 pic16_aopPut(AOP(result),"a",offset++);
8250 pic16_emitcode("inc","dptr");
8254 pic16_freeAsmop(result,NULL,ic,TRUE);
8257 /*-----------------------------------------------------------------*/
8258 /* genCodePointerGet - get value from code space */
8259 /*-----------------------------------------------------------------*/
8260 static void genCodePointerGet (operand *left,
8261 operand *result, iCode *ic)
8264 sym_link *retype = getSpec(operandType(result));
8266 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8268 pic16_aopOp(left,ic,FALSE);
8270 /* if the operand is already in dptr
8271 then we do nothing else we move the value to dptr */
8272 if (AOP_TYPE(left) != AOP_STR) {
8273 /* if this is remateriazable */
8274 if (AOP_TYPE(left) == AOP_IMMD)
8275 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8276 else { /* we need to get it byte by byte */
8277 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(left),0,FALSE,FALSE));
8278 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(left),1,FALSE,FALSE));
8279 if (options.model == MODEL_FLAT24)
8281 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(left),2,FALSE,FALSE));
8285 /* so dptr know contains the address */
8286 pic16_freeAsmop(left,NULL,ic,TRUE);
8287 pic16_aopOp(result,ic,FALSE);
8289 /* if bit then unpack */
8290 if (IS_BITVAR(retype))
8291 genUnpackBits(result,"dptr",CPOINTER);
8293 size = AOP_SIZE(result);
8297 pic16_emitcode("clr","a");
8298 pic16_emitcode("movc","a,@a+dptr");
8299 pic16_aopPut(AOP(result),"a",offset++);
8301 pic16_emitcode("inc","dptr");
8305 pic16_freeAsmop(result,NULL,ic,TRUE);
8308 /*-----------------------------------------------------------------*/
8309 /* genGenPointerGet - gget value from generic pointer space */
8310 /*-----------------------------------------------------------------*/
8311 static void genGenPointerGet (operand *left,
8312 operand *result, iCode *ic)
8315 sym_link *retype = getSpec(operandType(result));
8317 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8318 pic16_aopOp(left,ic,FALSE);
8319 pic16_aopOp(result,ic,FALSE);
8322 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8324 /* if the operand is already in dptr
8325 then we do nothing else we move the value to dptr */
8326 // if (AOP_TYPE(left) != AOP_STR) {
8327 /* if this is remateriazable */
8328 if (AOP_TYPE(left) == AOP_IMMD) {
8329 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE));
8330 pic16_emitcode("mov","b,#%d",pointerCode(retype));
8332 else { /* we need to get it byte by byte */
8334 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0));
8335 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
8337 size = AOP_SIZE(result);
8341 pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0));
8342 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++));
8344 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
8349 /* so dptr know contains the address */
8351 /* if bit then unpack */
8352 //if (IS_BITVAR(retype))
8353 // genUnpackBits(result,"dptr",GPOINTER);
8356 pic16_freeAsmop(left,NULL,ic,TRUE);
8357 pic16_freeAsmop(result,NULL,ic,TRUE);
8361 /*-----------------------------------------------------------------*/
8362 /* genConstPointerGet - get value from const generic pointer space */
8363 /*-----------------------------------------------------------------*/
8364 static void genConstPointerGet (operand *left,
8365 operand *result, iCode *ic)
8367 //sym_link *retype = getSpec(operandType(result));
8368 symbol *albl = newiTempLabel(NULL);
8369 symbol *blbl = newiTempLabel(NULL);
8372 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8373 pic16_aopOp(left,ic,FALSE);
8374 pic16_aopOp(result,ic,FALSE);
8377 DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result);
8379 DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__);
8381 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key));
8382 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key));
8383 pic16_emitpLabel(albl->key);
8385 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8387 pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
8388 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
8389 pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
8390 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl));
8392 pic16_emitpLabel(blbl->key);
8394 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0));
8397 pic16_freeAsmop(left,NULL,ic,TRUE);
8398 pic16_freeAsmop(result,NULL,ic,TRUE);
8401 /*-----------------------------------------------------------------*/
8402 /* genPointerGet - generate code for pointer get */
8403 /*-----------------------------------------------------------------*/
8404 static void genPointerGet (iCode *ic)
8406 operand *left, *result ;
8407 sym_link *type, *etype;
8410 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8413 result = IC_RESULT(ic) ;
8415 /* depending on the type of pointer we need to
8416 move it to the correct pointer register */
8417 type = operandType(left);
8418 etype = getSpec(type);
8421 if (IS_PTR_CONST(type))
8423 if (IS_CODEPTR(type))
8425 DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__);
8427 /* if left is of type of pointer then it is simple */
8428 if (IS_PTR(type) && !IS_FUNC(type->next))
8429 p_type = DCL_TYPE(type);
8431 /* we have to go by the storage class */
8432 p_type = PTR_TYPE(SPEC_OCLS(etype));
8434 DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8436 if (SPEC_OCLS(etype)->codesp ) {
8437 DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__);
8438 //p_type = CPOINTER ;
8441 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8442 DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__);
8443 /*p_type = FPOINTER ;*/
8445 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8446 DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__);
8447 /* p_type = PPOINTER; */
8449 if (SPEC_OCLS(etype) == idata )
8450 DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__);
8451 /* p_type = IPOINTER; */
8453 DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__);
8454 /* p_type = POINTER ; */
8457 /* now that we have the pointer type we assign
8458 the pointer values */
8463 genNearPointerGet (left,result,ic);
8467 genPagedPointerGet(left,result,ic);
8471 genFarPointerGet (left,result,ic);
8475 genConstPointerGet (left,result,ic);
8476 //pic16_emitcodePointerGet (left,result,ic);
8481 if (IS_PTR_CONST(type))
8482 genConstPointerGet (left,result,ic);
8485 genGenPointerGet (left,result,ic);
8491 /*-----------------------------------------------------------------*/
8492 /* genPackBits - generates code for packed bit storage */
8493 /*-----------------------------------------------------------------*/
8494 static void genPackBits (sym_link *etype ,
8496 char *rname, int p_type)
8504 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8505 blen = SPEC_BLEN(etype);
8506 bstr = SPEC_BSTR(etype);
8508 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8511 /* if the bit lenth is less than or */
8512 /* it exactly fits a byte then */
8513 if (SPEC_BLEN(etype) <= 8 ) {
8514 shCount = SPEC_BSTR(etype) ;
8516 /* shift left acc */
8519 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8524 pic16_emitcode ("mov","b,a");
8525 pic16_emitcode("mov","a,@%s",rname);
8529 pic16_emitcode ("mov","b,a");
8530 pic16_emitcode("movx","a,@dptr");
8534 pic16_emitcode ("push","b");
8535 pic16_emitcode ("push","acc");
8536 pic16_emitcode ("lcall","__gptrget");
8537 pic16_emitcode ("pop","b");
8541 pic16_emitcode ("anl","a,#0x%02x",(unsigned char)
8542 ((unsigned char)(0xFF << (blen+bstr)) |
8543 (unsigned char)(0xFF >> (8-bstr)) ) );
8544 pic16_emitcode ("orl","a,b");
8545 if (p_type == GPOINTER)
8546 pic16_emitcode("pop","b");
8552 pic16_emitcode("mov","@%s,a",rname);
8556 pic16_emitcode("movx","@dptr,a");
8560 DEBUGpic16_emitcode(";lcall","__gptrput");
8565 if ( SPEC_BLEN(etype) <= 8 )
8568 pic16_emitcode("inc","%s",rname);
8569 rLen = SPEC_BLEN(etype) ;
8571 /* now generate for lengths greater than one byte */
8574 l = pic16_aopGet(AOP(right),offset++,FALSE,TRUE);
8584 pic16_emitcode("mov","@%s,a",rname);
8586 pic16_emitcode("mov","@%s,%s",rname,l);
8591 pic16_emitcode("movx","@dptr,a");
8596 DEBUGpic16_emitcode(";lcall","__gptrput");
8599 pic16_emitcode ("inc","%s",rname);
8604 /* last last was not complete */
8606 /* save the byte & read byte */
8609 pic16_emitcode ("mov","b,a");
8610 pic16_emitcode("mov","a,@%s",rname);
8614 pic16_emitcode ("mov","b,a");
8615 pic16_emitcode("movx","a,@dptr");
8619 pic16_emitcode ("push","b");
8620 pic16_emitcode ("push","acc");
8621 pic16_emitcode ("lcall","__gptrget");
8622 pic16_emitcode ("pop","b");
8626 pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8627 pic16_emitcode ("orl","a,b");
8630 if (p_type == GPOINTER)
8631 pic16_emitcode("pop","b");
8636 pic16_emitcode("mov","@%s,a",rname);
8640 pic16_emitcode("movx","@dptr,a");
8644 DEBUGpic16_emitcode(";lcall","__gptrput");
8648 /*-----------------------------------------------------------------*/
8649 /* genDataPointerSet - remat pointer to data space */
8650 /*-----------------------------------------------------------------*/
8651 static void genDataPointerSet(operand *right,
8655 int size, offset = 0 ;
8656 char *l, buffer[256];
8658 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8659 pic16_aopOp(right,ic,FALSE);
8661 l = pic16_aopGet(AOP(result),0,FALSE,TRUE);
8662 size = AOP_SIZE(right);
8664 if ( AOP_TYPE(result) == AOP_PCODE) {
8665 fprintf(stderr,"genDataPointerSet %s, %d\n",
8666 AOP(result)->aopu.pcop->name,
8667 PCOI(AOP(result)->aopu.pcop)->offset);
8671 // tsd, was l+1 - the underline `_' prefix was being stripped
8674 sprintf(buffer,"(%s + %d)",l,offset);
8675 fprintf(stderr,"oops %s\n",buffer);
8677 sprintf(buffer,"%s",l);
8679 if (AOP_TYPE(right) == AOP_LIT) {
8680 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8681 lit = lit >> (8*offset);
8683 pic16_emitcode("movlw","%d",lit);
8684 pic16_emitcode("movwf","%s",buffer);
8686 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff));
8687 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8688 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8691 pic16_emitcode("clrf","%s",buffer);
8692 //pic16_emitpcode(POC_CLRF, popRegFromString(buffer));
8693 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
8696 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE));
8697 pic16_emitcode("movwf","%s",buffer);
8699 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
8700 //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer));
8701 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
8708 pic16_freeAsmop(right,NULL,ic,TRUE);
8709 pic16_freeAsmop(result,NULL,ic,TRUE);
8712 /*-----------------------------------------------------------------*/
8713 /* genNearPointerSet - pic16_emitcode for near pointer put */
8714 /*-----------------------------------------------------------------*/
8715 static void genNearPointerSet (operand *right,
8722 sym_link *ptype = operandType(result);
8725 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8726 retype= getSpec(operandType(right));
8728 pic16_aopOp(result,ic,FALSE);
8731 /* if the result is rematerializable &
8732 in data space & not a bit variable */
8733 //if (AOP_TYPE(result) == AOP_IMMD &&
8734 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8735 DCL_TYPE(ptype) == POINTER &&
8736 !IS_BITVAR(retype)) {
8737 genDataPointerSet (right,result,ic);
8738 pic16_freeAsmop(result,NULL,ic,TRUE);
8742 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8743 pic16_aopOp(right,ic,FALSE);
8744 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8746 /* if the value is already in a pointer register
8747 then don't need anything more */
8748 if (!AOP_INPREG(AOP(result))) {
8749 /* otherwise get a free pointer register */
8750 //aop = newAsmop(0);
8751 //preg = getFreePtr(ic,&aop,FALSE);
8752 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8753 //pic16_emitcode("mov","%s,%s",
8755 // pic16_aopGet(AOP(result),0,FALSE,TRUE));
8756 //rname = preg->name ;
8757 //pic16_emitcode("movwf","fsr0");
8758 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0));
8759 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0));
8760 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
8761 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0));
8765 // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8768 /* if bitfield then unpack the bits */
8769 if (IS_BITVAR(retype)) {
8770 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8771 "The programmer is obviously confused");
8772 //genPackBits (retype,right,rname,POINTER);
8776 /* we have can just get the values */
8777 int size = AOP_SIZE(right);
8780 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8782 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8785 //pic16_emitcode("mov","@%s,a",rname);
8786 pic16_emitcode("movf","indf0,w ;1");
8789 if (AOP_TYPE(right) == AOP_LIT) {
8790 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8792 pic16_emitcode("movlw","%s",l);
8793 pic16_emitcode("movwf","indf0 ;2");
8795 pic16_emitcode("clrf","indf0");
8797 pic16_emitcode("movf","%s,w",l);
8798 pic16_emitcode("movwf","indf0 ;2");
8800 //pic16_emitcode("mov","@%s,%s",rname,l);
8803 pic16_emitcode("incf","fsr0,f ;3");
8804 //pic16_emitcode("inc","%s",rname);
8809 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8810 /* now some housekeeping stuff */
8812 /* we had to allocate for this iCode */
8813 pic16_freeAsmop(NULL,aop,ic,TRUE);
8815 /* we did not allocate which means left
8816 already in a pointer register, then
8817 if size > 0 && this could be used again
8818 we have to point it back to where it
8820 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8821 if (AOP_SIZE(right) > 1 &&
8822 !OP_SYMBOL(result)->remat &&
8823 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8825 int size = AOP_SIZE(right) - 1;
8827 pic16_emitcode("decf","fsr0,f");
8828 //pic16_emitcode("dec","%s",rname);
8832 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8835 pic16_freeAsmop(right,NULL,ic,TRUE);
8836 pic16_freeAsmop(result,NULL,ic,TRUE);
8839 /*-----------------------------------------------------------------*/
8840 /* genPagedPointerSet - pic16_emitcode for Paged pointer put */
8841 /*-----------------------------------------------------------------*/
8842 static void genPagedPointerSet (operand *right,
8851 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8853 retype= getSpec(operandType(right));
8855 pic16_aopOp(result,ic,FALSE);
8857 /* if the value is already in a pointer register
8858 then don't need anything more */
8859 if (!AOP_INPREG(AOP(result))) {
8860 /* otherwise get a free pointer register */
8862 preg = getFreePtr(ic,&aop,FALSE);
8863 pic16_emitcode("mov","%s,%s",
8865 pic16_aopGet(AOP(result),0,FALSE,TRUE));
8866 rname = preg->name ;
8868 rname = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8870 pic16_freeAsmop(result,NULL,ic,TRUE);
8871 pic16_aopOp (right,ic,FALSE);
8873 /* if bitfield then unpack the bits */
8874 if (IS_BITVAR(retype))
8875 genPackBits (retype,right,rname,PPOINTER);
8877 /* we have can just get the values */
8878 int size = AOP_SIZE(right);
8882 l = pic16_aopGet(AOP(right),offset,FALSE,TRUE);
8885 pic16_emitcode("movx","@%s,a",rname);
8888 pic16_emitcode("inc","%s",rname);
8894 /* now some housekeeping stuff */
8896 /* we had to allocate for this iCode */
8897 pic16_freeAsmop(NULL,aop,ic,TRUE);
8899 /* we did not allocate which means left
8900 already in a pointer register, then
8901 if size > 0 && this could be used again
8902 we have to point it back to where it
8904 if (AOP_SIZE(right) > 1 &&
8905 !OP_SYMBOL(result)->remat &&
8906 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8908 int size = AOP_SIZE(right) - 1;
8910 pic16_emitcode("dec","%s",rname);
8915 pic16_freeAsmop(right,NULL,ic,TRUE);
8920 /*-----------------------------------------------------------------*/
8921 /* genFarPointerSet - set value from far space */
8922 /*-----------------------------------------------------------------*/
8923 static void genFarPointerSet (operand *right,
8924 operand *result, iCode *ic)
8927 sym_link *retype = getSpec(operandType(right));
8929 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8930 pic16_aopOp(result,ic,FALSE);
8932 /* if the operand is already in dptr
8933 then we do nothing else we move the value to dptr */
8934 if (AOP_TYPE(result) != AOP_STR) {
8935 /* if this is remateriazable */
8936 if (AOP_TYPE(result) == AOP_IMMD)
8937 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8938 else { /* we need to get it byte by byte */
8939 pic16_emitcode("mov","dpl,%s",pic16_aopGet(AOP(result),0,FALSE,FALSE));
8940 pic16_emitcode("mov","dph,%s",pic16_aopGet(AOP(result),1,FALSE,FALSE));
8941 if (options.model == MODEL_FLAT24)
8943 pic16_emitcode("mov", "dpx,%s",pic16_aopGet(AOP(result),2,FALSE,FALSE));
8947 /* so dptr know contains the address */
8948 pic16_freeAsmop(result,NULL,ic,TRUE);
8949 pic16_aopOp(right,ic,FALSE);
8951 /* if bit then unpack */
8952 if (IS_BITVAR(retype))
8953 genPackBits(retype,right,"dptr",FPOINTER);
8955 size = AOP_SIZE(right);
8959 char *l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
8961 pic16_emitcode("movx","@dptr,a");
8963 pic16_emitcode("inc","dptr");
8967 pic16_freeAsmop(right,NULL,ic,TRUE);
8970 /*-----------------------------------------------------------------*/
8971 /* genGenPointerSet - set value from generic pointer space */
8972 /*-----------------------------------------------------------------*/
8973 static void genGenPointerSet (operand *right,
8974 operand *result, iCode *ic)
8977 sym_link *retype = getSpec(operandType(right));
8979 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8981 pic16_aopOp(result,ic,FALSE);
8982 pic16_aopOp(right,ic,FALSE);
8983 size = AOP_SIZE(right);
8985 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
8987 /* if the operand is already in dptr
8988 then we do nothing else we move the value to dptr */
8989 if (AOP_TYPE(result) != AOP_STR) {
8990 /* if this is remateriazable */
8991 if (AOP_TYPE(result) == AOP_IMMD) {
8992 pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8993 pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE));
8995 else { /* we need to get it byte by byte */
8996 //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE);
8997 size = AOP_SIZE(right);
9000 /* hack hack! see if this the FSR. If so don't load W */
9001 if(AOP_TYPE(right) != AOP_ACC) {
9004 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0));
9005 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9007 if(AOP_SIZE(result) > 1) {
9008 pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9009 pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0));
9010 pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT));
9015 //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0));
9017 // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd));
9018 // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0));
9022 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++));
9023 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9026 pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0));
9033 if(aopIdx(AOP(result),0) != 4) {
9035 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9039 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9044 /* so dptr know contains the address */
9047 /* if bit then unpack */
9048 if (IS_BITVAR(retype))
9049 genPackBits(retype,right,"dptr",GPOINTER);
9051 size = AOP_SIZE(right);
9054 DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9058 pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset));
9059 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0));
9061 if (AOP_TYPE(right) == AOP_LIT)
9062 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9064 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9066 pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0));
9073 pic16_freeAsmop(right,NULL,ic,TRUE);
9074 pic16_freeAsmop(result,NULL,ic,TRUE);
9077 /*-----------------------------------------------------------------*/
9078 /* genPointerSet - stores the value into a pointer location */
9079 /*-----------------------------------------------------------------*/
9080 static void genPointerSet (iCode *ic)
9082 operand *right, *result ;
9083 sym_link *type, *etype;
9086 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9088 right = IC_RIGHT(ic);
9089 result = IC_RESULT(ic) ;
9091 /* depending on the type of pointer we need to
9092 move it to the correct pointer register */
9093 type = operandType(result);
9094 etype = getSpec(type);
9095 /* if left is of type of pointer then it is simple */
9096 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9097 p_type = DCL_TYPE(type);
9100 /* we have to go by the storage class */
9101 p_type = PTR_TYPE(SPEC_OCLS(etype));
9103 /* if (SPEC_OCLS(etype)->codesp ) { */
9104 /* p_type = CPOINTER ; */
9107 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9108 /* p_type = FPOINTER ; */
9110 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9111 /* p_type = PPOINTER ; */
9113 /* if (SPEC_OCLS(etype) == idata ) */
9114 /* p_type = IPOINTER ; */
9116 /* p_type = POINTER ; */
9119 /* now that we have the pointer type we assign
9120 the pointer values */
9125 genNearPointerSet (right,result,ic);
9129 genPagedPointerSet (right,result,ic);
9133 genFarPointerSet (right,result,ic);
9137 genGenPointerSet (right,result,ic);
9141 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9142 "genPointerSet: illegal pointer type");
9146 /*-----------------------------------------------------------------*/
9147 /* genIfx - generate code for Ifx statement */
9148 /*-----------------------------------------------------------------*/
9149 static void genIfx (iCode *ic, iCode *popIc)
9151 operand *cond = IC_COND(ic);
9154 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9156 pic16_aopOp(cond,ic,FALSE);
9158 /* get the value into acc */
9159 if (AOP_TYPE(cond) != AOP_CRY)
9160 pic16_toBoolean(cond);
9163 /* the result is now in the accumulator */
9164 pic16_freeAsmop(cond,NULL,ic,TRUE);
9166 /* if there was something to be popped then do it */
9170 /* if the condition is a bit variable */
9171 if (isbit && IS_ITEMP(cond) &&
9173 genIfxJump(ic,SPIL_LOC(cond)->rname);
9174 DEBUGpic16_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9177 if (isbit && !IS_ITEMP(cond))
9178 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9186 /*-----------------------------------------------------------------*/
9187 /* genAddrOf - generates code for address of */
9188 /*-----------------------------------------------------------------*/
9189 static void genAddrOf (iCode *ic)
9191 operand *right, *result, *left;
9194 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9197 //pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9199 pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
9200 pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9201 pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
9203 DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
9205 size = AOP_SIZE(IC_RESULT(ic));
9210 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset));
9211 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9216 pic16_freeAsmop(left,NULL,ic,FALSE);
9217 pic16_freeAsmop(result,NULL,ic,TRUE);
9222 /*-----------------------------------------------------------------*/
9223 /* genFarFarAssign - assignment when both are in far space */
9224 /*-----------------------------------------------------------------*/
9225 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9227 int size = AOP_SIZE(right);
9230 /* first push the right side on to the stack */
9232 l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE);
9234 pic16_emitcode ("push","acc");
9237 pic16_freeAsmop(right,NULL,ic,FALSE);
9238 /* now assign DPTR to result */
9239 pic16_aopOp(result,ic,FALSE);
9240 size = AOP_SIZE(result);
9242 pic16_emitcode ("pop","acc");
9243 pic16_aopPut(AOP(result),"a",--offset);
9245 pic16_freeAsmop(result,NULL,ic,FALSE);
9250 /*-----------------------------------------------------------------*/
9251 /* genAssign - generate code for assignment */
9252 /*-----------------------------------------------------------------*/
9253 static void genAssign (iCode *ic)
9255 operand *result, *right;
9256 int size, offset,know_W;
9257 unsigned long lit = 0L;
9259 result = IC_RESULT(ic);
9260 right = IC_RIGHT(ic) ;
9262 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9264 /* if they are the same */
9265 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9268 pic16_aopOp(right,ic,FALSE);
9269 pic16_aopOp(result,ic,TRUE);
9271 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9273 /* if they are the same registers */
9274 if (pic16_sameRegs(AOP(right),AOP(result)))
9277 /* if the result is a bit */
9278 if (AOP_TYPE(result) == AOP_CRY) {
9279 /* if the right size is a literal then
9280 we know what the value is */
9281 if (AOP_TYPE(right) == AOP_LIT) {
9283 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9284 pic16_popGet(AOP(result),0));
9286 if (((int) operandLitValue(right)))
9287 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9288 AOP(result)->aopu.aop_dir,
9289 AOP(result)->aopu.aop_dir);
9291 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9292 AOP(result)->aopu.aop_dir,
9293 AOP(result)->aopu.aop_dir);
9297 /* the right is also a bit variable */
9298 if (AOP_TYPE(right) == AOP_CRY) {
9299 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9300 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9301 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9303 pic16_emitcode("bcf","(%s >> 3),(%s & 7)",
9304 AOP(result)->aopu.aop_dir,
9305 AOP(result)->aopu.aop_dir);
9306 pic16_emitcode("btfsc","(%s >> 3),(%s & 7)",
9307 AOP(right)->aopu.aop_dir,
9308 AOP(right)->aopu.aop_dir);
9309 pic16_emitcode("bsf","(%s >> 3),(%s & 7)",
9310 AOP(result)->aopu.aop_dir,
9311 AOP(result)->aopu.aop_dir);
9316 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9317 pic16_toBoolean(right);
9319 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9320 //pic16_aopPut(AOP(result),"a",0);
9324 /* bit variables done */
9326 size = AOP_SIZE(result);
9328 if(AOP_TYPE(right) == AOP_LIT)
9329 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9331 /* VR - What is this?! */
9332 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9333 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9334 if(aopIdx(AOP(result),0) == 4) {
9335 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9336 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9337 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9340 DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9345 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9346 if(AOP_TYPE(right) == AOP_LIT) {
9348 if(know_W != (lit&0xff))
9349 pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff));
9351 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9353 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9357 } else if (AOP_TYPE(right) == AOP_CRY) {
9358 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9360 pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0));
9361 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9364 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9367 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It
9368 normally should work, but mind that thw W register live range
9369 is not checked, so if the code generator assumes that the W
9370 is already loaded after such a pair, wrong code will be generated.
9372 Checking the live range is the next step.
9373 This is experimental code yet and has not been fully tested yet.
9374 USE WITH CARE. Revert to old code by setting 0 to the condition above.
9375 Vangelis Rokas 030603 (vrokas@otenet.gr) */
9378 pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset));
9380 /* This is the old code, which is assumed(?!) that works fine(!?) */
9382 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9383 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9392 pic16_freeAsmop (right,NULL,ic,FALSE);
9393 pic16_freeAsmop (result,NULL,ic,TRUE);
9396 /*-----------------------------------------------------------------*/
9397 /* genJumpTab - generates code for jump table */
9398 /*-----------------------------------------------------------------*/
9399 static void genJumpTab (iCode *ic)
9404 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9406 pic16_aopOp(IC_JTCOND(ic),ic,FALSE);
9407 /* get the condition into accumulator */
9408 l = pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9410 /* multiply by three */
9411 pic16_emitcode("add","a,acc");
9412 pic16_emitcode("add","a,%s",pic16_aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9414 jtab = newiTempLabel(NULL);
9415 pic16_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9416 pic16_emitcode("jmp","@a+dptr");
9417 pic16_emitcode("","%05d_DS_:",jtab->key+100);
9419 pic16_emitpcode(POC_MOVLW, pic16_popGetLabel(jtab->key));
9420 pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(IC_JTCOND(ic)),0));
9422 pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_pclath));
9423 pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl));
9424 pic16_emitpLabel(jtab->key);
9426 pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9428 /* now generate the jump labels */
9429 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9430 jtab = setNextItem(IC_JTLABELS(ic))) {
9431 pic16_emitcode("ljmp","%05d_DS_",jtab->key+100);
9432 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(jtab->key));
9438 /*-----------------------------------------------------------------*/
9439 /* genMixedOperation - gen code for operators between mixed types */
9440 /*-----------------------------------------------------------------*/
9442 TSD - Written for the PIC port - but this unfortunately is buggy.
9443 This routine is good in that it is able to efficiently promote
9444 types to different (larger) sizes. Unfortunately, the temporary
9445 variables that are optimized out by this routine are sometimes
9446 used in other places. So until I know how to really parse the
9447 iCode tree, I'm going to not be using this routine :(.
9449 static int genMixedOperation (iCode *ic)
9452 operand *result = IC_RESULT(ic);
9453 sym_link *ctype = operandType(IC_LEFT(ic));
9454 operand *right = IC_RIGHT(ic);
9460 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9462 pic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9468 nextright = IC_RIGHT(nextic);
9469 nextleft = IC_LEFT(nextic);
9470 nextresult = IC_RESULT(nextic);
9472 pic16_aopOp(right,ic,FALSE);
9473 pic16_aopOp(result,ic,FALSE);
9474 pic16_aopOp(nextright, nextic, FALSE);
9475 pic16_aopOp(nextleft, nextic, FALSE);
9476 pic16_aopOp(nextresult, nextic, FALSE);
9478 if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9484 pic16_emitcode(";remove right +","");
9486 } else if (pic16_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9492 pic16_emitcode(";remove left +","");
9496 big = AOP_SIZE(nextleft);
9497 small = AOP_SIZE(nextright);
9499 switch(nextic->op) {
9502 pic16_emitcode(";optimize a +","");
9503 /* if unsigned or not an integral type */
9504 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9505 pic16_emitcode(";add a bit to something","");
9508 pic16_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9510 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9511 pic16_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9512 pic16_emitcode("movwf","%s",pic16_aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9514 pic16_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9522 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9523 pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9524 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9527 pic16_emitcode("movf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9529 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9530 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9531 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9532 pic16_emitcode(" incf","%s,w", pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9533 pic16_emitcode("movwf","%s", pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9536 pic16_emitcode("rlf","known_zero,w");
9543 if (!pic16_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9544 pic16_emitcode("addwf","%s,w",pic16_aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9545 pic16_emitcode("movwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9547 pic16_emitcode("addwf","%s,f",pic16_aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9557 pic16_freeAsmop(right,NULL,ic,TRUE);
9558 pic16_freeAsmop(result,NULL,ic,TRUE);
9559 pic16_freeAsmop(nextright,NULL,ic,TRUE);
9560 pic16_freeAsmop(nextleft,NULL,ic,TRUE);
9562 nextic->generated = 1;
9569 /*-----------------------------------------------------------------*/
9570 /* genCast - gen code for casting */
9571 /*-----------------------------------------------------------------*/
9572 static void genCast (iCode *ic)
9574 operand *result = IC_RESULT(ic);
9575 sym_link *ctype = operandType(IC_LEFT(ic));
9576 sym_link *rtype = operandType(IC_RIGHT(ic));
9577 operand *right = IC_RIGHT(ic);
9580 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9581 /* if they are equivalent then do nothing */
9582 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9585 pic16_aopOp(right,ic,FALSE) ;
9586 pic16_aopOp(result,ic,FALSE);
9588 DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
9590 /* if the result is a bit */
9591 if (AOP_TYPE(result) == AOP_CRY) {
9592 /* if the right size is a literal then
9593 we know what the value is */
9594 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9595 if (AOP_TYPE(right) == AOP_LIT) {
9597 pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9598 pic16_popGet(AOP(result),0));
9600 if (((int) operandLitValue(right)))
9601 pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
9602 AOP(result)->aopu.aop_dir,
9603 AOP(result)->aopu.aop_dir);
9605 pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
9606 AOP(result)->aopu.aop_dir,
9607 AOP(result)->aopu.aop_dir);
9612 /* the right is also a bit variable */
9613 if (AOP_TYPE(right) == AOP_CRY) {
9616 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9618 pic16_emitcode("clrc","");
9619 pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
9620 AOP(right)->aopu.aop_dir,
9621 AOP(right)->aopu.aop_dir);
9622 pic16_aopPut(AOP(result),"c",0);
9627 if (AOP_TYPE(right) == AOP_REG) {
9628 pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0));
9629 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
9630 pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0));
9632 pic16_toBoolean(right);
9633 pic16_aopPut(AOP(result),"a",0);
9637 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9639 size = AOP_SIZE(result);
9641 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9643 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
9644 pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0));
9645 pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0));
9648 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9653 /* if they are the same size : or less */
9654 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9656 /* if they are in the same place */
9657 if (pic16_sameRegs(AOP(right),AOP(result)))
9660 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9662 if (IS_PTR_CONST(rtype))
9664 if (IS_CODEPTR(rtype))
9666 DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
9668 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9670 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
9672 DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
9674 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9675 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
9676 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
9677 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
9678 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
9679 if(AOP_SIZE(result) <2)
9680 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9684 /* if they in different places then copy */
9685 size = AOP_SIZE(result);
9688 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9689 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9691 //pic16_aopPut(AOP(result),
9692 // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9702 /* if the result is of type pointer */
9703 if (IS_PTR(ctype)) {
9706 sym_link *type = operandType(right);
9707 sym_link *etype = getSpec(type);
9708 DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9710 /* pointer to generic pointer */
9711 if (IS_GENPTR(ctype)) {
9715 p_type = DCL_TYPE(type);
9717 /* we have to go by the storage class */
9718 p_type = PTR_TYPE(SPEC_OCLS(etype));
9720 /* if (SPEC_OCLS(etype)->codesp ) */
9721 /* p_type = CPOINTER ; */
9723 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9724 /* p_type = FPOINTER ; */
9726 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9727 /* p_type = PPOINTER; */
9729 /* if (SPEC_OCLS(etype) == idata ) */
9730 /* p_type = IPOINTER ; */
9732 /* p_type = POINTER ; */
9735 /* the first two bytes are known */
9736 DEBUGpic16_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9737 size = GPTRSIZE - 1;
9740 if(offset < AOP_SIZE(right)) {
9741 DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9742 if ((AOP_TYPE(right) == AOP_PCODE) &&
9743 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9744 pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset));
9745 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9747 pic16_aopPut(AOP(result),
9748 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9752 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset));
9755 /* the last byte depending on type */
9759 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1));
9762 pic16_emitcode(";BUG!? ","%d",__LINE__);
9766 pic16_emitcode(";BUG!? ","%d",__LINE__);
9770 pic16_emitcode(";BUG!? ","%d",__LINE__);
9775 /* this should never happen */
9776 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9777 "got unknown pointer type");
9780 //pic16_aopPut(AOP(result),l, GPTRSIZE - 1);
9784 /* just copy the pointers */
9785 size = AOP_SIZE(result);
9788 pic16_aopPut(AOP(result),
9789 pic16_aopGet(AOP(right),offset,FALSE,FALSE),
9798 /* so we now know that the size of destination is greater
9799 than the size of the source.
9800 Now, if the next iCode is an operator then we might be
9801 able to optimize the operation without performing a cast.
9803 if(genMixedOperation(ic))
9806 DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9808 /* we move to result for the size of source */
9809 size = AOP_SIZE(right);
9812 pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
9813 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
9817 /* now depending on the sign of the destination */
9818 size = AOP_SIZE(result) - AOP_SIZE(right);
9819 /* if unsigned or not an integral type */
9820 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9822 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++));
9824 /* we need to extend the sign :{ */
9827 /* Save one instruction of casting char to int */
9828 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset));
9829 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9830 pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset));
9832 pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg));
9835 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9837 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9839 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff));
9842 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset++));
9847 pic16_freeAsmop(right,NULL,ic,TRUE);
9848 pic16_freeAsmop(result,NULL,ic,TRUE);
9852 /*-----------------------------------------------------------------*/
9853 /* genDjnz - generate decrement & jump if not zero instrucion */
9854 /*-----------------------------------------------------------------*/
9855 static int genDjnz (iCode *ic, iCode *ifx)
9858 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9863 /* if the if condition has a false label
9864 then we cannot save */
9868 /* if the minus is not of the form
9870 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9871 !IS_OP_LITERAL(IC_RIGHT(ic)))
9874 if (operandLitValue(IC_RIGHT(ic)) != 1)
9877 /* if the size of this greater than one then no
9879 if (getSize(operandType(IC_RESULT(ic))) > 1)
9882 /* otherwise we can save BIG */
9883 lbl = newiTempLabel(NULL);
9884 lbl1= newiTempLabel(NULL);
9886 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9888 if (IS_AOP_PREG(IC_RESULT(ic))) {
9889 pic16_emitcode("dec","%s",
9890 pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9891 pic16_emitcode("mov","a,%s",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9892 pic16_emitcode("jnz","%05d_DS_",lbl->key+100);
9896 pic16_emitpcode(POC_DECFSZ,pic16_popGet(AOP(IC_RESULT(ic)),0));
9897 pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
9899 pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9900 pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9903 /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9904 /* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */
9905 /* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9906 /* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */
9909 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9914 /*-----------------------------------------------------------------*/
9915 /* genReceive - generate code for a receive iCode */
9916 /*-----------------------------------------------------------------*/
9917 static void genReceive (iCode *ic)
9919 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9921 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9922 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9923 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9925 int size = getSize(operandType(IC_RESULT(ic)));
9926 int offset = pic16_fReturnSizePic - size;
9928 pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ?
9929 fReturn[pic16_fReturnSizePic - offset - 1] : "acc"));
9932 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9933 size = AOP_SIZE(IC_RESULT(ic));
9936 pic16_emitcode ("pop","acc");
9937 pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9942 pic16_aopOp(IC_RESULT(ic),ic,FALSE);
9944 assignResultValue(IC_RESULT(ic));
9947 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9950 /*-----------------------------------------------------------------*/
9951 /* genDummyRead - generate code for dummy read of volatiles */
9952 /*-----------------------------------------------------------------*/
9954 genDummyRead (iCode * ic)
9956 pic16_emitcode ("; genDummyRead","");
9957 pic16_emitcode ("; not implemented","");
9962 /*-----------------------------------------------------------------*/
9963 /* genpic16Code - generate code for pic16 based controllers */
9964 /*-----------------------------------------------------------------*/
9966 * At this point, ralloc.c has gone through the iCode and attempted
9967 * to optimize in a way suitable for a PIC. Now we've got to generate
9968 * PIC instructions that correspond to the iCode.
9970 * Once the instructions are generated, we'll pass through both the
9971 * peep hole optimizer and the pCode optimizer.
9972 *-----------------------------------------------------------------*/
9974 void genpic16Code (iCode *lic)
9979 lineHead = lineCurr = NULL;
9981 pb = pic16_newpCodeChain(GcurMemmap,0,pic16_newpCodeCharP("; Starting pCode block"));
9982 pic16_addpBlock(pb);
9985 /* if debug information required */
9986 if (options.debug && currFunc) {
9988 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9990 if (IS_STATIC(currFunc->etype)) {
9991 pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9992 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name));
9994 pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9995 //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name));
10004 for (ic = lic ; ic ; ic = ic->next ) {
10006 // fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op);
10007 // DEBUGpic16_emitcode("; VR", "");
10008 DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op);
10009 if ( cln != ic->lineno ) {
10010 if ( options.debug ) {
10012 pic16_emitcode("",";C$%s$%d$%d$%d ==.",
10013 FileBaseName(ic->filename),ic->lineno,
10014 ic->level,ic->block);
10018 pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
10019 pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
10020 printCLine(ic->filename, ic->lineno));
10022 pic16_addpCode2pBlock(pb,
10023 pic16_newpCodeCSource(ic->lineno,
10025 printCLine(ic->filename, ic->lineno)));
10029 /* if the result is marked as
10030 spilt and rematerializable or code for
10031 this has already been generated then
10033 if (resultRemat(ic) || ic->generated )
10036 /* depending on the operation */
10055 /* IPOP happens only when trying to restore a
10056 spilt live range, if there is an ifx statement
10057 following this pop then the if statement might
10058 be using some of the registers being popped which
10059 would destroy the contents of the register so
10060 we need to check for this condition and handle it */
10062 ic->next->op == IFX &&
10063 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10064 genIfx (ic->next,ic);
10082 genEndFunction (ic);
10098 pic16_genPlus (ic) ;
10102 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10103 pic16_genMinus (ic);
10119 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10123 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10130 /* note these two are xlated by algebraic equivalence
10131 during parsing SDCC.y */
10132 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10133 "got '>=' or '<=' shouldn't have come here");
10137 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10149 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10153 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10157 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10181 genRightShift (ic);
10184 case GET_VALUE_AT_ADDRESS:
10189 if (POINTER_SET(ic))
10216 addSet(&_G.sendSet,ic);
10219 case DUMMY_READ_VOLATILE:
10229 /* now we are ready to call the
10230 peep hole optimizer */
10231 if (!options.nopeep) {
10232 peepHole (&lineHead);
10234 /* now do the actual printing */
10235 printLine (lineHead,codeOutFile);
10238 DFPRINTF((stderr,"printing pBlock\n\n"));
10239 pic16_printpBlock(stdout,pb);