1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
39 #ifdef HAVE_SYS_ISA_DEFS_H
40 #include <sys/isa_defs.h>
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
48 #if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
49 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
50 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
57 #include "SDCCpeeph.h"
63 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
64 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
65 void genMult8X8_8 (operand *, operand *,operand *);
67 static int labelOffset=0;
68 static int debug_verbose=1;
69 static int optimized_for_speed = 0;
71 /* max_key keeps track of the largest label number used in
72 a function. This is then used to adjust the label offset
73 for the next function.
76 static int GpsuedoStkPtr=0;
78 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
79 unsigned int pic14aopLiteral (value *val, int offset);
80 const char *AopType(short type);
81 static iCode *ifxForOp ( operand *op, iCode *ic );
83 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
85 /* this is the down and dirty file with all kinds of
86 kludgy & hacky stuff. This is what it is all about
87 CODE GENERATION for a specific MCU . some of the
88 routines may be reusable, will have to see */
90 static char *zero = "#0x00";
91 static char *one = "#0x01";
92 static char *spname = "sp";
94 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
95 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
96 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
97 static char **fReturn = fReturnpic14;
99 static char *accUse[] = {"a","b"};
101 //static short rbank = -1;
113 /* Resolved ifx structure. This structure stores information
114 about an iCode ifx that makes it easier to generate code.
116 typedef struct resolvedIfx {
117 symbol *lbl; /* pointer to a label */
118 int condition; /* true or false ifx */
119 int generated; /* set true when the code associated with the ifx
123 extern int pic14_ptrRegReq ;
124 extern int pic14_nRegs;
125 extern FILE *codeOutFile;
126 static void saverbank (int, iCode *,bool);
128 static lineNode *lineHead = NULL;
129 static lineNode *lineCurr = NULL;
131 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
132 0xE0, 0xC0, 0x80, 0x00};
133 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
134 0x07, 0x03, 0x01, 0x00};
138 /*-----------------------------------------------------------------*/
139 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
140 /* exponent of 2 is returned, otherwise -1 is */
142 /* note that this is similar to the function `powof2' in SDCCsymt */
146 /*-----------------------------------------------------------------*/
147 static int my_powof2 (unsigned long num)
150 if( (num & (num-1)) == 0) {
163 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
174 ((result) ? AOP_SIZE(result) : 0));
178 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
181 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
183 ((result) ? AopType(AOP_TYPE(result)) : "-"),
184 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
185 ((left) ? AopType(AOP_TYPE(left)) : "-"),
186 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
187 ((right) ? AopType(AOP_TYPE(right)) : "-"),
188 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
192 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
195 char lb[INITIAL_INLINEASM];
205 sprintf(lb,"%s\t",inst);
207 sprintf(lb,"%s",inst);
208 vsprintf(lb+(strlen(lb)),fmt,ap);
212 while (isspace(*lbp)) lbp++;
215 lineCurr = (lineCurr ?
216 connectLine(lineCurr,newLineNode(lb)) :
217 (lineHead = newLineNode(lb)));
218 lineCurr->isInline = _G.inLine;
219 lineCurr->isDebug = _G.debugLine;
221 addpCode2pBlock(pb,newpCodeCharP(lb));
227 void emitpLabel(int key)
229 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
232 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
236 addpCode2pBlock(pb,newpCode(poc,pcop));
238 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
241 void emitpcodeNULLop(PIC_OPCODE poc)
244 addpCode2pBlock(pb,newpCode(poc,NULL));
248 /*-----------------------------------------------------------------*/
249 /* pic14_emitcode - writes the code into a file : for now it is simple */
250 /*-----------------------------------------------------------------*/
251 void pic14_emitcode (char *inst,char *fmt, ...)
254 char lb[INITIAL_INLINEASM];
261 sprintf(lb,"%s\t",inst);
263 sprintf(lb,"%s",inst);
264 vsprintf(lb+(strlen(lb)),fmt,ap);
268 while (isspace(*lbp)) lbp++;
271 lineCurr = (lineCurr ?
272 connectLine(lineCurr,newLineNode(lb)) :
273 (lineHead = newLineNode(lb)));
274 lineCurr->isInline = _G.inLine;
275 lineCurr->isDebug = _G.debugLine;
278 addpCode2pBlock(pb,newpCodeCharP(lb));
284 /*-----------------------------------------------------------------*/
285 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
286 /*-----------------------------------------------------------------*/
287 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
289 bool r0iu = FALSE , r1iu = FALSE;
290 bool r0ou = FALSE , r1ou = FALSE;
292 /* the logic: if r0 & r1 used in the instruction
293 then we are in trouble otherwise */
295 /* first check if r0 & r1 are used by this
296 instruction, in which case we are in trouble */
297 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
298 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
303 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
304 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
306 /* if no usage of r0 then return it */
307 if (!r0iu && !r0ou) {
308 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
309 (*aopp)->type = AOP_R0;
311 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
314 /* if no usage of r1 then return it */
315 if (!r1iu && !r1ou) {
316 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
317 (*aopp)->type = AOP_R1;
319 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
322 /* now we know they both have usage */
323 /* if r0 not used in this instruction */
325 /* push it if not already pushed */
327 //pic14_emitcode ("push","%s",
328 // pic14_regWithIdx(R0_IDX)->dname);
332 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
333 (*aopp)->type = AOP_R0;
335 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
338 /* if r1 not used then */
341 /* push it if not already pushed */
343 //pic14_emitcode ("push","%s",
344 // pic14_regWithIdx(R1_IDX)->dname);
348 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
349 (*aopp)->type = AOP_R1;
350 return pic14_regWithIdx(R1_IDX);
354 /* I said end of world but not quite end of world yet */
355 /* if this is a result then we can push it on the stack*/
357 (*aopp)->type = AOP_STK;
361 /* other wise this is true end of the world */
362 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
363 "getFreePtr should never reach here");
367 /*-----------------------------------------------------------------*/
368 /* newAsmop - creates a new asmOp */
369 /*-----------------------------------------------------------------*/
370 asmop *newAsmop (short type)
374 aop = Safe_calloc(1,sizeof(asmop));
379 static void genSetDPTR(int n)
383 pic14_emitcode(";", "Select standard DPTR");
384 pic14_emitcode("mov", "dps, #0x00");
388 pic14_emitcode(";", "Select alternate DPTR");
389 pic14_emitcode("mov", "dps, #0x01");
393 /*-----------------------------------------------------------------*/
394 /* resolveIfx - converts an iCode ifx into a form more useful for */
395 /* generating code */
396 /*-----------------------------------------------------------------*/
397 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
402 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
404 resIfx->condition = 1; /* assume that the ifx is true */
405 resIfx->generated = 0; /* indicate that the ifx has not been used */
408 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
409 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
410 __FUNCTION__,__LINE__,resIfx->lbl->key);
413 resIfx->lbl = IC_TRUE(ifx);
415 resIfx->lbl = IC_FALSE(ifx);
416 resIfx->condition = 0;
419 DEBUGpic14_emitcode("; ***","ifx true is non-null");
421 DEBUGpic14_emitcode("; ***","ifx false is non-null");
424 DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
427 /*-----------------------------------------------------------------*/
428 /* pointerCode - returns the code for a pointer type */
429 /*-----------------------------------------------------------------*/
430 static int pointerCode (sym_link *etype)
433 return PTR_TYPE(SPEC_OCLS(etype));
437 /*-----------------------------------------------------------------*/
438 /* aopForSym - for a true symbol */
439 /*-----------------------------------------------------------------*/
440 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
443 memmap *space= SPEC_OCLS(sym->etype);
445 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
446 /* if already has one */
450 /* assign depending on the storage class */
451 /* if it is on the stack or indirectly addressable */
452 /* space we need to assign either r0 or r1 to it */
453 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
454 sym->aop = aop = newAsmop(0);
455 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
456 aop->size = getSize(sym->type);
458 /* now assign the address of the variable to
459 the pointer register */
460 if (aop->type != AOP_STK) {
464 pic14_emitcode("push","acc");
466 pic14_emitcode("mov","a,_bp");
467 pic14_emitcode("add","a,#0x%02x",
469 ((char)(sym->stack - _G.nRegsSaved )) :
470 ((char)sym->stack)) & 0xff);
471 pic14_emitcode("mov","%s,a",
472 aop->aopu.aop_ptr->name);
475 pic14_emitcode("pop","acc");
477 pic14_emitcode("mov","%s,#%s",
478 aop->aopu.aop_ptr->name,
480 aop->paged = space->paged;
482 aop->aopu.aop_stk = sym->stack;
486 if (sym->onStack && options.stack10bit)
488 /* It's on the 10 bit stack, which is located in
492 //DEBUGpic14_emitcode(";","%d",__LINE__);
495 pic14_emitcode("push","acc");
497 pic14_emitcode("mov","a,_bp");
498 pic14_emitcode("add","a,#0x%02x",
500 ((char)(sym->stack - _G.nRegsSaved )) :
501 ((char)sym->stack)) & 0xff);
504 pic14_emitcode ("mov","dpx1,#0x40");
505 pic14_emitcode ("mov","dph1,#0x00");
506 pic14_emitcode ("mov","dpl1, a");
510 pic14_emitcode("pop","acc");
512 sym->aop = aop = newAsmop(AOP_DPTR2);
513 aop->size = getSize(sym->type);
517 //DEBUGpic14_emitcode(";","%d",__LINE__);
518 /* if in bit space */
519 if (IN_BITSPACE(space)) {
520 sym->aop = aop = newAsmop (AOP_CRY);
521 aop->aopu.aop_dir = sym->rname ;
522 aop->size = getSize(sym->type);
523 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
526 /* if it is in direct space */
527 if (IN_DIRSPACE(space)) {
528 sym->aop = aop = newAsmop (AOP_DIR);
529 aop->aopu.aop_dir = sym->rname ;
530 aop->size = getSize(sym->type);
531 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
535 /* special case for a function */
536 if (IS_FUNC(sym->type)) {
537 sym->aop = aop = newAsmop(AOP_IMMD);
538 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
539 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
540 strcpy(aop->aopu.aop_immd,sym->rname);
541 aop->size = FPTRSIZE;
542 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
547 /* only remaining is far space */
548 /* in which case DPTR gets the address */
549 sym->aop = aop = newAsmop(AOP_PCODE);
551 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
552 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
553 PCOI(aop->aopu.pcop)->index = 0;
555 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
556 sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
558 allocDirReg (IC_LEFT(ic));
560 aop->size = FPTRSIZE;
562 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
563 sym->aop = aop = newAsmop(AOP_DPTR);
564 pic14_emitcode ("mov","dptr,#%s", sym->rname);
565 aop->size = getSize(sym->type);
567 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
570 /* if it is in code space */
571 if (IN_CODESPACE(space))
577 /*-----------------------------------------------------------------*/
578 /* aopForRemat - rematerialzes an object */
579 /*-----------------------------------------------------------------*/
580 static asmop *aopForRemat (operand *op) // x symbol *sym)
582 symbol *sym = OP_SYMBOL(op);
584 asmop *aop = newAsmop(AOP_PCODE);
588 ic = sym->rematiCode;
590 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
594 val += (int) operandLitValue(IC_RIGHT(ic));
595 } else if (ic->op == '-') {
596 val -= (int) operandLitValue(IC_RIGHT(ic));
600 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
603 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
604 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
605 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
606 PCOI(aop->aopu.pcop)->index = val;
608 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
609 OP_SYMBOL(IC_LEFT(ic))->rname,
610 val, IS_PTR_CONST(operandType(op)));
612 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
614 allocDirReg (IC_LEFT(ic));
619 int aopIdx (asmop *aop, int offset)
624 if(aop->type != AOP_REG)
627 return aop->aopu.aop_reg[offset]->rIdx;
630 /*-----------------------------------------------------------------*/
631 /* regsInCommon - two operands have some registers in common */
632 /*-----------------------------------------------------------------*/
633 static bool regsInCommon (operand *op1, operand *op2)
638 /* if they have registers in common */
639 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
642 sym1 = OP_SYMBOL(op1);
643 sym2 = OP_SYMBOL(op2);
645 if (sym1->nRegs == 0 || sym2->nRegs == 0)
648 for (i = 0 ; i < sym1->nRegs ; i++) {
653 for (j = 0 ; j < sym2->nRegs ;j++ ) {
657 if (sym2->regs[j] == sym1->regs[i])
665 /*-----------------------------------------------------------------*/
666 /* operandsEqu - equivalent */
667 /*-----------------------------------------------------------------*/
668 static bool operandsEqu ( operand *op1, operand *op2)
672 /* if they not symbols */
673 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
676 sym1 = OP_SYMBOL(op1);
677 sym2 = OP_SYMBOL(op2);
679 /* if both are itemps & one is spilt
680 and the other is not then false */
681 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
682 sym1->isspilt != sym2->isspilt )
685 /* if they are the same */
689 if (strcmp(sym1->rname,sym2->rname) == 0)
693 /* if left is a tmp & right is not */
697 (sym1->usl.spillLoc == sym2))
704 (sym2->usl.spillLoc == sym1))
710 /*-----------------------------------------------------------------*/
711 /* pic14_sameRegs - two asmops have the same registers */
712 /*-----------------------------------------------------------------*/
713 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
720 if (aop1->type != AOP_REG ||
721 aop2->type != AOP_REG )
724 if (aop1->size != aop2->size )
727 for (i = 0 ; i < aop1->size ; i++ )
728 if (aop1->aopu.aop_reg[i] !=
729 aop2->aopu.aop_reg[i] )
735 /*-----------------------------------------------------------------*/
736 /* aopOp - allocates an asmop for an operand : */
737 /*-----------------------------------------------------------------*/
738 void aopOp (operand *op, iCode *ic, bool result)
747 // DEBUGpic14_emitcode(";","%d",__LINE__);
748 /* if this a literal */
749 if (IS_OP_LITERAL(op)) {
750 op->aop = aop = newAsmop(AOP_LIT);
751 aop->aopu.aop_lit = op->operand.valOperand;
752 aop->size = getSize(operandType(op));
757 sym_link *type = operandType(op);
758 if(IS_PTR_CONST(type))
759 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
762 /* if already has a asmop then continue */
766 /* if the underlying symbol has a aop */
767 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
768 DEBUGpic14_emitcode(";","%d",__LINE__);
769 op->aop = OP_SYMBOL(op)->aop;
773 /* if this is a true symbol */
774 if (IS_TRUE_SYMOP(op)) {
775 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
776 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
780 /* this is a temporary : this has
786 e) can be a return use only */
791 /* if the type is a conditional */
792 if (sym->regType == REG_CND) {
793 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
798 /* if it is spilt then two situations
800 b) has a spill location */
801 if (sym->isspilt || sym->nRegs == 0) {
803 DEBUGpic14_emitcode(";","%d",__LINE__);
804 /* rematerialize it NOW */
807 sym->aop = op->aop = aop =
809 aop->size = getSize(sym->type);
810 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
816 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
817 aop->size = getSize(sym->type);
818 for ( i = 0 ; i < 2 ; i++ )
819 aop->aopu.aop_str[i] = accUse[i];
820 DEBUGpic14_emitcode(";","%d",__LINE__);
826 aop = op->aop = sym->aop = newAsmop(AOP_STR);
827 aop->size = getSize(sym->type);
828 for ( i = 0 ; i < fReturnSizePic ; i++ )
829 aop->aopu.aop_str[i] = fReturn[i];
830 DEBUGpic14_emitcode(";","%d",__LINE__);
834 /* else spill location */
835 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
836 /* force a new aop if sizes differ */
837 sym->usl.spillLoc->aop = NULL;
839 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
840 __FUNCTION__,__LINE__,
841 sym->usl.spillLoc->rname,
842 sym->rname, sym->usl.spillLoc->offset);
843 // X sym->aop = op->aop = aop = aopForSym(ic,sym->usl.spillLoc,result);
844 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
845 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
846 //allocDirReg (IC_LEFT(ic));
847 aop->size = getSize(sym->type);
853 sym_link *type = operandType(op);
854 if(IS_PTR_CONST(type))
855 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
858 /* must be in a register */
859 sym->aop = op->aop = aop = newAsmop(AOP_REG);
860 aop->size = sym->nRegs;
861 for ( i = 0 ; i < sym->nRegs ;i++)
862 aop->aopu.aop_reg[i] = sym->regs[i];
865 /*-----------------------------------------------------------------*/
866 /* freeAsmop - free up the asmop given to an operand */
867 /*----------------------------------------------------------------*/
868 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
885 /* depending on the asmop type only three cases need work AOP_RO
886 , AOP_R1 && AOP_STK */
892 pic14_emitcode ("pop","ar0");
896 bitVectUnSetBit(ic->rUsed,R0_IDX);
902 pic14_emitcode ("pop","ar1");
906 bitVectUnSetBit(ic->rUsed,R1_IDX);
912 int stk = aop->aopu.aop_stk + aop->size;
913 bitVectUnSetBit(ic->rUsed,R0_IDX);
914 bitVectUnSetBit(ic->rUsed,R1_IDX);
916 getFreePtr(ic,&aop,FALSE);
918 if (options.stack10bit)
920 /* I'm not sure what to do here yet... */
923 "*** Warning: probably generating bad code for "
924 "10 bit stack mode.\n");
928 pic14_emitcode ("mov","a,_bp");
929 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
930 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
932 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
936 pic14_emitcode("pop","acc");
937 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
939 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
942 freeAsmop(op,NULL,ic,TRUE);
944 pic14_emitcode("pop","ar0");
949 pic14_emitcode("pop","ar1");
957 /* all other cases just dealloc */
961 OP_SYMBOL(op)->aop = NULL;
962 /* if the symbol has a spill */
964 SPIL_LOC(op)->aop = NULL;
969 /*-----------------------------------------------------------------*/
970 /* aopGet - for fetching value of the aop */
971 /*-----------------------------------------------------------------*/
972 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
977 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
978 /* offset is greater than
980 if (offset > (aop->size - 1) &&
981 aop->type != AOP_LIT)
984 /* depending on type */
989 DEBUGpic14_emitcode(";","%d",__LINE__);
990 /* if we need to increment it */
991 while (offset > aop->coff) {
992 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
996 while (offset < aop->coff) {
997 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1001 aop->coff = offset ;
1003 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1004 return (dname ? "acc" : "a");
1006 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1007 rs = Safe_calloc(1,strlen(s)+1);
1013 DEBUGpic14_emitcode(";","%d",__LINE__);
1014 if (aop->type == AOP_DPTR2)
1019 while (offset > aop->coff) {
1020 pic14_emitcode ("inc","dptr");
1024 while (offset < aop->coff) {
1025 pic14_emitcode("lcall","__decdptr");
1031 pic14_emitcode("clr","a");
1032 pic14_emitcode("movc","a,@a+dptr");
1035 pic14_emitcode("movx","a,@dptr");
1038 if (aop->type == AOP_DPTR2)
1043 return (dname ? "acc" : "a");
1048 sprintf (s,"%s",aop->aopu.aop_immd);
1051 sprintf(s,"(%s >> %d)",
1056 aop->aopu.aop_immd);
1057 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1058 rs = Safe_calloc(1,strlen(s)+1);
1064 sprintf(s,"(%s + %d)",
1067 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1069 sprintf(s,"%s",aop->aopu.aop_dir);
1070 rs = Safe_calloc(1,strlen(s)+1);
1076 // return aop->aopu.aop_reg[offset]->dname;
1078 return aop->aopu.aop_reg[offset]->name;
1081 //pic14_emitcode(";","%d",__LINE__);
1082 return aop->aopu.aop_dir;
1085 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1086 return "AOP_accumulator_bug";
1089 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1090 rs = Safe_calloc(1,strlen(s)+1);
1095 DEBUGpic14_emitcode(";","%d",__LINE__);
1096 aop->coff = offset ;
1097 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1101 return aop->aopu.aop_str[offset];
1105 pCodeOp *pcop = aop->aopu.pcop;
1106 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE",__LINE__);
1108 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1109 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1110 sprintf(s,"%s", pcop->name);
1112 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1115 rs = Safe_calloc(1,strlen(s)+1);
1121 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1122 "aopget got unsupported aop->type");
1127 /*-----------------------------------------------------------------*/
1128 /* popGetTempReg - create a new temporary pCodeOp */
1129 /*-----------------------------------------------------------------*/
1130 pCodeOp *popGetTempReg(void)
1135 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1136 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1137 PCOR(pcop)->r->wasUsed=1;
1138 PCOR(pcop)->r->isFree=0;
1144 /*-----------------------------------------------------------------*/
1145 /* popGetTempReg - create a new temporary pCodeOp */
1146 /*-----------------------------------------------------------------*/
1147 void popReleaseTempReg(pCodeOp *pcop)
1150 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1151 PCOR(pcop)->r->isFree = 1;
1154 /*-----------------------------------------------------------------*/
1155 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1156 /*-----------------------------------------------------------------*/
1157 pCodeOp *popGetLabel(unsigned int key)
1160 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1165 return newpCodeOpLabel(NULL,key+100+labelOffset);
1168 /*-----------------------------------------------------------------*/
1169 /* popCopyReg - copy a pcode operator */
1170 /*-----------------------------------------------------------------*/
1171 pCodeOp *popCopyReg(pCodeOpReg *pc)
1175 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1176 pcor->pcop.type = pc->pcop.type;
1178 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1179 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1181 pcor->pcop.name = NULL;
1184 pcor->rIdx = pc->rIdx;
1187 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1191 /*-----------------------------------------------------------------*/
1192 /* popGet - asm operator to pcode operator conversion */
1193 /*-----------------------------------------------------------------*/
1194 pCodeOp *popGetLit(unsigned int lit)
1197 return newpCodeOpLit(lit);
1201 /*-----------------------------------------------------------------*/
1202 /* popGetImmd - asm operator to pcode immediate conversion */
1203 /*-----------------------------------------------------------------*/
1204 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1207 return newpCodeOpImmd(name, offset,index, 0);
1211 /*-----------------------------------------------------------------*/
1212 /* popGet - asm operator to pcode operator conversion */
1213 /*-----------------------------------------------------------------*/
1214 pCodeOp *popGetWithString(char *str)
1220 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1224 pcop = newpCodeOp(str,PO_STR);
1229 pCodeOp *popRegFromString(char *str)
1232 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOp) );
1233 pcop->type = PO_DIR;
1235 DEBUGpic14_emitcode(";","%d",__LINE__);
1236 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1241 pCodeOp *popRegFromIdx(int rIdx)
1245 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1246 __FUNCTION__,__LINE__,rIdx);
1248 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1250 PCOR(pcop)->rIdx = rIdx;
1251 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1252 PCOR(pcop)->r->isFree = 0;
1253 PCOR(pcop)->r->wasUsed = 1;
1255 pcop->type = PCOR(pcop)->r->pc_type;
1260 /*-----------------------------------------------------------------*/
1261 /* popGet - asm operator to pcode operator conversion */
1262 /*-----------------------------------------------------------------*/
1263 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1265 //char *s = buffer ;
1270 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1271 /* offset is greater than
1274 if (offset > (aop->size - 1) &&
1275 aop->type != AOP_LIT)
1276 return NULL; //zero;
1278 /* depending on type */
1279 switch (aop->type) {
1286 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1290 DEBUGpic14_emitcode(";","%d",__LINE__);
1291 return popGetImmd(aop->aopu.aop_immd,offset,0);
1294 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295 pcop->type = PO_DIR;
1299 sprintf(s,"(%s + %d)",
1303 sprintf(s,"%s",aop->aopu.aop_dir);
1304 pcop->name = Safe_calloc(1,strlen(s)+1);
1305 strcpy(pcop->name,s);
1307 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1308 strcpy(pcop->name,aop->aopu.aop_dir);
1309 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1310 if(PCOR(pcop)->r == NULL) {
1311 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1312 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1315 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1316 PCOR(pcop)->instance = offset;
1322 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1324 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1325 PCOR(pcop)->rIdx = rIdx;
1326 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1327 PCOR(pcop)->instance = offset;
1328 pcop->type = PCOR(pcop)->r->pc_type;
1329 //rs = aop->aopu.aop_reg[offset]->name;
1330 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1335 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1336 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1337 //if(PCOR(pcop)->r == NULL)
1338 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1342 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1345 DEBUGpic14_emitcode(";","%d",__LINE__);
1346 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1348 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1349 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1350 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1351 pcop->type = PCOR(pcop)->r->pc_type;
1352 pcop->name = PCOR(pcop)->r->name;
1358 DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__);
1359 pcop = pCodeOpCopy(aop->aopu.pcop);
1360 PCOI(pcop)->offset = offset;
1364 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1365 "popGet got unsupported aop->type");
1368 /*-----------------------------------------------------------------*/
1369 /* aopPut - puts a string for a aop */
1370 /*-----------------------------------------------------------------*/
1371 void aopPut (asmop *aop, char *s, int offset)
1376 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1378 if (aop->size && offset > ( aop->size - 1)) {
1379 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1380 "aopPut got offset > aop->size");
1384 /* will assign value to value */
1385 /* depending on where it is ofcourse */
1386 switch (aop->type) {
1389 sprintf(d,"(%s + %d)",
1390 aop->aopu.aop_dir,offset);
1391 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1394 sprintf(d,"%s",aop->aopu.aop_dir);
1397 DEBUGpic14_emitcode(";","%d",__LINE__);
1399 pic14_emitcode("movf","%s,w",s);
1400 pic14_emitcode("movwf","%s",d);
1403 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1404 if(offset >= aop->size) {
1405 emitpcode(POC_CLRF,popGet(aop,offset));
1408 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1411 emitpcode(POC_MOVWF,popGet(aop,offset));
1418 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1419 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1422 strcmp(s,"r0") == 0 ||
1423 strcmp(s,"r1") == 0 ||
1424 strcmp(s,"r2") == 0 ||
1425 strcmp(s,"r3") == 0 ||
1426 strcmp(s,"r4") == 0 ||
1427 strcmp(s,"r5") == 0 ||
1428 strcmp(s,"r6") == 0 ||
1429 strcmp(s,"r7") == 0 )
1430 pic14_emitcode("mov","%s,%s ; %d",
1431 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1436 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1438 pic14_emitcode("movwf","%s",
1439 aop->aopu.aop_reg[offset]->name);
1442 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1443 pcop->type = PO_GPR_REGISTER;
1445 PCOR(pcop)->rIdx = -1;
1446 PCOR(pcop)->r = NULL;
1448 DEBUGpic14_emitcode(";","%d",__LINE__);
1449 pcop->name = Safe_strdup(s);
1450 emitpcode(POC_MOVFW,pcop);
1452 emitpcode(POC_MOVWF,popGet(aop,offset));
1460 if (aop->type == AOP_DPTR2)
1466 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1467 "aopPut writting to code space");
1471 while (offset > aop->coff) {
1473 pic14_emitcode ("inc","dptr");
1476 while (offset < aop->coff) {
1478 pic14_emitcode("lcall","__decdptr");
1483 /* if not in accumulater */
1486 pic14_emitcode ("movx","@dptr,a");
1488 if (aop->type == AOP_DPTR2)
1496 while (offset > aop->coff) {
1498 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1500 while (offset < aop->coff) {
1502 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1508 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1513 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1515 if (strcmp(s,"r0") == 0 ||
1516 strcmp(s,"r1") == 0 ||
1517 strcmp(s,"r2") == 0 ||
1518 strcmp(s,"r3") == 0 ||
1519 strcmp(s,"r4") == 0 ||
1520 strcmp(s,"r5") == 0 ||
1521 strcmp(s,"r6") == 0 ||
1522 strcmp(s,"r7") == 0 ) {
1524 sprintf(buffer,"a%s",s);
1525 pic14_emitcode("mov","@%s,%s",
1526 aop->aopu.aop_ptr->name,buffer);
1528 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1533 if (strcmp(s,"a") == 0)
1534 pic14_emitcode("push","acc");
1536 pic14_emitcode("push","%s",s);
1541 /* if bit variable */
1542 if (!aop->aopu.aop_dir) {
1543 pic14_emitcode("clr","a");
1544 pic14_emitcode("rlc","a");
1547 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1550 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1553 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1555 lbl = newiTempLabel(NULL);
1557 if (strcmp(s,"a")) {
1560 pic14_emitcode("clr","c");
1561 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1562 pic14_emitcode("cpl","c");
1563 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1564 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1571 if (strcmp(aop->aopu.aop_str[offset],s))
1572 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1577 if (!offset && (strcmp(s,"acc") == 0))
1580 if (strcmp(aop->aopu.aop_str[offset],s))
1581 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1585 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1586 "aopPut got unsupported aop->type");
1592 /*-----------------------------------------------------------------*/
1593 /* reAdjustPreg - points a register back to where it should */
1594 /*-----------------------------------------------------------------*/
1595 static void reAdjustPreg (asmop *aop)
1599 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1601 if ((size = aop->size) <= 1)
1604 switch (aop->type) {
1608 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1612 if (aop->type == AOP_DPTR2)
1618 pic14_emitcode("lcall","__decdptr");
1621 if (aop->type == AOP_DPTR2)
1631 /*-----------------------------------------------------------------*/
1632 /* genNotFloat - generates not for float operations */
1633 /*-----------------------------------------------------------------*/
1634 static void genNotFloat (operand *op, operand *res)
1640 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1641 /* we will put 127 in the first byte of
1643 aopPut(AOP(res),"#127",0);
1644 size = AOP_SIZE(op) - 1;
1647 l = aopGet(op->aop,offset++,FALSE,FALSE);
1651 pic14_emitcode("orl","a,%s",
1653 offset++,FALSE,FALSE));
1655 tlbl = newiTempLabel(NULL);
1657 tlbl = newiTempLabel(NULL);
1658 aopPut(res->aop,one,1);
1659 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1660 aopPut(res->aop,zero,1);
1661 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1663 size = res->aop->size - 2;
1665 /* put zeros in the rest */
1667 aopPut(res->aop,zero,offset++);
1671 /*-----------------------------------------------------------------*/
1672 /* opIsGptr: returns non-zero if the passed operand is */
1673 /* a generic pointer type. */
1674 /*-----------------------------------------------------------------*/
1675 static int opIsGptr(operand *op)
1677 sym_link *type = operandType(op);
1679 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1680 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1688 /*-----------------------------------------------------------------*/
1689 /* pic14_getDataSize - get the operand data size */
1690 /*-----------------------------------------------------------------*/
1691 int pic14_getDataSize(operand *op)
1693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1696 return AOP_SIZE(op);
1698 // tsd- in the pic port, the genptr size is 1, so this code here
1699 // fails. ( in the 8051 port, the size was 4).
1702 size = AOP_SIZE(op);
1703 if (size == GPTRSIZE)
1705 sym_link *type = operandType(op);
1706 if (IS_GENPTR(type))
1708 /* generic pointer; arithmetic operations
1709 * should ignore the high byte (pointer type).
1712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1719 /*-----------------------------------------------------------------*/
1720 /* pic14_outAcc - output Acc */
1721 /*-----------------------------------------------------------------*/
1722 void pic14_outAcc(operand *result)
1725 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1726 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1729 size = pic14_getDataSize(result);
1731 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1734 /* unsigned or positive */
1736 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1741 /*-----------------------------------------------------------------*/
1742 /* pic14_outBitC - output a bit C */
1743 /*-----------------------------------------------------------------*/
1744 void pic14_outBitC(operand *result)
1747 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1748 /* if the result is bit */
1749 if (AOP_TYPE(result) == AOP_CRY)
1750 aopPut(AOP(result),"c",0);
1752 pic14_emitcode("clr","a ; %d", __LINE__);
1753 pic14_emitcode("rlc","a");
1754 pic14_outAcc(result);
1758 /*-----------------------------------------------------------------*/
1759 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1760 /*-----------------------------------------------------------------*/
1761 void pic14_toBoolean(operand *oper)
1763 int size = AOP_SIZE(oper) - 1;
1766 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1768 if ( AOP_TYPE(oper) != AOP_ACC) {
1769 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1772 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1777 /*-----------------------------------------------------------------*/
1778 /* genNot - generate code for ! operation */
1779 /*-----------------------------------------------------------------*/
1780 static void genNot (iCode *ic)
1783 sym_link *optype = operandType(IC_LEFT(ic));
1786 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1787 /* assign asmOps to operand & result */
1788 aopOp (IC_LEFT(ic),ic,FALSE);
1789 aopOp (IC_RESULT(ic),ic,TRUE);
1791 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1792 /* if in bit space then a special case */
1793 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1794 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1795 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1796 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1798 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1799 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1800 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1805 /* if type float then do float */
1806 if (IS_FLOAT(optype)) {
1807 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1811 size = AOP_SIZE(IC_RESULT(ic));
1813 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1814 emitpcode(POC_ANDLW,popGetLit(1));
1815 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1818 pic14_toBoolean(IC_LEFT(ic));
1820 tlbl = newiTempLabel(NULL);
1821 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1822 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1823 pic14_outBitC(IC_RESULT(ic));
1826 /* release the aops */
1827 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1828 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1832 /*-----------------------------------------------------------------*/
1833 /* genCpl - generate code for complement */
1834 /*-----------------------------------------------------------------*/
1835 static void genCpl (iCode *ic)
1841 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1842 /* assign asmOps to operand & result */
1843 aopOp (IC_LEFT(ic),ic,FALSE);
1844 aopOp (IC_RESULT(ic),ic,TRUE);
1846 /* if both are in bit space then
1848 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1849 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1851 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1852 pic14_emitcode("cpl","c");
1853 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1857 size = AOP_SIZE(IC_RESULT(ic));
1859 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1861 pic14_emitcode("cpl","a");
1862 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1867 /* release the aops */
1868 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1869 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1872 /*-----------------------------------------------------------------*/
1873 /* genUminusFloat - unary minus for floating points */
1874 /*-----------------------------------------------------------------*/
1875 static void genUminusFloat(operand *op,operand *result)
1877 int size ,offset =0 ;
1880 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1881 /* for this we just need to flip the
1882 first it then copy the rest in place */
1883 size = AOP_SIZE(op) - 1;
1884 l = aopGet(AOP(op),3,FALSE,FALSE);
1888 pic14_emitcode("cpl","acc.7");
1889 aopPut(AOP(result),"a",3);
1893 aopGet(AOP(op),offset,FALSE,FALSE),
1899 /*-----------------------------------------------------------------*/
1900 /* genUminus - unary minus code generation */
1901 /*-----------------------------------------------------------------*/
1902 static void genUminus (iCode *ic)
1905 sym_link *optype, *rtype;
1908 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1910 aopOp(IC_LEFT(ic),ic,FALSE);
1911 aopOp(IC_RESULT(ic),ic,TRUE);
1913 /* if both in bit space then special
1915 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1916 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1918 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1919 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1920 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1925 optype = operandType(IC_LEFT(ic));
1926 rtype = operandType(IC_RESULT(ic));
1928 /* if float then do float stuff */
1929 if (IS_FLOAT(optype)) {
1930 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1934 /* otherwise subtract from zero by taking the 2's complement */
1935 size = AOP_SIZE(IC_LEFT(ic));
1937 for(i=0; i<size; i++) {
1938 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1939 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1941 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1942 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1946 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1947 for(i=1; i<size; i++) {
1949 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1953 /* release the aops */
1954 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1955 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1958 /*-----------------------------------------------------------------*/
1959 /* saveRegisters - will look for a call and save the registers */
1960 /*-----------------------------------------------------------------*/
1961 static void saveRegisters(iCode *lic)
1968 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1970 for (ic = lic ; ic ; ic = ic->next)
1971 if (ic->op == CALL || ic->op == PCALL)
1975 fprintf(stderr,"found parameter push with no function call\n");
1979 /* if the registers have been saved already then
1981 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1984 /* find the registers in use at this time
1985 and push them away to safety */
1986 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1990 if (options.useXstack) {
1991 if (bitVectBitValue(rsave,R0_IDX))
1992 pic14_emitcode("mov","b,r0");
1993 pic14_emitcode("mov","r0,%s",spname);
1994 for (i = 0 ; i < pic14_nRegs ; i++) {
1995 if (bitVectBitValue(rsave,i)) {
1997 pic14_emitcode("mov","a,b");
1999 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2000 pic14_emitcode("movx","@r0,a");
2001 pic14_emitcode("inc","r0");
2004 pic14_emitcode("mov","%s,r0",spname);
2005 if (bitVectBitValue(rsave,R0_IDX))
2006 pic14_emitcode("mov","r0,b");
2008 //for (i = 0 ; i < pic14_nRegs ; i++) {
2009 // if (bitVectBitValue(rsave,i))
2010 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2013 dtype = operandType(IC_LEFT(ic));
2014 if (currFunc && dtype &&
2015 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2016 IFFUNC_ISISR(currFunc->type) &&
2019 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2022 /*-----------------------------------------------------------------*/
2023 /* unsaveRegisters - pop the pushed registers */
2024 /*-----------------------------------------------------------------*/
2025 static void unsaveRegisters (iCode *ic)
2030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2031 /* find the registers in use at this time
2032 and push them away to safety */
2033 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2036 if (options.useXstack) {
2037 pic14_emitcode("mov","r0,%s",spname);
2038 for (i = pic14_nRegs ; i >= 0 ; i--) {
2039 if (bitVectBitValue(rsave,i)) {
2040 pic14_emitcode("dec","r0");
2041 pic14_emitcode("movx","a,@r0");
2043 pic14_emitcode("mov","b,a");
2045 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2049 pic14_emitcode("mov","%s,r0",spname);
2050 if (bitVectBitValue(rsave,R0_IDX))
2051 pic14_emitcode("mov","r0,b");
2053 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2054 // if (bitVectBitValue(rsave,i))
2055 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2061 /*-----------------------------------------------------------------*/
2063 /*-----------------------------------------------------------------*/
2064 static void pushSide(operand * oper, int size)
2068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2070 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2071 if (AOP_TYPE(oper) != AOP_REG &&
2072 AOP_TYPE(oper) != AOP_DIR &&
2074 pic14_emitcode("mov","a,%s",l);
2075 pic14_emitcode("push","acc");
2077 pic14_emitcode("push","%s",l);
2082 /*-----------------------------------------------------------------*/
2083 /* assignResultValue - */
2084 /*-----------------------------------------------------------------*/
2085 static void assignResultValue(operand * oper)
2087 int size = AOP_SIZE(oper);
2089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2091 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2093 if(!GpsuedoStkPtr) {
2094 /* The last byte in the assignment is in W */
2096 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2101 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2103 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2108 /*-----------------------------------------------------------------*/
2109 /* genIpush - genrate code for pushing this gets a little complex */
2110 /*-----------------------------------------------------------------*/
2111 static void genIpush (iCode *ic)
2114 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2116 int size, offset = 0 ;
2120 /* if this is not a parm push : ie. it is spill push
2121 and spill push is always done on the local stack */
2122 if (!ic->parmPush) {
2124 /* and the item is spilt then do nothing */
2125 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2128 aopOp(IC_LEFT(ic),ic,FALSE);
2129 size = AOP_SIZE(IC_LEFT(ic));
2130 /* push it on the stack */
2132 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2137 pic14_emitcode("push","%s",l);
2142 /* this is a paramter push: in this case we call
2143 the routine to find the call and save those
2144 registers that need to be saved */
2147 /* then do the push */
2148 aopOp(IC_LEFT(ic),ic,FALSE);
2151 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2152 size = AOP_SIZE(IC_LEFT(ic));
2155 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2156 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2157 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2159 pic14_emitcode("mov","a,%s",l);
2160 pic14_emitcode("push","acc");
2162 pic14_emitcode("push","%s",l);
2165 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2169 /*-----------------------------------------------------------------*/
2170 /* genIpop - recover the registers: can happen only for spilling */
2171 /*-----------------------------------------------------------------*/
2172 static void genIpop (iCode *ic)
2174 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2179 /* if the temp was not pushed then */
2180 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2183 aopOp(IC_LEFT(ic),ic,FALSE);
2184 size = AOP_SIZE(IC_LEFT(ic));
2187 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2190 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2194 /*-----------------------------------------------------------------*/
2195 /* unsaverbank - restores the resgister bank from stack */
2196 /*-----------------------------------------------------------------*/
2197 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2199 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2207 if (options.useXstack) {
2209 r = getFreePtr(ic,&aop,FALSE);
2212 pic14_emitcode("mov","%s,_spx",r->name);
2213 pic14_emitcode("movx","a,@%s",r->name);
2214 pic14_emitcode("mov","psw,a");
2215 pic14_emitcode("dec","%s",r->name);
2218 pic14_emitcode ("pop","psw");
2221 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2222 if (options.useXstack) {
2223 pic14_emitcode("movx","a,@%s",r->name);
2224 //pic14_emitcode("mov","(%s+%d),a",
2225 // regspic14[i].base,8*bank+regspic14[i].offset);
2226 pic14_emitcode("dec","%s",r->name);
2229 pic14_emitcode("pop",""); //"(%s+%d)",
2230 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2233 if (options.useXstack) {
2235 pic14_emitcode("mov","_spx,%s",r->name);
2236 freeAsmop(NULL,aop,ic,TRUE);
2242 /*-----------------------------------------------------------------*/
2243 /* saverbank - saves an entire register bank on the stack */
2244 /*-----------------------------------------------------------------*/
2245 static void saverbank (int bank, iCode *ic, bool pushPsw)
2247 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2254 if (options.useXstack) {
2257 r = getFreePtr(ic,&aop,FALSE);
2258 pic14_emitcode("mov","%s,_spx",r->name);
2262 for (i = 0 ; i < pic14_nRegs ;i++) {
2263 if (options.useXstack) {
2264 pic14_emitcode("inc","%s",r->name);
2265 //pic14_emitcode("mov","a,(%s+%d)",
2266 // regspic14[i].base,8*bank+regspic14[i].offset);
2267 pic14_emitcode("movx","@%s,a",r->name);
2269 pic14_emitcode("push","");// "(%s+%d)",
2270 //regspic14[i].base,8*bank+regspic14[i].offset);
2274 if (options.useXstack) {
2275 pic14_emitcode("mov","a,psw");
2276 pic14_emitcode("movx","@%s,a",r->name);
2277 pic14_emitcode("inc","%s",r->name);
2278 pic14_emitcode("mov","_spx,%s",r->name);
2279 freeAsmop (NULL,aop,ic,TRUE);
2282 pic14_emitcode("push","psw");
2284 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2290 /*-----------------------------------------------------------------*/
2291 /* genCall - generates a call statement */
2292 /*-----------------------------------------------------------------*/
2293 static void genCall (iCode *ic)
2297 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2299 /* if caller saves & we have not saved then */
2303 /* if we are calling a function that is not using
2304 the same register bank then we need to save the
2305 destination registers on the stack */
2306 dtype = operandType(IC_LEFT(ic));
2307 if (currFunc && dtype &&
2308 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2309 IFFUNC_ISISR(currFunc->type) &&
2312 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2314 /* if send set is not empty the assign */
2317 /* For the Pic port, there is no data stack.
2318 * So parameters passed to functions are stored
2319 * in registers. (The pCode optimizer will get
2320 * rid of most of these :).
2322 int psuedoStkPtr=-1;
2323 int firstTimeThruLoop = 1;
2325 _G.sendSet = reverseSet(_G.sendSet);
2327 /* First figure how many parameters are getting passed */
2328 for (sic = setFirstItem(_G.sendSet) ; sic ;
2329 sic = setNextItem(_G.sendSet)) {
2331 aopOp(IC_LEFT(sic),sic,FALSE);
2332 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2333 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2336 for (sic = setFirstItem(_G.sendSet) ; sic ;
2337 sic = setNextItem(_G.sendSet)) {
2338 int size, offset = 0;
2340 aopOp(IC_LEFT(sic),sic,FALSE);
2341 size = AOP_SIZE(IC_LEFT(sic));
2345 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2346 AopType(AOP_TYPE(IC_LEFT(sic))));
2348 if(!firstTimeThruLoop) {
2349 /* If this is not the first time we've been through the loop
2350 * then we need to save the parameter in a temporary
2351 * register. The last byte of the last parameter is
2353 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2356 firstTimeThruLoop=0;
2358 //if (strcmp(l,fReturn[offset])) {
2360 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2361 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2362 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2364 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2369 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2374 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2375 OP_SYMBOL(IC_LEFT(ic))->rname :
2376 OP_SYMBOL(IC_LEFT(ic))->name));
2379 /* if we need assign a result value */
2380 if ((IS_ITEMP(IC_RESULT(ic)) &&
2381 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2382 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2383 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2386 aopOp(IC_RESULT(ic),ic,FALSE);
2389 assignResultValue(IC_RESULT(ic));
2391 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2392 AopType(AOP_TYPE(IC_RESULT(ic))));
2394 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2397 /* adjust the stack for parameters if
2399 if (ic->parmBytes) {
2401 if (ic->parmBytes > 3) {
2402 pic14_emitcode("mov","a,%s",spname);
2403 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2404 pic14_emitcode("mov","%s,a",spname);
2406 for ( i = 0 ; i < ic->parmBytes ;i++)
2407 pic14_emitcode("dec","%s",spname);
2411 /* if register bank was saved then pop them */
2413 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2415 /* if we hade saved some registers then unsave them */
2416 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2417 unsaveRegisters (ic);
2422 /*-----------------------------------------------------------------*/
2423 /* genPcall - generates a call by pointer statement */
2424 /*-----------------------------------------------------------------*/
2425 static void genPcall (iCode *ic)
2428 symbol *rlbl = newiTempLabel(NULL);
2431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2432 /* if caller saves & we have not saved then */
2436 /* if we are calling a function that is not using
2437 the same register bank then we need to save the
2438 destination registers on the stack */
2439 dtype = operandType(IC_LEFT(ic));
2440 if (currFunc && dtype &&
2441 IFFUNC_ISISR(currFunc->type) &&
2442 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2443 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2446 /* push the return address on to the stack */
2447 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2448 pic14_emitcode("push","acc");
2449 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2450 pic14_emitcode("push","acc");
2452 if (options.model == MODEL_FLAT24)
2454 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2455 pic14_emitcode("push","acc");
2458 /* now push the calling address */
2459 aopOp(IC_LEFT(ic),ic,FALSE);
2461 pushSide(IC_LEFT(ic), FPTRSIZE);
2463 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2465 /* if send set is not empty the assign */
2469 for (sic = setFirstItem(_G.sendSet) ; sic ;
2470 sic = setNextItem(_G.sendSet)) {
2471 int size, offset = 0;
2472 aopOp(IC_LEFT(sic),sic,FALSE);
2473 size = AOP_SIZE(IC_LEFT(sic));
2475 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2477 if (strcmp(l,fReturn[offset]))
2478 pic14_emitcode("mov","%s,%s",
2483 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2488 pic14_emitcode("ret","");
2489 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2492 /* if we need assign a result value */
2493 if ((IS_ITEMP(IC_RESULT(ic)) &&
2494 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2495 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2496 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2499 aopOp(IC_RESULT(ic),ic,FALSE);
2502 assignResultValue(IC_RESULT(ic));
2504 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2507 /* adjust the stack for parameters if
2509 if (ic->parmBytes) {
2511 if (ic->parmBytes > 3) {
2512 pic14_emitcode("mov","a,%s",spname);
2513 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2514 pic14_emitcode("mov","%s,a",spname);
2516 for ( i = 0 ; i < ic->parmBytes ;i++)
2517 pic14_emitcode("dec","%s",spname);
2521 /* if register bank was saved then unsave them */
2522 if (currFunc && dtype &&
2523 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2524 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2526 /* if we hade saved some registers then
2529 unsaveRegisters (ic);
2533 /*-----------------------------------------------------------------*/
2534 /* resultRemat - result is rematerializable */
2535 /*-----------------------------------------------------------------*/
2536 static int resultRemat (iCode *ic)
2538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2539 if (SKIP_IC(ic) || ic->op == IFX)
2542 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2543 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2544 if (sym->remat && !POINTER_SET(ic))
2551 #if defined(__BORLANDC__) || defined(_MSC_VER)
2552 #define STRCASECMP stricmp
2554 #define STRCASECMP strcasecmp
2558 /*-----------------------------------------------------------------*/
2559 /* inExcludeList - return 1 if the string is in exclude Reg list */
2560 /*-----------------------------------------------------------------*/
2561 static bool inExcludeList(char *s)
2563 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2567 if (options.excludeRegs[i] &&
2568 STRCASECMP(options.excludeRegs[i],"none") == 0)
2571 for ( i = 0 ; options.excludeRegs[i]; i++) {
2572 if (options.excludeRegs[i] &&
2573 STRCASECMP(s,options.excludeRegs[i]) == 0)
2580 /*-----------------------------------------------------------------*/
2581 /* genFunction - generated code for function entry */
2582 /*-----------------------------------------------------------------*/
2583 static void genFunction (iCode *ic)
2588 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2590 labelOffset += (max_key+4);
2594 /* create the function header */
2595 pic14_emitcode(";","-----------------------------------------");
2596 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2597 pic14_emitcode(";","-----------------------------------------");
2599 pic14_emitcode("","%s:",sym->rname);
2600 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2602 ftype = operandType(IC_LEFT(ic));
2604 /* if critical function then turn interrupts off */
2605 if (IFFUNC_ISCRITICAL(ftype))
2606 pic14_emitcode("clr","ea");
2608 /* here we need to generate the equates for the
2609 register bank if required */
2611 if (FUNC_REGBANK(ftype) != rbank) {
2614 rbank = FUNC_REGBANK(ftype);
2615 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2616 if (strcmp(regspic14[i].base,"0") == 0)
2617 pic14_emitcode("","%s = 0x%02x",
2619 8*rbank+regspic14[i].offset);
2621 pic14_emitcode ("","%s = %s + 0x%02x",
2624 8*rbank+regspic14[i].offset);
2629 /* if this is an interrupt service routine then
2630 save acc, b, dpl, dph */
2631 if (IFFUNC_ISISR(sym->type)) {
2632 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2633 emitpcodeNULLop(POC_NOP);
2634 emitpcodeNULLop(POC_NOP);
2635 emitpcodeNULLop(POC_NOP);
2636 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2637 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2638 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2639 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2641 pBlockConvert2ISR(pb);
2643 if (!inExcludeList("acc"))
2644 pic14_emitcode ("push","acc");
2645 if (!inExcludeList("b"))
2646 pic14_emitcode ("push","b");
2647 if (!inExcludeList("dpl"))
2648 pic14_emitcode ("push","dpl");
2649 if (!inExcludeList("dph"))
2650 pic14_emitcode ("push","dph");
2651 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2653 pic14_emitcode ("push", "dpx");
2654 /* Make sure we're using standard DPTR */
2655 pic14_emitcode ("push", "dps");
2656 pic14_emitcode ("mov", "dps, #0x00");
2657 if (options.stack10bit)
2659 /* This ISR could conceivably use DPTR2. Better save it. */
2660 pic14_emitcode ("push", "dpl1");
2661 pic14_emitcode ("push", "dph1");
2662 pic14_emitcode ("push", "dpx1");
2665 /* if this isr has no bank i.e. is going to
2666 run with bank 0 , then we need to save more
2668 if (!FUNC_REGBANK(sym->type)) {
2670 /* if this function does not call any other
2671 function then we can be economical and
2672 save only those registers that are used */
2673 if (! IFFUNC_HASFCALL(sym->type)) {
2676 /* if any registers used */
2677 if (sym->regsUsed) {
2678 /* save the registers used */
2679 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2680 if (bitVectBitValue(sym->regsUsed,i) ||
2681 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2682 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2687 /* this function has a function call cannot
2688 determines register usage so we will have the
2690 saverbank(0,ic,FALSE);
2695 /* if callee-save to be used for this function
2696 then save the registers being used in this function */
2697 if (IFFUNC_CALLEESAVES(sym->type)) {
2700 /* if any registers used */
2701 if (sym->regsUsed) {
2702 /* save the registers used */
2703 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2704 if (bitVectBitValue(sym->regsUsed,i) ||
2705 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2706 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2714 /* set the register bank to the desired value */
2715 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2716 pic14_emitcode("push","psw");
2717 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2720 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2722 if (options.useXstack) {
2723 pic14_emitcode("mov","r0,%s",spname);
2724 pic14_emitcode("mov","a,_bp");
2725 pic14_emitcode("movx","@r0,a");
2726 pic14_emitcode("inc","%s",spname);
2730 /* set up the stack */
2731 pic14_emitcode ("push","_bp"); /* save the callers stack */
2733 pic14_emitcode ("mov","_bp,%s",spname);
2736 /* adjust the stack for the function */
2741 werror(W_STACK_OVERFLOW,sym->name);
2743 if (i > 3 && sym->recvSize < 4) {
2745 pic14_emitcode ("mov","a,sp");
2746 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2747 pic14_emitcode ("mov","sp,a");
2752 pic14_emitcode("inc","sp");
2757 pic14_emitcode ("mov","a,_spx");
2758 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2759 pic14_emitcode ("mov","_spx,a");
2764 /*-----------------------------------------------------------------*/
2765 /* genEndFunction - generates epilogue for functions */
2766 /*-----------------------------------------------------------------*/
2767 static void genEndFunction (iCode *ic)
2769 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2771 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2773 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2775 pic14_emitcode ("mov","%s,_bp",spname);
2778 /* if use external stack but some variables were
2779 added to the local stack then decrement the
2781 if (options.useXstack && sym->stack) {
2782 pic14_emitcode("mov","a,sp");
2783 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2784 pic14_emitcode("mov","sp,a");
2788 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2789 if (options.useXstack) {
2790 pic14_emitcode("mov","r0,%s",spname);
2791 pic14_emitcode("movx","a,@r0");
2792 pic14_emitcode("mov","_bp,a");
2793 pic14_emitcode("dec","%s",spname);
2797 pic14_emitcode ("pop","_bp");
2801 /* restore the register bank */
2802 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2803 pic14_emitcode ("pop","psw");
2805 if (IFFUNC_ISISR(sym->type)) {
2807 /* now we need to restore the registers */
2808 /* if this isr has no bank i.e. is going to
2809 run with bank 0 , then we need to save more
2811 if (!FUNC_REGBANK(sym->type)) {
2813 /* if this function does not call any other
2814 function then we can be economical and
2815 save only those registers that are used */
2816 if (! IFFUNC_HASFCALL(sym->type)) {
2819 /* if any registers used */
2820 if (sym->regsUsed) {
2821 /* save the registers used */
2822 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2823 if (bitVectBitValue(sym->regsUsed,i) ||
2824 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2825 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2830 /* this function has a function call cannot
2831 determines register usage so we will have the
2833 unsaverbank(0,ic,FALSE);
2837 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2839 if (options.stack10bit)
2841 pic14_emitcode ("pop", "dpx1");
2842 pic14_emitcode ("pop", "dph1");
2843 pic14_emitcode ("pop", "dpl1");
2845 pic14_emitcode ("pop", "dps");
2846 pic14_emitcode ("pop", "dpx");
2848 if (!inExcludeList("dph"))
2849 pic14_emitcode ("pop","dph");
2850 if (!inExcludeList("dpl"))
2851 pic14_emitcode ("pop","dpl");
2852 if (!inExcludeList("b"))
2853 pic14_emitcode ("pop","b");
2854 if (!inExcludeList("acc"))
2855 pic14_emitcode ("pop","acc");
2857 if (IFFUNC_ISCRITICAL(sym->type))
2858 pic14_emitcode("setb","ea");
2861 /* if debug then send end of function */
2862 /* if (options.debug && currFunc) { */
2865 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2866 FileBaseName(ic->filename),currFunc->lastLine,
2867 ic->level,ic->block);
2868 if (IS_STATIC(currFunc->etype))
2869 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2871 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2875 pic14_emitcode ("reti","");
2877 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2878 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2879 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2880 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2881 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2882 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2884 emitpcodeNULLop(POC_RETFIE);
2888 if (IFFUNC_ISCRITICAL(sym->type))
2889 pic14_emitcode("setb","ea");
2891 if (IFFUNC_CALLEESAVES(sym->type)) {
2894 /* if any registers used */
2895 if (sym->regsUsed) {
2896 /* save the registers used */
2897 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2898 if (bitVectBitValue(sym->regsUsed,i) ||
2899 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2900 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2906 /* if debug then send end of function */
2909 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2910 FileBaseName(ic->filename),currFunc->lastLine,
2911 ic->level,ic->block);
2912 if (IS_STATIC(currFunc->etype))
2913 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2915 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2919 pic14_emitcode ("return","");
2920 emitpcodeNULLop(POC_RETURN);
2922 /* Mark the end of a function */
2923 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2928 /*-----------------------------------------------------------------*/
2929 /* genRet - generate code for return statement */
2930 /*-----------------------------------------------------------------*/
2931 static void genRet (iCode *ic)
2933 int size,offset = 0 , pushed = 0;
2935 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2936 /* if we have no return value then
2937 just generate the "ret" */
2941 /* we have something to return then
2942 move the return value into place */
2943 aopOp(IC_LEFT(ic),ic,FALSE);
2944 size = AOP_SIZE(IC_LEFT(ic));
2948 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2950 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2952 pic14_emitcode("push","%s",l);
2955 l = aopGet(AOP(IC_LEFT(ic)),offset,
2957 if (strcmp(fReturn[offset],l)) {
2958 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2959 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2960 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2962 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2965 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2966 pic14_emitcode("movwf","%s",fReturn[offset]);
2976 if (strcmp(fReturn[pushed],"a"))
2977 pic14_emitcode("pop",fReturn[pushed]);
2979 pic14_emitcode("pop","acc");
2982 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2985 /* generate a jump to the return label
2986 if the next is not the return statement */
2987 if (!(ic->next && ic->next->op == LABEL &&
2988 IC_LABEL(ic->next) == returnLabel)) {
2990 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2991 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2996 /*-----------------------------------------------------------------*/
2997 /* genLabel - generates a label */
2998 /*-----------------------------------------------------------------*/
2999 static void genLabel (iCode *ic)
3001 /* special case never generate */
3002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3003 if (IC_LABEL(ic) == entryLabel)
3006 emitpLabel(IC_LABEL(ic)->key);
3007 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3010 /*-----------------------------------------------------------------*/
3011 /* genGoto - generates a goto */
3012 /*-----------------------------------------------------------------*/
3014 static void genGoto (iCode *ic)
3016 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3017 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3021 /*-----------------------------------------------------------------*/
3022 /* genMultbits :- multiplication of bits */
3023 /*-----------------------------------------------------------------*/
3024 static void genMultbits (operand *left,
3028 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3030 if(!pic14_sameRegs(AOP(result),AOP(right)))
3031 emitpcode(POC_BSF, popGet(AOP(result),0));
3033 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3034 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3035 emitpcode(POC_BCF, popGet(AOP(result),0));
3040 /*-----------------------------------------------------------------*/
3041 /* genMultOneByte : 8 bit multiplication & division */
3042 /*-----------------------------------------------------------------*/
3043 static void genMultOneByte (operand *left,
3047 sym_link *opetype = operandType(result);
3052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3053 DEBUGpic14_AopType(__LINE__,left,right,result);
3054 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3056 /* (if two literals, the value is computed before) */
3057 /* if one literal, literal on the right */
3058 if (AOP_TYPE(left) == AOP_LIT){
3064 size = AOP_SIZE(result);
3067 if (AOP_TYPE(right) == AOP_LIT){
3068 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3069 aopGet(AOP(right),0,FALSE,FALSE),
3070 aopGet(AOP(left),0,FALSE,FALSE),
3071 aopGet(AOP(result),0,FALSE,FALSE));
3072 pic14_emitcode("call","genMultLit");
3074 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3075 aopGet(AOP(right),0,FALSE,FALSE),
3076 aopGet(AOP(left),0,FALSE,FALSE),
3077 aopGet(AOP(result),0,FALSE,FALSE));
3078 pic14_emitcode("call","genMult8X8_8");
3081 genMult8X8_8 (left, right,result);
3084 /* signed or unsigned */
3085 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3086 //l = aopGet(AOP(left),0,FALSE,FALSE);
3088 //pic14_emitcode("mul","ab");
3089 /* if result size = 1, mul signed = mul unsigned */
3090 //aopPut(AOP(result),"a",0);
3092 } else { // (size > 1)
3094 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3095 aopGet(AOP(right),0,FALSE,FALSE),
3096 aopGet(AOP(left),0,FALSE,FALSE),
3097 aopGet(AOP(result),0,FALSE,FALSE));
3099 if (SPEC_USIGN(opetype)){
3100 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3101 genUMult8X8_16 (left, right, result, NULL);
3104 /* for filling the MSBs */
3105 emitpcode(POC_CLRF, popGet(AOP(result),2));
3106 emitpcode(POC_CLRF, popGet(AOP(result),3));
3110 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3112 pic14_emitcode("mov","a,b");
3114 /* adjust the MSB if left or right neg */
3116 /* if one literal */
3117 if (AOP_TYPE(right) == AOP_LIT){
3118 pic14_emitcode("multiply ","right is a lit");
3119 /* AND literal negative */
3120 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3121 /* adjust MSB (c==0 after mul) */
3122 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3126 genSMult8X8_16 (left, right, result, NULL);
3130 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3132 pic14_emitcode("rlc","a");
3133 pic14_emitcode("subb","a,acc");
3141 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3142 //aopPut(AOP(result),"a",offset++);
3146 /*-----------------------------------------------------------------*/
3147 /* genMult - generates code for multiplication */
3148 /*-----------------------------------------------------------------*/
3149 static void genMult (iCode *ic)
3151 operand *left = IC_LEFT(ic);
3152 operand *right = IC_RIGHT(ic);
3153 operand *result= IC_RESULT(ic);
3155 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3156 /* assign the amsops */
3157 aopOp (left,ic,FALSE);
3158 aopOp (right,ic,FALSE);
3159 aopOp (result,ic,TRUE);
3161 DEBUGpic14_AopType(__LINE__,left,right,result);
3163 /* special cases first */
3165 if (AOP_TYPE(left) == AOP_CRY &&
3166 AOP_TYPE(right)== AOP_CRY) {
3167 genMultbits(left,right,result);
3171 /* if both are of size == 1 */
3172 if (AOP_SIZE(left) == 1 &&
3173 AOP_SIZE(right) == 1 ) {
3174 genMultOneByte(left,right,result);
3178 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3180 /* should have been converted to function call */
3184 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3185 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3186 freeAsmop(result,NULL,ic,TRUE);
3189 /*-----------------------------------------------------------------*/
3190 /* genDivbits :- division of bits */
3191 /*-----------------------------------------------------------------*/
3192 static void genDivbits (operand *left,
3199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3200 /* the result must be bit */
3201 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3202 l = aopGet(AOP(left),0,FALSE,FALSE);
3206 pic14_emitcode("div","ab");
3207 pic14_emitcode("rrc","a");
3208 aopPut(AOP(result),"c",0);
3211 /*-----------------------------------------------------------------*/
3212 /* genDivOneByte : 8 bit division */
3213 /*-----------------------------------------------------------------*/
3214 static void genDivOneByte (operand *left,
3218 sym_link *opetype = operandType(result);
3223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3224 size = AOP_SIZE(result) - 1;
3226 /* signed or unsigned */
3227 if (SPEC_USIGN(opetype)) {
3228 /* unsigned is easy */
3229 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3230 l = aopGet(AOP(left),0,FALSE,FALSE);
3232 pic14_emitcode("div","ab");
3233 aopPut(AOP(result),"a",0);
3235 aopPut(AOP(result),zero,offset++);
3239 /* signed is a little bit more difficult */
3241 /* save the signs of the operands */
3242 l = aopGet(AOP(left),0,FALSE,FALSE);
3244 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3245 pic14_emitcode("push","acc"); /* save it on the stack */
3247 /* now sign adjust for both left & right */
3248 l = aopGet(AOP(right),0,FALSE,FALSE);
3250 lbl = newiTempLabel(NULL);
3251 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3252 pic14_emitcode("cpl","a");
3253 pic14_emitcode("inc","a");
3254 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3255 pic14_emitcode("mov","b,a");
3257 /* sign adjust left side */
3258 l = aopGet(AOP(left),0,FALSE,FALSE);
3261 lbl = newiTempLabel(NULL);
3262 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3263 pic14_emitcode("cpl","a");
3264 pic14_emitcode("inc","a");
3265 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3267 /* now the division */
3268 pic14_emitcode("div","ab");
3269 /* we are interested in the lower order
3271 pic14_emitcode("mov","b,a");
3272 lbl = newiTempLabel(NULL);
3273 pic14_emitcode("pop","acc");
3274 /* if there was an over flow we don't
3275 adjust the sign of the result */
3276 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3277 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3279 pic14_emitcode("clr","a");
3280 pic14_emitcode("subb","a,b");
3281 pic14_emitcode("mov","b,a");
3282 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3284 /* now we are done */
3285 aopPut(AOP(result),"b",0);
3287 pic14_emitcode("mov","c,b.7");
3288 pic14_emitcode("subb","a,acc");
3291 aopPut(AOP(result),"a",offset++);
3295 /*-----------------------------------------------------------------*/
3296 /* genDiv - generates code for division */
3297 /*-----------------------------------------------------------------*/
3298 static void genDiv (iCode *ic)
3300 operand *left = IC_LEFT(ic);
3301 operand *right = IC_RIGHT(ic);
3302 operand *result= IC_RESULT(ic);
3304 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3305 /* assign the amsops */
3306 aopOp (left,ic,FALSE);
3307 aopOp (right,ic,FALSE);
3308 aopOp (result,ic,TRUE);
3310 /* special cases first */
3312 if (AOP_TYPE(left) == AOP_CRY &&
3313 AOP_TYPE(right)== AOP_CRY) {
3314 genDivbits(left,right,result);
3318 /* if both are of size == 1 */
3319 if (AOP_SIZE(left) == 1 &&
3320 AOP_SIZE(right) == 1 ) {
3321 genDivOneByte(left,right,result);
3325 /* should have been converted to function call */
3328 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3329 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3330 freeAsmop(result,NULL,ic,TRUE);
3333 /*-----------------------------------------------------------------*/
3334 /* genModbits :- modulus of bits */
3335 /*-----------------------------------------------------------------*/
3336 static void genModbits (operand *left,
3343 /* the result must be bit */
3344 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3345 l = aopGet(AOP(left),0,FALSE,FALSE);
3349 pic14_emitcode("div","ab");
3350 pic14_emitcode("mov","a,b");
3351 pic14_emitcode("rrc","a");
3352 aopPut(AOP(result),"c",0);
3355 /*-----------------------------------------------------------------*/
3356 /* genModOneByte : 8 bit modulus */
3357 /*-----------------------------------------------------------------*/
3358 static void genModOneByte (operand *left,
3362 sym_link *opetype = operandType(result);
3366 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3367 /* signed or unsigned */
3368 if (SPEC_USIGN(opetype)) {
3369 /* unsigned is easy */
3370 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3371 l = aopGet(AOP(left),0,FALSE,FALSE);
3373 pic14_emitcode("div","ab");
3374 aopPut(AOP(result),"b",0);
3378 /* signed is a little bit more difficult */
3380 /* save the signs of the operands */
3381 l = aopGet(AOP(left),0,FALSE,FALSE);
3384 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3385 pic14_emitcode("push","acc"); /* save it on the stack */
3387 /* now sign adjust for both left & right */
3388 l = aopGet(AOP(right),0,FALSE,FALSE);
3391 lbl = newiTempLabel(NULL);
3392 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3393 pic14_emitcode("cpl","a");
3394 pic14_emitcode("inc","a");
3395 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3396 pic14_emitcode("mov","b,a");
3398 /* sign adjust left side */
3399 l = aopGet(AOP(left),0,FALSE,FALSE);
3402 lbl = newiTempLabel(NULL);
3403 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3404 pic14_emitcode("cpl","a");
3405 pic14_emitcode("inc","a");
3406 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3408 /* now the multiplication */
3409 pic14_emitcode("div","ab");
3410 /* we are interested in the lower order
3412 lbl = newiTempLabel(NULL);
3413 pic14_emitcode("pop","acc");
3414 /* if there was an over flow we don't
3415 adjust the sign of the result */
3416 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3417 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3419 pic14_emitcode("clr","a");
3420 pic14_emitcode("subb","a,b");
3421 pic14_emitcode("mov","b,a");
3422 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3424 /* now we are done */
3425 aopPut(AOP(result),"b",0);
3429 /*-----------------------------------------------------------------*/
3430 /* genMod - generates code for division */
3431 /*-----------------------------------------------------------------*/
3432 static void genMod (iCode *ic)
3434 operand *left = IC_LEFT(ic);
3435 operand *right = IC_RIGHT(ic);
3436 operand *result= IC_RESULT(ic);
3438 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3439 /* assign the amsops */
3440 aopOp (left,ic,FALSE);
3441 aopOp (right,ic,FALSE);
3442 aopOp (result,ic,TRUE);
3444 /* special cases first */
3446 if (AOP_TYPE(left) == AOP_CRY &&
3447 AOP_TYPE(right)== AOP_CRY) {
3448 genModbits(left,right,result);
3452 /* if both are of size == 1 */
3453 if (AOP_SIZE(left) == 1 &&
3454 AOP_SIZE(right) == 1 ) {
3455 genModOneByte(left,right,result);
3459 /* should have been converted to function call */
3463 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3464 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3465 freeAsmop(result,NULL,ic,TRUE);
3468 /*-----------------------------------------------------------------*/
3469 /* genIfxJump :- will create a jump depending on the ifx */
3470 /*-----------------------------------------------------------------*/
3472 note: May need to add parameter to indicate when a variable is in bit space.
3474 static void genIfxJump (iCode *ic, char *jval)
3477 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3478 /* if true label then we jump if condition
3480 if ( IC_TRUE(ic) ) {
3482 if(strcmp(jval,"a") == 0)
3484 else if (strcmp(jval,"c") == 0)
3487 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3488 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3491 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3492 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3496 /* false label is present */
3497 if(strcmp(jval,"a") == 0)
3499 else if (strcmp(jval,"c") == 0)
3502 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3503 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3506 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3507 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3512 /* mark the icode as generated */
3516 /*-----------------------------------------------------------------*/
3518 /*-----------------------------------------------------------------*/
3519 static void genSkip(iCode *ifx,int status_bit)
3524 if ( IC_TRUE(ifx) ) {
3525 switch(status_bit) {
3540 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3541 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3545 switch(status_bit) {
3559 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3560 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3566 /*-----------------------------------------------------------------*/
3568 /*-----------------------------------------------------------------*/
3569 static void genSkipc(resolvedIfx *rifx)
3579 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3580 rifx->generated = 1;
3583 /*-----------------------------------------------------------------*/
3585 /*-----------------------------------------------------------------*/
3586 static void genSkipz2(resolvedIfx *rifx)
3596 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3597 rifx->generated = 1;
3600 /*-----------------------------------------------------------------*/
3602 /*-----------------------------------------------------------------*/
3603 static void genSkipz(iCode *ifx, int condition)
3614 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3616 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3619 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3621 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3624 /*-----------------------------------------------------------------*/
3626 /*-----------------------------------------------------------------*/
3627 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3633 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3635 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3638 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3639 rifx->generated = 1;
3643 /*-----------------------------------------------------------------*/
3644 /* genChkZeroes :- greater or less than comparison */
3645 /* For each byte in a literal that is zero, inclusive or the */
3646 /* the corresponding byte in the operand with W */
3647 /* returns true if any of the bytes are zero */
3648 /*-----------------------------------------------------------------*/
3649 static int genChkZeroes(operand *op, int lit, int size)
3656 i = (lit >> (size*8)) & 0xff;
3660 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3662 emitpcode(POC_IORFW, popGet(AOP(op),size));
3671 /*-----------------------------------------------------------------*/
3672 /* genCmp :- greater or less than comparison */
3673 /*-----------------------------------------------------------------*/
3674 static void genCmp (operand *left,operand *right,
3675 operand *result, iCode *ifx, int sign)
3677 int size; //, offset = 0 ;
3678 unsigned long lit = 0L,i = 0;
3679 resolvedIfx rFalseIfx;
3680 // resolvedIfx rTrueIfx;
3682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3684 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3685 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3689 resolveIfx(&rFalseIfx,ifx);
3690 truelbl = newiTempLabel(NULL);
3692 //if(IC_TRUE(ifx) == NULL)
3693 /* if left & right are bit variables */
3694 if (AOP_TYPE(left) == AOP_CRY &&
3695 AOP_TYPE(right) == AOP_CRY ) {
3696 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3697 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3699 /* subtract right from left if at the
3700 end the carry flag is set then we know that
3701 left is greater than right */
3702 size = max(AOP_SIZE(left),AOP_SIZE(right));
3704 /* if unsigned char cmp with lit, do cjne left,#right,zz */
3705 //if((size == 1) && !sign &&
3706 // (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){
3707 // symbol *lbl = newiTempLabel(NULL);
3708 // pic14_emitcode("cjne","%s,%s,%05d_DS_",
3709 // aopGet(AOP(left),offset,FALSE,FALSE),
3710 // aopGet(AOP(right),offset,FALSE,FALSE),
3712 //pic14_emitcode("","%05d_DS_:",lbl->key+100);
3716 symbol *lbl = newiTempLabel(NULL);
3718 if(AOP_TYPE(right) == AOP_LIT) {
3720 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3722 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3729 genSkipCond(&rFalseIfx,left,size-1,7);
3731 /* no need to compare to 0...*/
3732 /* NOTE: this is a de-generate compare that most certainly
3733 * creates some dead code. */
3734 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3736 if(ifx) ifx->generated = 1;
3743 //i = (lit >> (size*8)) & 0xff;
3744 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3746 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3748 i = ((0-lit) & 0xff);
3751 /* lit is 0x7f, all signed chars are less than
3752 * this except for 0x7f itself */
3753 emitpcode(POC_XORLW, popGetLit(0x7f));
3754 genSkipz2(&rFalseIfx);
3756 emitpcode(POC_ADDLW, popGetLit(0x80));
3757 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3758 genSkipc(&rFalseIfx);
3762 emitpcode(POC_ADDLW, popGetLit(i));
3763 genSkipc(&rFalseIfx);
3767 if(ifx) ifx->generated = 1;
3771 /* chars are out of the way. now do ints and longs */
3774 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3781 genSkipCond(&rFalseIfx,left,size,7);
3782 if(ifx) ifx->generated = 1;
3787 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3789 //rFalseIfx.condition ^= 1;
3790 //genSkipCond(&rFalseIfx,left,size,7);
3791 //rFalseIfx.condition ^= 1;
3793 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3794 if(rFalseIfx.condition)
3795 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3797 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3799 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3800 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3801 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3804 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3806 if(rFalseIfx.condition) {
3808 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3814 genSkipc(&rFalseIfx);
3815 emitpLabel(truelbl->key);
3816 if(ifx) ifx->generated = 1;
3823 if( (lit & 0xff) == 0) {
3824 /* lower byte is zero */
3825 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3826 i = ((lit >> 8) & 0xff) ^0x80;
3827 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3828 emitpcode(POC_ADDLW, popGetLit( 0x80));
3829 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3830 genSkipc(&rFalseIfx);
3833 if(ifx) ifx->generated = 1;
3838 /* Special cases for signed longs */
3839 if( (lit & 0xffffff) == 0) {
3840 /* lower byte is zero */
3841 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3842 i = ((lit >> 8*3) & 0xff) ^0x80;
3843 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3844 emitpcode(POC_ADDLW, popGetLit( 0x80));
3845 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3846 genSkipc(&rFalseIfx);
3849 if(ifx) ifx->generated = 1;
3857 if(lit & (0x80 << (size*8))) {
3858 /* lit is negative */
3859 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3861 //genSkipCond(&rFalseIfx,left,size,7);
3863 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3865 if(rFalseIfx.condition)
3866 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3868 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3872 /* lit is positive */
3873 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3874 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3875 if(rFalseIfx.condition)
3876 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3878 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3880 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3881 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3882 //rFalseIfx.condition ^= 1;
3883 //genSkipCond(&rFalseIfx,left,size,7);
3884 //rFalseIfx.condition ^= 1;
3888 This works, but is only good for ints.
3889 It also requires a "known zero" register.
3890 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3891 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3892 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3893 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3894 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3895 genSkipc(&rFalseIfx);
3897 emitpLabel(truelbl->key);
3898 if(ifx) ifx->generated = 1;
3902 /* There are no more special cases, so perform a general compare */
3904 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3905 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3909 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3911 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3913 //rFalseIfx.condition ^= 1;
3914 genSkipc(&rFalseIfx);
3916 emitpLabel(truelbl->key);
3918 if(ifx) ifx->generated = 1;
3925 /* sign is out of the way. So now do an unsigned compare */
3926 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3929 //genChkZeroes(left)
3931 /* General case - compare to an unsigned literal on the right.*/
3933 i = (lit >> (size*8)) & 0xff;
3934 emitpcode(POC_MOVLW, popGetLit(i));
3935 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3937 i = (lit >> (size*8)) & 0xff;
3940 emitpcode(POC_MOVLW, popGetLit(i));
3942 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3944 /* this byte of the lit is zero,
3945 *if it's not the last then OR in the variable */
3947 emitpcode(POC_IORFW, popGet(AOP(left),size));
3952 emitpLabel(lbl->key);
3953 //if(emitFinalCheck)
3954 genSkipc(&rFalseIfx);
3956 emitpLabel(truelbl->key);
3958 if(ifx) ifx->generated = 1;
3964 if(AOP_TYPE(left) == AOP_LIT) {
3965 //symbol *lbl = newiTempLabel(NULL);
3967 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3970 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3973 if((lit == 0) && (sign == 0)){
3976 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3978 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3980 //rFalseIfx.condition ^= 1;
3981 genSkipz2(&rFalseIfx);
3982 if(ifx) ifx->generated = 1;
3989 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3990 /* degenerate compare can never be true */
3991 if(rFalseIfx.condition == 0)
3992 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3994 if(ifx) ifx->generated = 1;
4000 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4001 emitpcode(POC_ADDLW, popGetLit(0x80));
4002 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4003 rFalseIfx.condition ^= 1;
4004 genSkipc(&rFalseIfx);
4006 rFalseIfx.condition ^= 1;
4007 genSkipCond(&rFalseIfx,right,0,7);
4012 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4013 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4015 rFalseIfx.condition ^= 1;
4016 genSkipc(&rFalseIfx);
4018 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4019 genSkipz2(&rFalseIfx);
4023 if(ifx) ifx->generated = 1;
4028 /* Size is greater than 1 */
4038 /* this means lit = 0xffffffff, or -1 */
4041 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4042 rFalseIfx.condition ^= 1;
4043 genSkipCond(&rFalseIfx,right,size,7);
4044 if(ifx) ifx->generated = 1;
4051 if(rFalseIfx.condition) {
4052 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4053 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4056 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4058 emitpcode(POC_IORFW, popGet(AOP(right),size));
4062 if(rFalseIfx.condition) {
4063 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4064 emitpLabel(truelbl->key);
4066 rFalseIfx.condition ^= 1;
4067 genSkipCond(&rFalseIfx,right,s,7);
4070 if(ifx) ifx->generated = 1;
4075 if(lit & (0x80 << (size*8))) {
4076 /* Lit is less than zero */
4077 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4078 //rFalseIfx.condition ^= 1;
4079 //genSkipCond(&rFalseIfx,left,size,7);
4080 //rFalseIfx.condition ^= 1;
4081 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4082 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4084 if(rFalseIfx.condition)
4085 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4087 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4091 /* Lit is greater than or equal to zero */
4092 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4093 //rFalseIfx.condition ^= 1;
4094 //genSkipCond(&rFalseIfx,right,size,7);
4095 //rFalseIfx.condition ^= 1;
4097 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4098 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4100 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4101 if(rFalseIfx.condition)
4102 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4104 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4107 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4108 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4112 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4114 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4116 rFalseIfx.condition ^= 1;
4117 //rFalseIfx.condition = 1;
4118 genSkipc(&rFalseIfx);
4120 emitpLabel(truelbl->key);
4122 if(ifx) ifx->generated = 1;
4126 /* Unsigned compare for sizes greater than 1 */
4129 i = (lit >> (size*8)) & 0xff;
4133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4134 emitpcode(POC_MOVLW, popGetLit(i&0xff));
4135 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4137 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4140 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
4141 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4146 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4148 emitpLabel(lbl->key);
4150 rFalseIfx.condition ^= 1;
4151 genSkipc(&rFalseIfx);
4155 emitpLabel(truelbl->key);
4156 if(ifx) ifx->generated = 1;
4160 /* Compare two variables */
4162 DEBUGpic14_emitcode(";sign","%d",sign);
4166 /* Sigh. thus sucks... */
4168 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4169 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4170 emitpcode(POC_MOVLW, popGetLit(0x80));
4171 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4172 emitpcode(POC_XORFW, popGet(AOP(right),size));
4173 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4175 /* Signed char comparison */
4176 /* Special thanks to Nikolai Golovchenko for this snippet */
4177 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4178 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4179 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4180 emitpcode(POC_XORFW, popGet(AOP(left),0));
4181 emitpcode(POC_XORFW, popGet(AOP(right),0));
4182 emitpcode(POC_ADDLW, popGetLit(0x80));
4184 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4185 genSkipc(&rFalseIfx);
4187 if(ifx) ifx->generated = 1;
4193 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4194 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4198 /* The rest of the bytes of a multi-byte compare */
4202 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4205 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4206 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4211 emitpLabel(lbl->key);
4213 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4214 genSkipc(&rFalseIfx);
4215 if(ifx) ifx->generated = 1;
4222 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4223 pic14_outBitC(result);
4225 /* if the result is used in the next
4226 ifx conditional branch then generate
4227 code a little differently */
4229 genIfxJump (ifx,"c");
4231 pic14_outBitC(result);
4232 /* leave the result in acc */
4237 /*-----------------------------------------------------------------*/
4238 /* genCmpGt :- greater than comparison */
4239 /*-----------------------------------------------------------------*/
4240 static void genCmpGt (iCode *ic, iCode *ifx)
4242 operand *left, *right, *result;
4243 sym_link *letype , *retype;
4246 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4248 right= IC_RIGHT(ic);
4249 result = IC_RESULT(ic);
4251 letype = getSpec(operandType(left));
4252 retype =getSpec(operandType(right));
4253 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4254 /* assign the amsops */
4255 aopOp (left,ic,FALSE);
4256 aopOp (right,ic,FALSE);
4257 aopOp (result,ic,TRUE);
4259 genCmp(right, left, result, ifx, sign);
4261 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4262 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4263 freeAsmop(result,NULL,ic,TRUE);
4266 /*-----------------------------------------------------------------*/
4267 /* genCmpLt - less than comparisons */
4268 /*-----------------------------------------------------------------*/
4269 static void genCmpLt (iCode *ic, iCode *ifx)
4271 operand *left, *right, *result;
4272 sym_link *letype , *retype;
4275 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4277 right= IC_RIGHT(ic);
4278 result = IC_RESULT(ic);
4280 letype = getSpec(operandType(left));
4281 retype =getSpec(operandType(right));
4282 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4284 /* assign the amsops */
4285 aopOp (left,ic,FALSE);
4286 aopOp (right,ic,FALSE);
4287 aopOp (result,ic,TRUE);
4289 genCmp(left, right, result, ifx, sign);
4291 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4292 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4293 freeAsmop(result,NULL,ic,TRUE);
4296 /*-----------------------------------------------------------------*/
4297 /* genc16bit2lit - compare a 16 bit value to a literal */
4298 /*-----------------------------------------------------------------*/
4299 static void genc16bit2lit(operand *op, int lit, int offset)
4303 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4304 if( (lit&0xff) == 0)
4309 switch( BYTEofLONG(lit,i)) {
4311 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4314 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4317 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4320 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4321 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4326 switch( BYTEofLONG(lit,i)) {
4328 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4332 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4336 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4339 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4341 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4347 /*-----------------------------------------------------------------*/
4348 /* gencjneshort - compare and jump if not equal */
4349 /*-----------------------------------------------------------------*/
4350 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4352 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4357 unsigned long lit = 0L;
4358 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4359 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4361 resolveIfx(&rIfx,ifx);
4362 lbl = newiTempLabel(NULL);
4365 /* if the left side is a literal or
4366 if the right is in a pointer register and left
4368 if ((AOP_TYPE(left) == AOP_LIT) ||
4369 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4374 if(AOP_TYPE(right) == AOP_LIT)
4375 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4377 /* if the right side is a literal then anything goes */
4378 if (AOP_TYPE(right) == AOP_LIT &&
4379 AOP_TYPE(left) != AOP_DIR ) {
4382 genc16bit2lit(left, lit, 0);
4384 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4389 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4390 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4392 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4396 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4404 /* if the right side is in a register or in direct space or
4405 if the left is a pointer register & right is not */
4406 else if (AOP_TYPE(right) == AOP_REG ||
4407 AOP_TYPE(right) == AOP_DIR ||
4408 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4409 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4412 genc16bit2lit(left, lit, 0);
4414 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4419 if((AOP_TYPE(left) == AOP_DIR) &&
4420 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4422 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4423 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4425 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4427 switch (lit & 0xff) {
4429 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4432 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4433 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4437 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4438 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4442 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4443 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4448 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4451 if(AOP_TYPE(result) == AOP_CRY) {
4452 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4457 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4459 /* fix me. probably need to check result size too */
4460 emitpcode(POC_CLRF,popGet(AOP(result),0));
4465 emitpcode(POC_INCF,popGet(AOP(result),0));
4475 } else if(AOP_TYPE(right) == AOP_REG &&
4476 AOP_TYPE(left) != AOP_DIR){
4479 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4480 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4481 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4486 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4491 /* right is a pointer reg need both a & b */
4493 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4495 pic14_emitcode("mov","b,%s",l);
4496 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4497 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4501 emitpLabel(lbl->key);
4508 /*-----------------------------------------------------------------*/
4509 /* gencjne - compare and jump if not equal */
4510 /*-----------------------------------------------------------------*/
4511 static void gencjne(operand *left, operand *right, iCode *ifx)
4513 symbol *tlbl = newiTempLabel(NULL);
4515 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4516 gencjneshort(left, right, lbl);
4518 pic14_emitcode("mov","a,%s",one);
4519 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4520 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4521 pic14_emitcode("clr","a");
4522 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4524 emitpLabel(lbl->key);
4525 emitpLabel(tlbl->key);
4530 /*-----------------------------------------------------------------*/
4531 /* genCmpEq - generates code for equal to */
4532 /*-----------------------------------------------------------------*/
4533 static void genCmpEq (iCode *ic, iCode *ifx)
4535 operand *left, *right, *result;
4536 unsigned long lit = 0L;
4539 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4542 DEBUGpic14_emitcode ("; ifx is non-null","");
4544 DEBUGpic14_emitcode ("; ifx is null","");
4546 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4547 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4548 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4550 size = max(AOP_SIZE(left),AOP_SIZE(right));
4552 DEBUGpic14_AopType(__LINE__,left,right,result);
4554 /* if literal, literal on the right or
4555 if the right is in a pointer register and left
4557 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4558 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4559 operand *tmp = right ;
4565 if(ifx && !AOP_SIZE(result)){
4567 /* if they are both bit variables */
4568 if (AOP_TYPE(left) == AOP_CRY &&
4569 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4570 if(AOP_TYPE(right) == AOP_LIT){
4571 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4573 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4574 pic14_emitcode("cpl","c");
4575 } else if(lit == 1L) {
4576 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4578 pic14_emitcode("clr","c");
4580 /* AOP_TYPE(right) == AOP_CRY */
4582 symbol *lbl = newiTempLabel(NULL);
4583 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4584 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4585 pic14_emitcode("cpl","c");
4586 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4588 /* if true label then we jump if condition
4590 tlbl = newiTempLabel(NULL);
4591 if ( IC_TRUE(ifx) ) {
4592 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4593 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4595 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4596 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4598 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4601 /* left and right are both bit variables, result is carry */
4604 resolveIfx(&rIfx,ifx);
4606 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4607 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4608 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4609 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4614 /* They're not both bit variables. Is the right a literal? */
4615 if(AOP_TYPE(right) == AOP_LIT) {
4616 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4621 switch(lit & 0xff) {
4623 if ( IC_TRUE(ifx) ) {
4624 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4626 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4628 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4629 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4633 if ( IC_TRUE(ifx) ) {
4634 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4636 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4638 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4639 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4643 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4645 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4650 /* end of size == 1 */
4654 genc16bit2lit(left,lit,offset);
4657 /* end of size == 2 */
4662 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4663 emitpcode(POC_IORFW,popGet(AOP(left),1));
4664 emitpcode(POC_IORFW,popGet(AOP(left),2));
4665 emitpcode(POC_IORFW,popGet(AOP(left),3));
4669 /* search for patterns that can be optimized */
4671 genc16bit2lit(left,lit,0);
4674 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4676 genc16bit2lit(left,lit,2);
4678 emitpcode(POC_IORFW,popGet(AOP(left),2));
4679 emitpcode(POC_IORFW,popGet(AOP(left),3));
4692 } else if(AOP_TYPE(right) == AOP_CRY ) {
4693 /* we know the left is not a bit, but that the right is */
4694 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4695 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4696 popGet(AOP(right),offset));
4697 emitpcode(POC_XORLW,popGetLit(1));
4699 /* if the two are equal, then W will be 0 and the Z bit is set
4700 * we could test Z now, or go ahead and check the high order bytes if
4701 * the variable we're comparing is larger than a byte. */
4704 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4706 if ( IC_TRUE(ifx) ) {
4708 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4709 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4712 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4713 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4717 /* They're both variables that are larger than bits */
4720 tlbl = newiTempLabel(NULL);
4723 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4724 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4726 if ( IC_TRUE(ifx) ) {
4729 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4730 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4733 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4734 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4738 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4739 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4743 if(s>1 && IC_TRUE(ifx)) {
4744 emitpLabel(tlbl->key);
4745 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4749 /* mark the icode as generated */
4754 /* if they are both bit variables */
4755 if (AOP_TYPE(left) == AOP_CRY &&
4756 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4757 if(AOP_TYPE(right) == AOP_LIT){
4758 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4760 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4761 pic14_emitcode("cpl","c");
4762 } else if(lit == 1L) {
4763 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4765 pic14_emitcode("clr","c");
4767 /* AOP_TYPE(right) == AOP_CRY */
4769 symbol *lbl = newiTempLabel(NULL);
4770 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4771 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4772 pic14_emitcode("cpl","c");
4773 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4776 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4777 pic14_outBitC(result);
4781 genIfxJump (ifx,"c");
4784 /* if the result is used in an arithmetic operation
4785 then put the result in place */
4786 pic14_outBitC(result);
4789 gencjne(left,right,result,ifx);
4792 gencjne(left,right,newiTempLabel(NULL));
4794 if(IC_TRUE(ifx)->key)
4795 gencjne(left,right,IC_TRUE(ifx)->key);
4797 gencjne(left,right,IC_FALSE(ifx)->key);
4801 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4802 aopPut(AOP(result),"a",0);
4807 genIfxJump (ifx,"a");
4811 /* if the result is used in an arithmetic operation
4812 then put the result in place */
4814 if (AOP_TYPE(result) != AOP_CRY)
4815 pic14_outAcc(result);
4817 /* leave the result in acc */
4821 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4822 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4823 freeAsmop(result,NULL,ic,TRUE);
4826 /*-----------------------------------------------------------------*/
4827 /* ifxForOp - returns the icode containing the ifx for operand */
4828 /*-----------------------------------------------------------------*/
4829 static iCode *ifxForOp ( operand *op, iCode *ic )
4831 /* if true symbol then needs to be assigned */
4832 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4833 if (IS_TRUE_SYMOP(op))
4836 /* if this has register type condition and
4837 the next instruction is ifx with the same operand
4838 and live to of the operand is upto the ifx only then */
4840 ic->next->op == IFX &&
4841 IC_COND(ic->next)->key == op->key &&
4842 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4846 ic->next->op == IFX &&
4847 IC_COND(ic->next)->key == op->key) {
4848 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4852 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4854 ic->next->op == IFX)
4855 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4858 ic->next->op == IFX &&
4859 IC_COND(ic->next)->key == op->key) {
4860 DEBUGpic14_emitcode ("; "," key is okay");
4861 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4862 OP_SYMBOL(op)->liveTo,
4869 /*-----------------------------------------------------------------*/
4870 /* genAndOp - for && operation */
4871 /*-----------------------------------------------------------------*/
4872 static void genAndOp (iCode *ic)
4874 operand *left,*right, *result;
4877 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4878 /* note here that && operations that are in an
4879 if statement are taken away by backPatchLabels
4880 only those used in arthmetic operations remain */
4881 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4882 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4883 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4885 /* if both are bit variables */
4886 if (AOP_TYPE(left) == AOP_CRY &&
4887 AOP_TYPE(right) == AOP_CRY ) {
4888 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4889 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4890 pic14_outBitC(result);
4892 tlbl = newiTempLabel(NULL);
4893 pic14_toBoolean(left);
4894 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4895 pic14_toBoolean(right);
4896 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4897 pic14_outBitAcc(result);
4900 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4901 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4902 freeAsmop(result,NULL,ic,TRUE);
4906 /*-----------------------------------------------------------------*/
4907 /* genOrOp - for || operation */
4908 /*-----------------------------------------------------------------*/
4911 modified this code, but it doesn't appear to ever get called
4914 static void genOrOp (iCode *ic)
4916 operand *left,*right, *result;
4919 /* note here that || operations that are in an
4920 if statement are taken away by backPatchLabels
4921 only those used in arthmetic operations remain */
4922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4923 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4924 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4925 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4927 DEBUGpic14_AopType(__LINE__,left,right,result);
4929 /* if both are bit variables */
4930 if (AOP_TYPE(left) == AOP_CRY &&
4931 AOP_TYPE(right) == AOP_CRY ) {
4932 pic14_emitcode("clrc","");
4933 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4934 AOP(left)->aopu.aop_dir,
4935 AOP(left)->aopu.aop_dir);
4936 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4937 AOP(right)->aopu.aop_dir,
4938 AOP(right)->aopu.aop_dir);
4939 pic14_emitcode("setc","");
4942 tlbl = newiTempLabel(NULL);
4943 pic14_toBoolean(left);
4945 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4946 pic14_toBoolean(right);
4947 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4949 pic14_outBitAcc(result);
4952 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4953 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4954 freeAsmop(result,NULL,ic,TRUE);
4957 /*-----------------------------------------------------------------*/
4958 /* isLiteralBit - test if lit == 2^n */
4959 /*-----------------------------------------------------------------*/
4960 static int isLiteralBit(unsigned long lit)
4962 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4963 0x100L,0x200L,0x400L,0x800L,
4964 0x1000L,0x2000L,0x4000L,0x8000L,
4965 0x10000L,0x20000L,0x40000L,0x80000L,
4966 0x100000L,0x200000L,0x400000L,0x800000L,
4967 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4968 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4971 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4972 for(idx = 0; idx < 32; idx++)
4978 /*-----------------------------------------------------------------*/
4979 /* continueIfTrue - */
4980 /*-----------------------------------------------------------------*/
4981 static void continueIfTrue (iCode *ic)
4983 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4985 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4989 /*-----------------------------------------------------------------*/
4991 /*-----------------------------------------------------------------*/
4992 static void jumpIfTrue (iCode *ic)
4994 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4996 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5000 /*-----------------------------------------------------------------*/
5001 /* jmpTrueOrFalse - */
5002 /*-----------------------------------------------------------------*/
5003 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5005 // ugly but optimized by peephole
5006 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5008 symbol *nlbl = newiTempLabel(NULL);
5009 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5010 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5011 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5012 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5015 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5016 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5021 /*-----------------------------------------------------------------*/
5022 /* genAnd - code for and */
5023 /*-----------------------------------------------------------------*/
5024 static void genAnd (iCode *ic, iCode *ifx)
5026 operand *left, *right, *result;
5028 unsigned long lit = 0L;
5033 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5034 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5035 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5036 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5038 resolveIfx(&rIfx,ifx);
5040 /* if left is a literal & right is not then exchange them */
5041 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5042 AOP_NEEDSACC(left)) {
5043 operand *tmp = right ;
5048 /* if result = right then exchange them */
5049 if(pic14_sameRegs(AOP(result),AOP(right))){
5050 operand *tmp = right ;
5055 /* if right is bit then exchange them */
5056 if (AOP_TYPE(right) == AOP_CRY &&
5057 AOP_TYPE(left) != AOP_CRY){
5058 operand *tmp = right ;
5062 if(AOP_TYPE(right) == AOP_LIT)
5063 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5065 size = AOP_SIZE(result);
5067 DEBUGpic14_AopType(__LINE__,left,right,result);
5070 // result = bit & yy;
5071 if (AOP_TYPE(left) == AOP_CRY){
5072 // c = bit & literal;
5073 if(AOP_TYPE(right) == AOP_LIT){
5075 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5078 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5081 if(size && (AOP_TYPE(result) == AOP_CRY)){
5082 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5085 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5089 pic14_emitcode("clr","c");
5092 if (AOP_TYPE(right) == AOP_CRY){
5094 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5095 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5098 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5100 pic14_emitcode("rrc","a");
5101 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5107 pic14_outBitC(result);
5109 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5110 genIfxJump(ifx, "c");
5114 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5115 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5116 if((AOP_TYPE(right) == AOP_LIT) &&
5117 (AOP_TYPE(result) == AOP_CRY) &&
5118 (AOP_TYPE(left) != AOP_CRY)){
5119 int posbit = isLiteralBit(lit);
5123 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5126 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5132 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5133 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5135 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5136 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5139 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5140 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5141 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5148 symbol *tlbl = newiTempLabel(NULL);
5149 int sizel = AOP_SIZE(left);
5151 pic14_emitcode("setb","c");
5153 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5154 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5156 if((posbit = isLiteralBit(bytelit)) != 0)
5157 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5159 if(bytelit != 0x0FFL)
5160 pic14_emitcode("anl","a,%s",
5161 aopGet(AOP(right),offset,FALSE,TRUE));
5162 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5167 // bit = left & literal
5169 pic14_emitcode("clr","c");
5170 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5172 // if(left & literal)
5175 jmpTrueOrFalse(ifx, tlbl);
5179 pic14_outBitC(result);
5183 /* if left is same as result */
5184 if(pic14_sameRegs(AOP(result),AOP(left))){
5186 for(;size--; offset++,lit>>=8) {
5187 if(AOP_TYPE(right) == AOP_LIT){
5188 switch(lit & 0xff) {
5190 /* and'ing with 0 has clears the result */
5191 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5192 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5195 /* and'ing with 0xff is a nop when the result and left are the same */
5200 int p = my_powof2( (~lit) & 0xff );
5202 /* only one bit is set in the literal, so use a bcf instruction */
5203 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5204 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5207 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5208 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5209 if(know_W != (lit&0xff))
5210 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5212 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5217 if (AOP_TYPE(left) == AOP_ACC) {
5218 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5220 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5221 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5228 // left & result in different registers
5229 if(AOP_TYPE(result) == AOP_CRY){
5231 // if(size), result in bit
5232 // if(!size && ifx), conditional oper: if(left & right)
5233 symbol *tlbl = newiTempLabel(NULL);
5234 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5236 pic14_emitcode("setb","c");
5238 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5239 pic14_emitcode("anl","a,%s",
5240 aopGet(AOP(left),offset,FALSE,FALSE));
5241 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5246 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5247 pic14_outBitC(result);
5249 jmpTrueOrFalse(ifx, tlbl);
5251 for(;(size--);offset++) {
5253 // result = left & right
5254 if(AOP_TYPE(right) == AOP_LIT){
5255 int t = (lit >> (offset*8)) & 0x0FFL;
5258 pic14_emitcode("clrf","%s",
5259 aopGet(AOP(result),offset,FALSE,FALSE));
5260 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5263 pic14_emitcode("movf","%s,w",
5264 aopGet(AOP(left),offset,FALSE,FALSE));
5265 pic14_emitcode("movwf","%s",
5266 aopGet(AOP(result),offset,FALSE,FALSE));
5267 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5268 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5271 pic14_emitcode("movlw","0x%x",t);
5272 pic14_emitcode("andwf","%s,w",
5273 aopGet(AOP(left),offset,FALSE,FALSE));
5274 pic14_emitcode("movwf","%s",
5275 aopGet(AOP(result),offset,FALSE,FALSE));
5277 emitpcode(POC_MOVLW, popGetLit(t));
5278 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5279 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5284 if (AOP_TYPE(left) == AOP_ACC) {
5285 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5286 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5288 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5289 pic14_emitcode("andwf","%s,w",
5290 aopGet(AOP(left),offset,FALSE,FALSE));
5291 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5292 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5294 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5295 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5301 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5302 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5303 freeAsmop(result,NULL,ic,TRUE);
5306 /*-----------------------------------------------------------------*/
5307 /* genOr - code for or */
5308 /*-----------------------------------------------------------------*/
5309 static void genOr (iCode *ic, iCode *ifx)
5311 operand *left, *right, *result;
5313 unsigned long lit = 0L;
5315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5317 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5318 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5319 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5321 DEBUGpic14_AopType(__LINE__,left,right,result);
5323 /* if left is a literal & right is not then exchange them */
5324 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5325 AOP_NEEDSACC(left)) {
5326 operand *tmp = right ;
5331 /* if result = right then exchange them */
5332 if(pic14_sameRegs(AOP(result),AOP(right))){
5333 operand *tmp = right ;
5338 /* if right is bit then exchange them */
5339 if (AOP_TYPE(right) == AOP_CRY &&
5340 AOP_TYPE(left) != AOP_CRY){
5341 operand *tmp = right ;
5346 DEBUGpic14_AopType(__LINE__,left,right,result);
5348 if(AOP_TYPE(right) == AOP_LIT)
5349 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5351 size = AOP_SIZE(result);
5355 if (AOP_TYPE(left) == AOP_CRY){
5356 if(AOP_TYPE(right) == AOP_LIT){
5357 // c = bit & literal;
5359 // lit != 0 => result = 1
5360 if(AOP_TYPE(result) == AOP_CRY){
5362 emitpcode(POC_BSF, popGet(AOP(result),0));
5363 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5364 // AOP(result)->aopu.aop_dir,
5365 // AOP(result)->aopu.aop_dir);
5367 continueIfTrue(ifx);
5371 // lit == 0 => result = left
5372 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5374 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5377 if (AOP_TYPE(right) == AOP_CRY){
5378 if(pic14_sameRegs(AOP(result),AOP(left))){
5380 emitpcode(POC_BCF, popGet(AOP(result),0));
5381 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5382 emitpcode(POC_BSF, popGet(AOP(result),0));
5384 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5385 AOP(result)->aopu.aop_dir,
5386 AOP(result)->aopu.aop_dir);
5387 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5388 AOP(right)->aopu.aop_dir,
5389 AOP(right)->aopu.aop_dir);
5390 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5391 AOP(result)->aopu.aop_dir,
5392 AOP(result)->aopu.aop_dir);
5394 if( AOP_TYPE(result) == AOP_ACC) {
5395 emitpcode(POC_MOVLW, popGetLit(0));
5396 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5397 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5398 emitpcode(POC_MOVLW, popGetLit(1));
5402 emitpcode(POC_BCF, popGet(AOP(result),0));
5403 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5404 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5405 emitpcode(POC_BSF, popGet(AOP(result),0));
5407 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5408 AOP(result)->aopu.aop_dir,
5409 AOP(result)->aopu.aop_dir);
5410 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5411 AOP(right)->aopu.aop_dir,
5412 AOP(right)->aopu.aop_dir);
5413 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5414 AOP(left)->aopu.aop_dir,
5415 AOP(left)->aopu.aop_dir);
5416 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5417 AOP(result)->aopu.aop_dir,
5418 AOP(result)->aopu.aop_dir);
5423 symbol *tlbl = newiTempLabel(NULL);
5424 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5427 emitpcode(POC_BCF, popGet(AOP(result),0));
5428 if( AOP_TYPE(right) == AOP_ACC) {
5429 emitpcode(POC_IORLW, popGetLit(0));
5431 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5432 emitpcode(POC_BSF, popGet(AOP(result),0));
5437 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5438 pic14_emitcode(";XXX setb","c");
5439 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5440 AOP(left)->aopu.aop_dir,tlbl->key+100);
5441 pic14_toBoolean(right);
5442 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5443 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5444 jmpTrueOrFalse(ifx, tlbl);
5448 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5455 pic14_outBitC(result);
5457 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5458 genIfxJump(ifx, "c");
5462 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5463 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5464 if((AOP_TYPE(right) == AOP_LIT) &&
5465 (AOP_TYPE(result) == AOP_CRY) &&
5466 (AOP_TYPE(left) != AOP_CRY)){
5468 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5471 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5473 continueIfTrue(ifx);
5476 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5477 // lit = 0, result = boolean(left)
5479 pic14_emitcode(";XXX setb","c");
5480 pic14_toBoolean(right);
5482 symbol *tlbl = newiTempLabel(NULL);
5483 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5485 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5487 genIfxJump (ifx,"a");
5491 pic14_outBitC(result);
5495 /* if left is same as result */
5496 if(pic14_sameRegs(AOP(result),AOP(left))){
5498 for(;size--; offset++,lit>>=8) {
5499 if(AOP_TYPE(right) == AOP_LIT){
5500 if((lit & 0xff) == 0)
5501 /* or'ing with 0 has no effect */
5504 int p = my_powof2(lit & 0xff);
5506 /* only one bit is set in the literal, so use a bsf instruction */
5508 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5510 if(know_W != (lit & 0xff))
5511 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5512 know_W = lit & 0xff;
5513 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5518 if (AOP_TYPE(left) == AOP_ACC) {
5519 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5520 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5522 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5523 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5525 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5526 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5532 // left & result in different registers
5533 if(AOP_TYPE(result) == AOP_CRY){
5535 // if(size), result in bit
5536 // if(!size && ifx), conditional oper: if(left | right)
5537 symbol *tlbl = newiTempLabel(NULL);
5538 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5539 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5543 pic14_emitcode(";XXX setb","c");
5545 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5546 pic14_emitcode(";XXX orl","a,%s",
5547 aopGet(AOP(left),offset,FALSE,FALSE));
5548 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5553 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5554 pic14_outBitC(result);
5556 jmpTrueOrFalse(ifx, tlbl);
5557 } else for(;(size--);offset++){
5559 // result = left & right
5560 if(AOP_TYPE(right) == AOP_LIT){
5561 int t = (lit >> (offset*8)) & 0x0FFL;
5564 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5565 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5567 pic14_emitcode("movf","%s,w",
5568 aopGet(AOP(left),offset,FALSE,FALSE));
5569 pic14_emitcode("movwf","%s",
5570 aopGet(AOP(result),offset,FALSE,FALSE));
5573 emitpcode(POC_MOVLW, popGetLit(t));
5574 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5575 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5577 pic14_emitcode("movlw","0x%x",t);
5578 pic14_emitcode("iorwf","%s,w",
5579 aopGet(AOP(left),offset,FALSE,FALSE));
5580 pic14_emitcode("movwf","%s",
5581 aopGet(AOP(result),offset,FALSE,FALSE));
5587 // faster than result <- left, anl result,right
5588 // and better if result is SFR
5589 if (AOP_TYPE(left) == AOP_ACC) {
5590 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5591 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5593 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5594 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5596 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5597 pic14_emitcode("iorwf","%s,w",
5598 aopGet(AOP(left),offset,FALSE,FALSE));
5600 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5601 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5606 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5607 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5608 freeAsmop(result,NULL,ic,TRUE);
5611 /*-----------------------------------------------------------------*/
5612 /* genXor - code for xclusive or */
5613 /*-----------------------------------------------------------------*/
5614 static void genXor (iCode *ic, iCode *ifx)
5616 operand *left, *right, *result;
5618 unsigned long lit = 0L;
5620 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5622 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5623 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5624 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5626 /* if left is a literal & right is not ||
5627 if left needs acc & right does not */
5628 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5629 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5630 operand *tmp = right ;
5635 /* if result = right then exchange them */
5636 if(pic14_sameRegs(AOP(result),AOP(right))){
5637 operand *tmp = right ;
5642 /* if right is bit then exchange them */
5643 if (AOP_TYPE(right) == AOP_CRY &&
5644 AOP_TYPE(left) != AOP_CRY){
5645 operand *tmp = right ;
5649 if(AOP_TYPE(right) == AOP_LIT)
5650 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5652 size = AOP_SIZE(result);
5656 if (AOP_TYPE(left) == AOP_CRY){
5657 if(AOP_TYPE(right) == AOP_LIT){
5658 // c = bit & literal;
5660 // lit>>1 != 0 => result = 1
5661 if(AOP_TYPE(result) == AOP_CRY){
5663 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5664 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5666 continueIfTrue(ifx);
5669 pic14_emitcode("setb","c");
5673 // lit == 0, result = left
5674 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5676 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5678 // lit == 1, result = not(left)
5679 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5680 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5681 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5682 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5685 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5686 pic14_emitcode("cpl","c");
5693 symbol *tlbl = newiTempLabel(NULL);
5694 if (AOP_TYPE(right) == AOP_CRY){
5696 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5699 int sizer = AOP_SIZE(right);
5701 // if val>>1 != 0, result = 1
5702 pic14_emitcode("setb","c");
5704 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5706 // test the msb of the lsb
5707 pic14_emitcode("anl","a,#0xfe");
5708 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5712 pic14_emitcode("rrc","a");
5714 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5715 pic14_emitcode("cpl","c");
5716 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5721 pic14_outBitC(result);
5723 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5724 genIfxJump(ifx, "c");
5728 if(pic14_sameRegs(AOP(result),AOP(left))){
5729 /* if left is same as result */
5730 for(;size--; offset++) {
5731 if(AOP_TYPE(right) == AOP_LIT){
5732 int t = (lit >> (offset*8)) & 0x0FFL;
5736 if (IS_AOP_PREG(left)) {
5737 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5738 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5739 aopPut(AOP(result),"a",offset);
5741 emitpcode(POC_MOVLW, popGetLit(t));
5742 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5743 pic14_emitcode("xrl","%s,%s",
5744 aopGet(AOP(left),offset,FALSE,TRUE),
5745 aopGet(AOP(right),offset,FALSE,FALSE));
5748 if (AOP_TYPE(left) == AOP_ACC)
5749 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5751 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5752 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5754 if (IS_AOP_PREG(left)) {
5755 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5756 aopPut(AOP(result),"a",offset);
5758 pic14_emitcode("xrl","%s,a",
5759 aopGet(AOP(left),offset,FALSE,TRUE));
5765 // left & result in different registers
5766 if(AOP_TYPE(result) == AOP_CRY){
5768 // if(size), result in bit
5769 // if(!size && ifx), conditional oper: if(left ^ right)
5770 symbol *tlbl = newiTempLabel(NULL);
5771 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5773 pic14_emitcode("setb","c");
5775 if((AOP_TYPE(right) == AOP_LIT) &&
5776 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5777 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5779 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5780 pic14_emitcode("xrl","a,%s",
5781 aopGet(AOP(left),offset,FALSE,FALSE));
5783 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5788 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5789 pic14_outBitC(result);
5791 jmpTrueOrFalse(ifx, tlbl);
5792 } else for(;(size--);offset++){
5794 // result = left & right
5795 if(AOP_TYPE(right) == AOP_LIT){
5796 int t = (lit >> (offset*8)) & 0x0FFL;
5799 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5800 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5801 pic14_emitcode("movf","%s,w",
5802 aopGet(AOP(left),offset,FALSE,FALSE));
5803 pic14_emitcode("movwf","%s",
5804 aopGet(AOP(result),offset,FALSE,FALSE));
5807 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5808 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5809 pic14_emitcode("comf","%s,w",
5810 aopGet(AOP(left),offset,FALSE,FALSE));
5811 pic14_emitcode("movwf","%s",
5812 aopGet(AOP(result),offset,FALSE,FALSE));
5815 emitpcode(POC_MOVLW, popGetLit(t));
5816 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5817 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5818 pic14_emitcode("movlw","0x%x",t);
5819 pic14_emitcode("xorwf","%s,w",
5820 aopGet(AOP(left),offset,FALSE,FALSE));
5821 pic14_emitcode("movwf","%s",
5822 aopGet(AOP(result),offset,FALSE,FALSE));
5828 // faster than result <- left, anl result,right
5829 // and better if result is SFR
5830 if (AOP_TYPE(left) == AOP_ACC) {
5831 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5832 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5834 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5835 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5836 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5837 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5839 if ( AOP_TYPE(result) != AOP_ACC){
5840 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5841 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5847 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5848 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5849 freeAsmop(result,NULL,ic,TRUE);
5852 /*-----------------------------------------------------------------*/
5853 /* genInline - write the inline code out */
5854 /*-----------------------------------------------------------------*/
5855 static void genInline (iCode *ic)
5857 char *buffer, *bp, *bp1;
5859 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5861 _G.inLine += (!options.asmpeep);
5863 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5864 strcpy(buffer,IC_INLINE(ic));
5866 /* emit each line as a code */
5870 pic14_emitcode(bp1,"");
5871 addpCode2pBlock(pb,newpCodeInlineP(bp1));
5878 pic14_emitcode(bp1,"");
5885 pic14_emitcode(bp1,"");
5886 addpCode2pBlock(pb,newpCodeInlineP(bp1));
5888 /* pic14_emitcode("",buffer); */
5889 _G.inLine -= (!options.asmpeep);
5892 /*-----------------------------------------------------------------*/
5893 /* genRRC - rotate right with carry */
5894 /*-----------------------------------------------------------------*/
5895 static void genRRC (iCode *ic)
5897 operand *left , *result ;
5898 int size, offset = 0, same;
5900 /* rotate right with carry */
5902 result=IC_RESULT(ic);
5903 aopOp (left,ic,FALSE);
5904 aopOp (result,ic,FALSE);
5906 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5908 same = pic14_sameRegs(AOP(result),AOP(left));
5910 size = AOP_SIZE(result);
5912 /* get the lsb and put it into the carry */
5913 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5920 emitpcode(POC_RRF, popGet(AOP(left),offset));
5922 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5923 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5929 freeAsmop(left,NULL,ic,TRUE);
5930 freeAsmop(result,NULL,ic,TRUE);
5933 /*-----------------------------------------------------------------*/
5934 /* genRLC - generate code for rotate left with carry */
5935 /*-----------------------------------------------------------------*/
5936 static void genRLC (iCode *ic)
5938 operand *left , *result ;
5939 int size, offset = 0;
5942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5943 /* rotate right with carry */
5945 result=IC_RESULT(ic);
5946 aopOp (left,ic,FALSE);
5947 aopOp (result,ic,FALSE);
5949 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5951 same = pic14_sameRegs(AOP(result),AOP(left));
5953 /* move it to the result */
5954 size = AOP_SIZE(result);
5956 /* get the msb and put it into the carry */
5957 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5964 emitpcode(POC_RLF, popGet(AOP(left),offset));
5966 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5967 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5974 freeAsmop(left,NULL,ic,TRUE);
5975 freeAsmop(result,NULL,ic,TRUE);
5978 /*-----------------------------------------------------------------*/
5979 /* genGetHbit - generates code get highest order bit */
5980 /*-----------------------------------------------------------------*/
5981 static void genGetHbit (iCode *ic)
5983 operand *left, *result;
5985 result=IC_RESULT(ic);
5986 aopOp (left,ic,FALSE);
5987 aopOp (result,ic,FALSE);
5989 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5990 /* get the highest order byte into a */
5991 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5992 if(AOP_TYPE(result) == AOP_CRY){
5993 pic14_emitcode("rlc","a");
5994 pic14_outBitC(result);
5997 pic14_emitcode("rl","a");
5998 pic14_emitcode("anl","a,#0x01");
5999 pic14_outAcc(result);
6003 freeAsmop(left,NULL,ic,TRUE);
6004 freeAsmop(result,NULL,ic,TRUE);
6007 /*-----------------------------------------------------------------*/
6008 /* AccRol - rotate left accumulator by known count */
6009 /*-----------------------------------------------------------------*/
6010 static void AccRol (int shCount)
6012 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6013 shCount &= 0x0007; // shCount : 0..7
6018 pic14_emitcode("rl","a");
6021 pic14_emitcode("rl","a");
6022 pic14_emitcode("rl","a");
6025 pic14_emitcode("swap","a");
6026 pic14_emitcode("rr","a");
6029 pic14_emitcode("swap","a");
6032 pic14_emitcode("swap","a");
6033 pic14_emitcode("rl","a");
6036 pic14_emitcode("rr","a");
6037 pic14_emitcode("rr","a");
6040 pic14_emitcode("rr","a");
6045 /*-----------------------------------------------------------------*/
6046 /* AccLsh - left shift accumulator by known count */
6047 /*-----------------------------------------------------------------*/
6048 static void AccLsh (int shCount)
6050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6053 pic14_emitcode("add","a,acc");
6056 pic14_emitcode("add","a,acc");
6057 pic14_emitcode("add","a,acc");
6059 /* rotate left accumulator */
6061 /* and kill the lower order bits */
6062 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6067 /*-----------------------------------------------------------------*/
6068 /* AccRsh - right shift accumulator by known count */
6069 /*-----------------------------------------------------------------*/
6070 static void AccRsh (int shCount)
6072 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6076 pic14_emitcode("rrc","a");
6078 /* rotate right accumulator */
6079 AccRol(8 - shCount);
6080 /* and kill the higher order bits */
6081 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6087 /*-----------------------------------------------------------------*/
6088 /* AccSRsh - signed right shift accumulator by known count */
6089 /*-----------------------------------------------------------------*/
6090 static void AccSRsh (int shCount)
6093 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6096 pic14_emitcode("mov","c,acc.7");
6097 pic14_emitcode("rrc","a");
6098 } else if(shCount == 2){
6099 pic14_emitcode("mov","c,acc.7");
6100 pic14_emitcode("rrc","a");
6101 pic14_emitcode("mov","c,acc.7");
6102 pic14_emitcode("rrc","a");
6104 tlbl = newiTempLabel(NULL);
6105 /* rotate right accumulator */
6106 AccRol(8 - shCount);
6107 /* and kill the higher order bits */
6108 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6109 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6110 pic14_emitcode("orl","a,#0x%02x",
6111 (unsigned char)~SRMask[shCount]);
6112 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6117 /*-----------------------------------------------------------------*/
6118 /* shiftR1Left2Result - shift right one byte from left to result */
6119 /*-----------------------------------------------------------------*/
6120 static void shiftR1Left2ResultSigned (operand *left, int offl,
6121 operand *result, int offr,
6126 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6128 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6132 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6134 emitpcode(POC_RRF, popGet(AOP(result),offr));
6136 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6137 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6143 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6145 emitpcode(POC_RRF, popGet(AOP(result),offr));
6147 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6148 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6150 emitpcode(POC_RLFW, popGet(AOP(result),offl));
6151 emitpcode(POC_RRF, popGet(AOP(result),offl));
6157 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6159 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6160 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6163 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6164 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6165 emitpcode(POC_ANDLW, popGetLit(0x1f));
6167 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6168 emitpcode(POC_IORLW, popGetLit(0xe0));
6170 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6174 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6175 emitpcode(POC_ANDLW, popGetLit(0x0f));
6176 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6177 emitpcode(POC_IORLW, popGetLit(0xf0));
6178 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6182 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6184 emitpcode(POC_SWAPFW, popGet(AOP(result),offr));
6185 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6187 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6188 emitpcode(POC_ANDLW, popGetLit(0x07));
6189 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6190 emitpcode(POC_IORLW, popGetLit(0xf8));
6191 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6199 emitpcode(POC_MOVLW, popGetLit(0x00));
6200 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6201 emitpcode(POC_MOVLW, popGetLit(0xfe));
6202 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),6,0));
6203 emitpcode(POC_IORLW, popGetLit(0x01));
6204 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6206 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6207 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6208 emitpcode(POC_DECF, popGet(AOP(result),offr));
6209 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6210 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6216 emitpcode(POC_MOVLW, popGetLit(0x00));
6217 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6218 emitpcode(POC_MOVLW, popGetLit(0xff));
6219 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6221 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6222 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6223 emitpcode(POC_DECF, popGet(AOP(result),offr));
6231 /*-----------------------------------------------------------------*/
6232 /* shiftR1Left2Result - shift right one byte from left to result */
6233 /*-----------------------------------------------------------------*/
6234 static void shiftR1Left2Result (operand *left, int offl,
6235 operand *result, int offr,
6236 int shCount, int sign)
6240 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6242 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6244 /* Copy the msb into the carry if signed. */
6246 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6256 emitpcode(POC_RRF, popGet(AOP(result),offr));
6258 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6259 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6265 emitpcode(POC_RRF, popGet(AOP(result),offr));
6267 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6268 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6271 emitpcode(POC_RRF, popGet(AOP(result),offr));
6276 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6278 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6279 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6282 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6283 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6284 emitpcode(POC_ANDLW, popGetLit(0x1f));
6285 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6289 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6290 emitpcode(POC_ANDLW, popGetLit(0x0f));
6291 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6295 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6296 emitpcode(POC_ANDLW, popGetLit(0x0f));
6297 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6299 emitpcode(POC_RRF, popGet(AOP(result),offr));
6304 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6305 emitpcode(POC_ANDLW, popGetLit(0x80));
6306 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6307 emitpcode(POC_RLF, popGet(AOP(result),offr));
6308 emitpcode(POC_RLF, popGet(AOP(result),offr));
6313 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6314 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6315 emitpcode(POC_RLF, popGet(AOP(result),offr));
6324 /*-----------------------------------------------------------------*/
6325 /* shiftL1Left2Result - shift left one byte from left to result */
6326 /*-----------------------------------------------------------------*/
6327 static void shiftL1Left2Result (operand *left, int offl,
6328 operand *result, int offr, int shCount)
6333 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6335 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6336 DEBUGpic14_emitcode ("; ***","same = %d",same);
6337 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6339 /* shift left accumulator */
6340 //AccLsh(shCount); // don't comment out just yet...
6341 // aopPut(AOP(result),"a",offr);
6345 /* Shift left 1 bit position */
6346 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6348 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6350 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6351 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6355 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6356 emitpcode(POC_ANDLW,popGetLit(0x7e));
6357 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6358 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6361 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6362 emitpcode(POC_ANDLW,popGetLit(0x3e));
6363 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6364 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6365 emitpcode(POC_RLF, popGet(AOP(result),offr));
6368 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6369 emitpcode(POC_ANDLW, popGetLit(0xf0));
6370 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6373 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6374 emitpcode(POC_ANDLW, popGetLit(0xf0));
6375 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6376 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6379 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6380 emitpcode(POC_ANDLW, popGetLit(0x30));
6381 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6382 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6383 emitpcode(POC_RLF, popGet(AOP(result),offr));
6386 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6387 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6388 emitpcode(POC_RRF, popGet(AOP(result),offr));
6392 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6397 /*-----------------------------------------------------------------*/
6398 /* movLeft2Result - move byte from left to result */
6399 /*-----------------------------------------------------------------*/
6400 static void movLeft2Result (operand *left, int offl,
6401 operand *result, int offr, int sign)
6404 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6405 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6406 l = aopGet(AOP(left),offl,FALSE,FALSE);
6408 if (*l == '@' && (IS_AOP_PREG(result))) {
6409 pic14_emitcode("mov","a,%s",l);
6410 aopPut(AOP(result),"a",offr);
6413 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6414 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6416 //aopPut(AOP(result),l,offr);
6418 /* MSB sign in acc.7 ! */
6419 //if(pic14_getDataSize(left) == offl+1){
6420 // pic14_emitcode("mov","a,%s",l);
6421 // aopPut(AOP(result),"a",offr);
6428 /*-----------------------------------------------------------------*/
6429 /* shiftL2Left2Result - shift left two bytes from left to result */
6430 /*-----------------------------------------------------------------*/
6431 static void shiftL2Left2Result (operand *left, int offl,
6432 operand *result, int offr, int shCount)
6436 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6438 if(pic14_sameRegs(AOP(result), AOP(left))) {
6446 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6447 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6448 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6452 emitpcode(POC_RLF, popGet(AOP(result),offr));
6453 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6459 emitpcode(POC_MOVLW, popGetLit(0x0f));
6460 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6461 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6462 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6463 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6464 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6465 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6467 emitpcode(POC_RLF, popGet(AOP(result),offr));
6468 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6472 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6473 emitpcode(POC_RRF, popGet(AOP(result),offr));
6474 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6475 emitpcode(POC_RRF, popGet(AOP(result),offr));
6476 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6477 emitpcode(POC_ANDLW,popGetLit(0xc0));
6478 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6479 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6480 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6481 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6484 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6485 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6486 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6487 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6488 emitpcode(POC_RRF, popGet(AOP(result),offr));
6498 /* note, use a mov/add for the shift since the mov has a
6499 chance of getting optimized out */
6500 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6501 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6502 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6503 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6504 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6508 emitpcode(POC_RLF, popGet(AOP(result),offr));
6509 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6515 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6516 emitpcode(POC_ANDLW, popGetLit(0xF0));
6517 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6518 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6519 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6520 emitpcode(POC_ANDLW, popGetLit(0xF0));
6521 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6522 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6526 emitpcode(POC_RLF, popGet(AOP(result),offr));
6527 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6531 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6532 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6533 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6534 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6536 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6537 emitpcode(POC_RRF, popGet(AOP(result),offr));
6538 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6539 emitpcode(POC_ANDLW,popGetLit(0xc0));
6540 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6541 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6542 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6543 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6546 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6547 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6548 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6549 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6550 emitpcode(POC_RRF, popGet(AOP(result),offr));
6555 /*-----------------------------------------------------------------*/
6556 /* shiftR2Left2Result - shift right two bytes from left to result */
6557 /*-----------------------------------------------------------------*/
6558 static void shiftR2Left2Result (operand *left, int offl,
6559 operand *result, int offr,
6560 int shCount, int sign)
6564 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6565 same = pic14_sameRegs(AOP(result), AOP(left));
6567 if(same && ((offl + MSB16) == offr)){
6569 /* don't crash result[offr] */
6570 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6571 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6573 movLeft2Result(left,offl, result, offr, 0);
6574 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6576 /* a:x >> shCount (x = lsb(result))*/
6579 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6581 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6591 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6592 emitpcode(POC_RRF,popGet(AOP(result),offr));
6595 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6596 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6597 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6598 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6603 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6604 emitpcode(POC_RRF,popGet(AOP(result),offr));
6611 emitpcode(POC_MOVLW, popGetLit(0xf0));
6612 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6613 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6615 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6616 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6617 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6618 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6620 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6621 emitpcode(POC_ANDLW, popGetLit(0x0f));
6622 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6624 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6625 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6626 emitpcode(POC_ANDLW, popGetLit(0xf0));
6627 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6628 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6632 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6633 emitpcode(POC_RRF, popGet(AOP(result),offr));
6641 emitpcode(POC_RLF, popGet(AOP(result),offr));
6642 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6644 emitpcode(POC_RLF, popGet(AOP(result),offr));
6645 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6646 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6647 emitpcode(POC_ANDLW,popGetLit(0x03));
6648 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6649 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6650 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6651 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6653 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6654 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6655 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6656 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6657 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_RLF, popGet(AOP(result),offr));
6659 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6660 emitpcode(POC_ANDLW,popGetLit(0x03));
6661 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6666 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6667 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6668 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6669 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6675 /*-----------------------------------------------------------------*/
6676 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6677 /*-----------------------------------------------------------------*/
6678 static void shiftLLeftOrResult (operand *left, int offl,
6679 operand *result, int offr, int shCount)
6681 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6682 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6683 /* shift left accumulator */
6685 /* or with result */
6686 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6687 /* back to result */
6688 aopPut(AOP(result),"a",offr);
6691 /*-----------------------------------------------------------------*/
6692 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6693 /*-----------------------------------------------------------------*/
6694 static void shiftRLeftOrResult (operand *left, int offl,
6695 operand *result, int offr, int shCount)
6697 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6698 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6699 /* shift right accumulator */
6701 /* or with result */
6702 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6703 /* back to result */
6704 aopPut(AOP(result),"a",offr);
6707 /*-----------------------------------------------------------------*/
6708 /* genlshOne - left shift a one byte quantity by known count */
6709 /*-----------------------------------------------------------------*/
6710 static void genlshOne (operand *result, operand *left, int shCount)
6712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6713 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6716 /*-----------------------------------------------------------------*/
6717 /* genlshTwo - left shift two bytes by known amount != 0 */
6718 /*-----------------------------------------------------------------*/
6719 static void genlshTwo (operand *result,operand *left, int shCount)
6723 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6724 size = pic14_getDataSize(result);
6726 /* if shCount >= 8 */
6732 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6734 movLeft2Result(left, LSB, result, MSB16, 0);
6736 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6739 /* 1 <= shCount <= 7 */
6742 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6744 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6748 /*-----------------------------------------------------------------*/
6749 /* shiftLLong - shift left one long from left to result */
6750 /* offl = LSB or MSB16 */
6751 /*-----------------------------------------------------------------*/
6752 static void shiftLLong (operand *left, operand *result, int offr )
6755 int size = AOP_SIZE(result);
6757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6758 if(size >= LSB+offr){
6759 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6761 pic14_emitcode("add","a,acc");
6762 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6763 size >= MSB16+offr && offr != LSB )
6764 pic14_emitcode("xch","a,%s",
6765 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6767 aopPut(AOP(result),"a",LSB+offr);
6770 if(size >= MSB16+offr){
6771 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6772 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6775 pic14_emitcode("rlc","a");
6776 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6777 size >= MSB24+offr && offr != LSB)
6778 pic14_emitcode("xch","a,%s",
6779 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6781 aopPut(AOP(result),"a",MSB16+offr);
6784 if(size >= MSB24+offr){
6785 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6786 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6789 pic14_emitcode("rlc","a");
6790 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6791 size >= MSB32+offr && offr != LSB )
6792 pic14_emitcode("xch","a,%s",
6793 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6795 aopPut(AOP(result),"a",MSB24+offr);
6798 if(size > MSB32+offr){
6799 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6800 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6803 pic14_emitcode("rlc","a");
6804 aopPut(AOP(result),"a",MSB32+offr);
6807 aopPut(AOP(result),zero,LSB);
6810 /*-----------------------------------------------------------------*/
6811 /* genlshFour - shift four byte by a known amount != 0 */
6812 /*-----------------------------------------------------------------*/
6813 static void genlshFour (operand *result, operand *left, int shCount)
6817 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6818 size = AOP_SIZE(result);
6820 /* if shifting more that 3 bytes */
6821 if (shCount >= 24 ) {
6824 /* lowest order of left goes to the highest
6825 order of the destination */
6826 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6828 movLeft2Result(left, LSB, result, MSB32, 0);
6829 aopPut(AOP(result),zero,LSB);
6830 aopPut(AOP(result),zero,MSB16);
6831 aopPut(AOP(result),zero,MSB32);
6835 /* more than two bytes */
6836 else if ( shCount >= 16 ) {
6837 /* lower order two bytes goes to higher order two bytes */
6839 /* if some more remaining */
6841 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6843 movLeft2Result(left, MSB16, result, MSB32, 0);
6844 movLeft2Result(left, LSB, result, MSB24, 0);
6846 aopPut(AOP(result),zero,MSB16);
6847 aopPut(AOP(result),zero,LSB);
6851 /* if more than 1 byte */
6852 else if ( shCount >= 8 ) {
6853 /* lower order three bytes goes to higher order three bytes */
6857 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6859 movLeft2Result(left, LSB, result, MSB16, 0);
6861 else{ /* size = 4 */
6863 movLeft2Result(left, MSB24, result, MSB32, 0);
6864 movLeft2Result(left, MSB16, result, MSB24, 0);
6865 movLeft2Result(left, LSB, result, MSB16, 0);
6866 aopPut(AOP(result),zero,LSB);
6868 else if(shCount == 1)
6869 shiftLLong(left, result, MSB16);
6871 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6872 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6873 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6874 aopPut(AOP(result),zero,LSB);
6879 /* 1 <= shCount <= 7 */
6880 else if(shCount <= 2){
6881 shiftLLong(left, result, LSB);
6883 shiftLLong(result, result, LSB);
6885 /* 3 <= shCount <= 7, optimize */
6887 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6888 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6889 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6893 /*-----------------------------------------------------------------*/
6894 /* genLeftShiftLiteral - left shifting by known count */
6895 /*-----------------------------------------------------------------*/
6896 static void genLeftShiftLiteral (operand *left,
6901 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6904 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6905 freeAsmop(right,NULL,ic,TRUE);
6907 aopOp(left,ic,FALSE);
6908 aopOp(result,ic,FALSE);
6910 size = getSize(operandType(result));
6913 pic14_emitcode("; shift left ","result %d, left %d",size,
6917 /* I suppose that the left size >= result size */
6920 movLeft2Result(left, size, result, size, 0);
6924 else if(shCount >= (size * 8))
6926 aopPut(AOP(result),zero,size);
6930 genlshOne (result,left,shCount);
6935 genlshTwo (result,left,shCount);
6939 genlshFour (result,left,shCount);
6943 freeAsmop(left,NULL,ic,TRUE);
6944 freeAsmop(result,NULL,ic,TRUE);
6947 /*-----------------------------------------------------------------*
6948 * genMultiAsm - repeat assembly instruction for size of register.
6949 * if endian == 1, then the high byte (i.e base address + size of
6950 * register) is used first else the low byte is used first;
6951 *-----------------------------------------------------------------*/
6952 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
6957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6970 emitpcode(poc, popGet(AOP(reg),offset));
6975 /*-----------------------------------------------------------------*/
6976 /* genLeftShift - generates code for left shifting */
6977 /*-----------------------------------------------------------------*/
6978 static void genLeftShift (iCode *ic)
6980 operand *left,*right, *result;
6983 symbol *tlbl , *tlbl1;
6985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6987 right = IC_RIGHT(ic);
6989 result = IC_RESULT(ic);
6991 aopOp(right,ic,FALSE);
6993 /* if the shift count is known then do it
6994 as efficiently as possible */
6995 if (AOP_TYPE(right) == AOP_LIT) {
6996 genLeftShiftLiteral (left,right,result,ic);
7000 /* shift count is unknown then we have to form
7001 a loop get the loop count in B : Note: we take
7002 only the lower order byte since shifting
7003 more that 32 bits make no sense anyway, ( the
7004 largest size of an object can be only 32 bits ) */
7007 aopOp(left,ic,FALSE);
7008 aopOp(result,ic,FALSE);
7010 /* now move the left to the result if they are not the
7012 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7013 AOP_SIZE(result) > 1) {
7015 size = AOP_SIZE(result);
7018 l = aopGet(AOP(left),offset,FALSE,TRUE);
7019 if (*l == '@' && (IS_AOP_PREG(result))) {
7021 pic14_emitcode("mov","a,%s",l);
7022 aopPut(AOP(result),"a",offset);
7024 aopPut(AOP(result),l,offset);
7029 size = AOP_SIZE(result);
7031 /* if it is only one byte then */
7033 if(optimized_for_speed) {
7034 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7035 emitpcode(POC_ANDLW, popGetLit(0xf0));
7036 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7037 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7038 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7039 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7040 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7041 emitpcode(POC_RLFW, popGet(AOP(result),0));
7042 emitpcode(POC_ANDLW, popGetLit(0xfe));
7043 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7044 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7045 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7048 tlbl = newiTempLabel(NULL);
7049 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7050 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7051 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7054 emitpcode(POC_COMFW, popGet(AOP(right),0));
7055 emitpcode(POC_RRF, popGet(AOP(result),0));
7056 emitpLabel(tlbl->key);
7057 emitpcode(POC_RLF, popGet(AOP(result),0));
7058 emitpcode(POC_ADDLW, popGetLit(1));
7060 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7065 if (pic14_sameRegs(AOP(left),AOP(result))) {
7067 tlbl = newiTempLabel(NULL);
7068 emitpcode(POC_COMFW, popGet(AOP(right),0));
7069 genMultiAsm(POC_RRF, result, size,1);
7070 emitpLabel(tlbl->key);
7071 genMultiAsm(POC_RLF, result, size,0);
7072 emitpcode(POC_ADDLW, popGetLit(1));
7074 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7078 tlbl = newiTempLabel(NULL);
7080 tlbl1 = newiTempLabel(NULL);
7082 reAdjustPreg(AOP(result));
7084 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7085 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7086 l = aopGet(AOP(result),offset,FALSE,FALSE);
7088 pic14_emitcode("add","a,acc");
7089 aopPut(AOP(result),"a",offset++);
7091 l = aopGet(AOP(result),offset,FALSE,FALSE);
7093 pic14_emitcode("rlc","a");
7094 aopPut(AOP(result),"a",offset++);
7096 reAdjustPreg(AOP(result));
7098 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7099 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7101 freeAsmop (right,NULL,ic,TRUE);
7102 freeAsmop(left,NULL,ic,TRUE);
7103 freeAsmop(result,NULL,ic,TRUE);
7106 /*-----------------------------------------------------------------*/
7107 /* genrshOne - right shift a one byte quantity by known count */
7108 /*-----------------------------------------------------------------*/
7109 static void genrshOne (operand *result, operand *left,
7110 int shCount, int sign)
7112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7113 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7116 /*-----------------------------------------------------------------*/
7117 /* genrshTwo - right shift two bytes by known amount != 0 */
7118 /*-----------------------------------------------------------------*/
7119 static void genrshTwo (operand *result,operand *left,
7120 int shCount, int sign)
7122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7123 /* if shCount >= 8 */
7127 shiftR1Left2Result(left, MSB16, result, LSB,
7130 movLeft2Result(left, MSB16, result, LSB, sign);
7132 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7135 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7136 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7140 /* 1 <= shCount <= 7 */
7142 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7145 /*-----------------------------------------------------------------*/
7146 /* shiftRLong - shift right one long from left to result */
7147 /* offl = LSB or MSB16 */
7148 /*-----------------------------------------------------------------*/
7149 static void shiftRLong (operand *left, int offl,
7150 operand *result, int sign)
7152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7154 pic14_emitcode("clr","c");
7155 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7157 pic14_emitcode("mov","c,acc.7");
7158 pic14_emitcode("rrc","a");
7159 aopPut(AOP(result),"a",MSB32-offl);
7161 /* add sign of "a" */
7162 addSign(result, MSB32, sign);
7164 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7165 pic14_emitcode("rrc","a");
7166 aopPut(AOP(result),"a",MSB24-offl);
7168 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7169 pic14_emitcode("rrc","a");
7170 aopPut(AOP(result),"a",MSB16-offl);
7173 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7174 pic14_emitcode("rrc","a");
7175 aopPut(AOP(result),"a",LSB);
7179 /*-----------------------------------------------------------------*/
7180 /* genrshFour - shift four byte by a known amount != 0 */
7181 /*-----------------------------------------------------------------*/
7182 static void genrshFour (operand *result, operand *left,
7183 int shCount, int sign)
7185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7186 /* if shifting more that 3 bytes */
7187 if(shCount >= 24 ) {
7190 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7192 movLeft2Result(left, MSB32, result, LSB, sign);
7193 addSign(result, MSB16, sign);
7195 else if(shCount >= 16){
7198 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7200 movLeft2Result(left, MSB24, result, LSB, 0);
7201 movLeft2Result(left, MSB32, result, MSB16, sign);
7203 addSign(result, MSB24, sign);
7205 else if(shCount >= 8){
7208 shiftRLong(left, MSB16, result, sign);
7209 else if(shCount == 0){
7210 movLeft2Result(left, MSB16, result, LSB, 0);
7211 movLeft2Result(left, MSB24, result, MSB16, 0);
7212 movLeft2Result(left, MSB32, result, MSB24, sign);
7213 addSign(result, MSB32, sign);
7216 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7217 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7218 /* the last shift is signed */
7219 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7220 addSign(result, MSB32, sign);
7223 else{ /* 1 <= shCount <= 7 */
7225 shiftRLong(left, LSB, result, sign);
7227 shiftRLong(result, LSB, result, sign);
7230 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7231 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7232 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7237 /*-----------------------------------------------------------------*/
7238 /* genRightShiftLiteral - right shifting by known count */
7239 /*-----------------------------------------------------------------*/
7240 static void genRightShiftLiteral (operand *left,
7246 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7249 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7250 freeAsmop(right,NULL,ic,TRUE);
7252 aopOp(left,ic,FALSE);
7253 aopOp(result,ic,FALSE);
7256 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7260 size = pic14_getDataSize(left);
7261 /* test the LEFT size !!! */
7263 /* I suppose that the left size >= result size */
7265 size = pic14_getDataSize(result);
7267 movLeft2Result(left, size, result, size, 0);
7270 else if(shCount >= (size * 8)){
7272 /* get sign in acc.7 */
7273 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
7274 addSign(result, LSB, sign);
7278 genrshOne (result,left,shCount,sign);
7282 genrshTwo (result,left,shCount,sign);
7286 genrshFour (result,left,shCount,sign);
7292 freeAsmop(left,NULL,ic,TRUE);
7293 freeAsmop(result,NULL,ic,TRUE);
7297 /*-----------------------------------------------------------------*/
7298 /* genSignedRightShift - right shift of signed number */
7299 /*-----------------------------------------------------------------*/
7300 static void genSignedRightShift (iCode *ic)
7302 operand *right, *left, *result;
7305 symbol *tlbl, *tlbl1 ;
7308 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7310 /* we do it the hard way put the shift count in b
7311 and loop thru preserving the sign */
7312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7314 right = IC_RIGHT(ic);
7316 result = IC_RESULT(ic);
7318 aopOp(right,ic,FALSE);
7319 aopOp(left,ic,FALSE);
7320 aopOp(result,ic,FALSE);
7323 if ( AOP_TYPE(right) == AOP_LIT) {
7324 genRightShiftLiteral (left,right,result,ic,1);
7327 /* shift count is unknown then we have to form
7328 a loop get the loop count in B : Note: we take
7329 only the lower order byte since shifting
7330 more that 32 bits make no sense anyway, ( the
7331 largest size of an object can be only 32 bits ) */
7333 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7334 //pic14_emitcode("inc","b");
7335 //freeAsmop (right,NULL,ic,TRUE);
7336 //aopOp(left,ic,FALSE);
7337 //aopOp(result,ic,FALSE);
7339 /* now move the left to the result if they are not the
7341 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7342 AOP_SIZE(result) > 1) {
7344 size = AOP_SIZE(result);
7348 l = aopGet(AOP(left),offset,FALSE,TRUE);
7349 if (*l == '@' && IS_AOP_PREG(result)) {
7351 pic14_emitcode("mov","a,%s",l);
7352 aopPut(AOP(result),"a",offset);
7354 aopPut(AOP(result),l,offset);
7356 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7357 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7363 /* mov the highest order bit to OVR */
7364 tlbl = newiTempLabel(NULL);
7365 tlbl1= newiTempLabel(NULL);
7367 size = AOP_SIZE(result);
7370 pctemp = popGetTempReg(); /* grab a temporary working register. */
7372 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7374 /* offset should be 0, 1 or 3 */
7375 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7377 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7379 emitpcode(POC_MOVWF, pctemp);
7382 emitpLabel(tlbl->key);
7384 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7385 emitpcode(POC_RRF, popGet(AOP(result),offset));
7388 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7391 emitpcode(POC_DECFSZ, pctemp);
7392 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7393 emitpLabel(tlbl1->key);
7395 popReleaseTempReg(pctemp);
7397 size = AOP_SIZE(result);
7399 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7400 pic14_emitcode("rlc","a");
7401 pic14_emitcode("mov","ov,c");
7402 /* if it is only one byte then */
7404 l = aopGet(AOP(left),0,FALSE,FALSE);
7406 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7407 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7408 pic14_emitcode("mov","c,ov");
7409 pic14_emitcode("rrc","a");
7410 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7411 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7412 aopPut(AOP(result),"a",0);
7416 reAdjustPreg(AOP(result));
7417 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7418 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7419 pic14_emitcode("mov","c,ov");
7421 l = aopGet(AOP(result),offset,FALSE,FALSE);
7423 pic14_emitcode("rrc","a");
7424 aopPut(AOP(result),"a",offset--);
7426 reAdjustPreg(AOP(result));
7427 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7428 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7433 freeAsmop(left,NULL,ic,TRUE);
7434 freeAsmop(result,NULL,ic,TRUE);
7435 freeAsmop(right,NULL,ic,TRUE);
7438 /*-----------------------------------------------------------------*/
7439 /* genRightShift - generate code for right shifting */
7440 /*-----------------------------------------------------------------*/
7441 static void genRightShift (iCode *ic)
7443 operand *right, *left, *result;
7447 symbol *tlbl, *tlbl1 ;
7449 /* if signed then we do it the hard way preserve the
7450 sign bit moving it inwards */
7451 retype = getSpec(operandType(IC_RESULT(ic)));
7452 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7454 if (!SPEC_USIGN(retype)) {
7455 genSignedRightShift (ic);
7459 /* signed & unsigned types are treated the same : i.e. the
7460 signed is NOT propagated inwards : quoting from the
7461 ANSI - standard : "for E1 >> E2, is equivalent to division
7462 by 2**E2 if unsigned or if it has a non-negative value,
7463 otherwise the result is implementation defined ", MY definition
7464 is that the sign does not get propagated */
7466 right = IC_RIGHT(ic);
7468 result = IC_RESULT(ic);
7470 aopOp(right,ic,FALSE);
7472 /* if the shift count is known then do it
7473 as efficiently as possible */
7474 if (AOP_TYPE(right) == AOP_LIT) {
7475 genRightShiftLiteral (left,right,result,ic, 0);
7479 /* shift count is unknown then we have to form
7480 a loop get the loop count in B : Note: we take
7481 only the lower order byte since shifting
7482 more that 32 bits make no sense anyway, ( the
7483 largest size of an object can be only 32 bits ) */
7485 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7486 pic14_emitcode("inc","b");
7487 aopOp(left,ic,FALSE);
7488 aopOp(result,ic,FALSE);
7490 /* now move the left to the result if they are not the
7492 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7493 AOP_SIZE(result) > 1) {
7495 size = AOP_SIZE(result);
7498 l = aopGet(AOP(left),offset,FALSE,TRUE);
7499 if (*l == '@' && IS_AOP_PREG(result)) {
7501 pic14_emitcode("mov","a,%s",l);
7502 aopPut(AOP(result),"a",offset);
7504 aopPut(AOP(result),l,offset);
7509 tlbl = newiTempLabel(NULL);
7510 tlbl1= newiTempLabel(NULL);
7511 size = AOP_SIZE(result);
7514 /* if it is only one byte then */
7517 tlbl = newiTempLabel(NULL);
7518 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7519 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7520 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7523 emitpcode(POC_COMFW, popGet(AOP(right),0));
7524 emitpcode(POC_RLF, popGet(AOP(result),0));
7525 emitpLabel(tlbl->key);
7526 emitpcode(POC_RRF, popGet(AOP(result),0));
7527 emitpcode(POC_ADDLW, popGetLit(1));
7529 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7534 reAdjustPreg(AOP(result));
7535 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7536 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7539 l = aopGet(AOP(result),offset,FALSE,FALSE);
7541 pic14_emitcode("rrc","a");
7542 aopPut(AOP(result),"a",offset--);
7544 reAdjustPreg(AOP(result));
7546 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7547 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7550 freeAsmop(left,NULL,ic,TRUE);
7551 freeAsmop (right,NULL,ic,TRUE);
7552 freeAsmop(result,NULL,ic,TRUE);
7555 /*-----------------------------------------------------------------*/
7556 /* genUnpackBits - generates code for unpacking bits */
7557 /*-----------------------------------------------------------------*/
7558 static void genUnpackBits (operand *result, char *rname, int ptype)
7565 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7566 etype = getSpec(operandType(result));
7568 /* read the first byte */
7573 pic14_emitcode("mov","a,@%s",rname);
7577 pic14_emitcode("movx","a,@%s",rname);
7581 pic14_emitcode("movx","a,@dptr");
7585 pic14_emitcode("clr","a");
7586 pic14_emitcode("movc","a","@a+dptr");
7590 pic14_emitcode("lcall","__gptrget");
7594 /* if we have bitdisplacement then it fits */
7595 /* into this byte completely or if length is */
7596 /* less than a byte */
7597 if ((shCnt = SPEC_BSTR(etype)) ||
7598 (SPEC_BLEN(etype) <= 8)) {
7600 /* shift right acc */
7603 pic14_emitcode("anl","a,#0x%02x",
7604 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7605 aopPut(AOP(result),"a",offset);
7609 /* bit field did not fit in a byte */
7610 rlen = SPEC_BLEN(etype) - 8;
7611 aopPut(AOP(result),"a",offset++);
7618 pic14_emitcode("inc","%s",rname);
7619 pic14_emitcode("mov","a,@%s",rname);
7623 pic14_emitcode("inc","%s",rname);
7624 pic14_emitcode("movx","a,@%s",rname);
7628 pic14_emitcode("inc","dptr");
7629 pic14_emitcode("movx","a,@dptr");
7633 pic14_emitcode("clr","a");
7634 pic14_emitcode("inc","dptr");
7635 pic14_emitcode("movc","a","@a+dptr");
7639 pic14_emitcode("inc","dptr");
7640 pic14_emitcode("lcall","__gptrget");
7645 /* if we are done */
7649 aopPut(AOP(result),"a",offset++);
7654 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7655 aopPut(AOP(result),"a",offset);
7662 /*-----------------------------------------------------------------*/
7663 /* genDataPointerGet - generates code when ptr offset is known */
7664 /*-----------------------------------------------------------------*/
7665 static void genDataPointerGet (operand *left,
7669 int size , offset = 0;
7672 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7675 /* optimization - most of the time, left and result are the same
7676 * address, but different types. for the pic code, we could omit
7680 aopOp(result,ic,TRUE);
7682 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7684 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7686 size = AOP_SIZE(result);
7689 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7693 freeAsmop(left,NULL,ic,TRUE);
7694 freeAsmop(result,NULL,ic,TRUE);
7697 /*-----------------------------------------------------------------*/
7698 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7699 /*-----------------------------------------------------------------*/
7700 static void genNearPointerGet (operand *left,
7707 sym_link *rtype, *retype;
7708 sym_link *ltype = operandType(left);
7711 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7713 rtype = operandType(result);
7714 retype= getSpec(rtype);
7716 aopOp(left,ic,FALSE);
7718 /* if left is rematerialisable and
7719 result is not bit variable type and
7720 the left is pointer to data space i.e
7721 lower 128 bytes of space */
7722 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7723 !IS_BITVAR(retype) &&
7724 DCL_TYPE(ltype) == POINTER) {
7725 //genDataPointerGet (left,result,ic);
7729 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7731 /* if the value is already in a pointer register
7732 then don't need anything more */
7733 if (!AOP_INPREG(AOP(left))) {
7734 /* otherwise get a free pointer register */
7735 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7737 preg = getFreePtr(ic,&aop,FALSE);
7738 pic14_emitcode("mov","%s,%s",
7740 aopGet(AOP(left),0,FALSE,TRUE));
7741 rname = preg->name ;
7743 rname = aopGet(AOP(left),0,FALSE,FALSE);
7745 freeAsmop(left,NULL,ic,TRUE);
7746 aopOp (result,ic,FALSE);
7748 /* if bitfield then unpack the bits */
7749 if (IS_BITVAR(retype))
7750 genUnpackBits (result,rname,POINTER);
7752 /* we have can just get the values */
7753 int size = AOP_SIZE(result);
7756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7758 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7760 pic14_emitcode("mov","a,@%s",rname);
7761 aopPut(AOP(result),"a",offset);
7763 sprintf(buffer,"@%s",rname);
7764 aopPut(AOP(result),buffer,offset);
7768 pic14_emitcode("inc","%s",rname);
7772 /* now some housekeeping stuff */
7774 /* we had to allocate for this iCode */
7775 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7776 freeAsmop(NULL,aop,ic,TRUE);
7778 /* we did not allocate which means left
7779 already in a pointer register, then
7780 if size > 0 && this could be used again
7781 we have to point it back to where it
7783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7784 if (AOP_SIZE(result) > 1 &&
7785 !OP_SYMBOL(left)->remat &&
7786 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7788 int size = AOP_SIZE(result) - 1;
7790 pic14_emitcode("dec","%s",rname);
7795 freeAsmop(result,NULL,ic,TRUE);
7799 /*-----------------------------------------------------------------*/
7800 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7801 /*-----------------------------------------------------------------*/
7802 static void genPagedPointerGet (operand *left,
7809 sym_link *rtype, *retype;
7811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7813 rtype = operandType(result);
7814 retype= getSpec(rtype);
7816 aopOp(left,ic,FALSE);
7818 /* if the value is already in a pointer register
7819 then don't need anything more */
7820 if (!AOP_INPREG(AOP(left))) {
7821 /* otherwise get a free pointer register */
7823 preg = getFreePtr(ic,&aop,FALSE);
7824 pic14_emitcode("mov","%s,%s",
7826 aopGet(AOP(left),0,FALSE,TRUE));
7827 rname = preg->name ;
7829 rname = aopGet(AOP(left),0,FALSE,FALSE);
7831 freeAsmop(left,NULL,ic,TRUE);
7832 aopOp (result,ic,FALSE);
7834 /* if bitfield then unpack the bits */
7835 if (IS_BITVAR(retype))
7836 genUnpackBits (result,rname,PPOINTER);
7838 /* we have can just get the values */
7839 int size = AOP_SIZE(result);
7844 pic14_emitcode("movx","a,@%s",rname);
7845 aopPut(AOP(result),"a",offset);
7850 pic14_emitcode("inc","%s",rname);
7854 /* now some housekeeping stuff */
7856 /* we had to allocate for this iCode */
7857 freeAsmop(NULL,aop,ic,TRUE);
7859 /* we did not allocate which means left
7860 already in a pointer register, then
7861 if size > 0 && this could be used again
7862 we have to point it back to where it
7864 if (AOP_SIZE(result) > 1 &&
7865 !OP_SYMBOL(left)->remat &&
7866 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7868 int size = AOP_SIZE(result) - 1;
7870 pic14_emitcode("dec","%s",rname);
7875 freeAsmop(result,NULL,ic,TRUE);
7880 /*-----------------------------------------------------------------*/
7881 /* genFarPointerGet - gget value from far space */
7882 /*-----------------------------------------------------------------*/
7883 static void genFarPointerGet (operand *left,
7884 operand *result, iCode *ic)
7887 sym_link *retype = getSpec(operandType(result));
7889 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7891 aopOp(left,ic,FALSE);
7893 /* if the operand is already in dptr
7894 then we do nothing else we move the value to dptr */
7895 if (AOP_TYPE(left) != AOP_STR) {
7896 /* if this is remateriazable */
7897 if (AOP_TYPE(left) == AOP_IMMD)
7898 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7899 else { /* we need to get it byte by byte */
7900 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7901 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7902 if (options.model == MODEL_FLAT24)
7904 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7908 /* so dptr know contains the address */
7909 freeAsmop(left,NULL,ic,TRUE);
7910 aopOp(result,ic,FALSE);
7912 /* if bit then unpack */
7913 if (IS_BITVAR(retype))
7914 genUnpackBits(result,"dptr",FPOINTER);
7916 size = AOP_SIZE(result);
7920 pic14_emitcode("movx","a,@dptr");
7921 aopPut(AOP(result),"a",offset++);
7923 pic14_emitcode("inc","dptr");
7927 freeAsmop(result,NULL,ic,TRUE);
7930 /*-----------------------------------------------------------------*/
7931 /* genCodePointerGet - get value from code space */
7932 /*-----------------------------------------------------------------*/
7933 static void genCodePointerGet (operand *left,
7934 operand *result, iCode *ic)
7937 sym_link *retype = getSpec(operandType(result));
7939 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7941 aopOp(left,ic,FALSE);
7943 /* if the operand is already in dptr
7944 then we do nothing else we move the value to dptr */
7945 if (AOP_TYPE(left) != AOP_STR) {
7946 /* if this is remateriazable */
7947 if (AOP_TYPE(left) == AOP_IMMD)
7948 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7949 else { /* we need to get it byte by byte */
7950 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7951 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7952 if (options.model == MODEL_FLAT24)
7954 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7958 /* so dptr know contains the address */
7959 freeAsmop(left,NULL,ic,TRUE);
7960 aopOp(result,ic,FALSE);
7962 /* if bit then unpack */
7963 if (IS_BITVAR(retype))
7964 genUnpackBits(result,"dptr",CPOINTER);
7966 size = AOP_SIZE(result);
7970 pic14_emitcode("clr","a");
7971 pic14_emitcode("movc","a,@a+dptr");
7972 aopPut(AOP(result),"a",offset++);
7974 pic14_emitcode("inc","dptr");
7978 freeAsmop(result,NULL,ic,TRUE);
7981 /*-----------------------------------------------------------------*/
7982 /* genGenPointerGet - gget value from generic pointer space */
7983 /*-----------------------------------------------------------------*/
7984 static void genGenPointerGet (operand *left,
7985 operand *result, iCode *ic)
7988 sym_link *retype = getSpec(operandType(result));
7990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7991 aopOp(left,ic,FALSE);
7992 aopOp(result,ic,FALSE);
7995 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7997 /* if the operand is already in dptr
7998 then we do nothing else we move the value to dptr */
7999 // if (AOP_TYPE(left) != AOP_STR) {
8000 /* if this is remateriazable */
8001 if (AOP_TYPE(left) == AOP_IMMD) {
8002 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8003 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8005 else { /* we need to get it byte by byte */
8007 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8008 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8010 size = AOP_SIZE(result);
8014 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8015 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8017 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8022 /* so dptr know contains the address */
8024 /* if bit then unpack */
8025 //if (IS_BITVAR(retype))
8026 // genUnpackBits(result,"dptr",GPOINTER);
8029 freeAsmop(left,NULL,ic,TRUE);
8030 freeAsmop(result,NULL,ic,TRUE);
8034 /*-----------------------------------------------------------------*/
8035 /* genConstPointerGet - get value from const generic pointer space */
8036 /*-----------------------------------------------------------------*/
8037 static void genConstPointerGet (operand *left,
8038 operand *result, iCode *ic)
8040 //sym_link *retype = getSpec(operandType(result));
8041 symbol *albl = newiTempLabel(NULL);
8042 symbol *blbl = newiTempLabel(NULL);
8045 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8046 aopOp(left,ic,FALSE);
8047 aopOp(result,ic,FALSE);
8050 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8052 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8054 emitpcode(POC_CALL,popGetLabel(albl->key));
8055 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8056 emitpLabel(albl->key);
8058 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8060 emitpcode(poc,popGet(AOP(left),1));
8061 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8062 emitpcode(poc,popGet(AOP(left),0));
8063 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8065 emitpLabel(blbl->key);
8067 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8070 freeAsmop(left,NULL,ic,TRUE);
8071 freeAsmop(result,NULL,ic,TRUE);
8074 /*-----------------------------------------------------------------*/
8075 /* genPointerGet - generate code for pointer get */
8076 /*-----------------------------------------------------------------*/
8077 static void genPointerGet (iCode *ic)
8079 operand *left, *result ;
8080 sym_link *type, *etype;
8083 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8086 result = IC_RESULT(ic) ;
8088 /* depending on the type of pointer we need to
8089 move it to the correct pointer register */
8090 type = operandType(left);
8091 etype = getSpec(type);
8093 if (IS_PTR_CONST(type))
8094 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8096 /* if left is of type of pointer then it is simple */
8097 if (IS_PTR(type) && !IS_FUNC(type->next))
8098 p_type = DCL_TYPE(type);
8100 /* we have to go by the storage class */
8101 p_type = PTR_TYPE(SPEC_OCLS(etype));
8103 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8105 if (SPEC_OCLS(etype)->codesp ) {
8106 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8107 //p_type = CPOINTER ;
8110 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8111 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8112 /*p_type = FPOINTER ;*/
8114 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8115 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8116 /* p_type = PPOINTER; */
8118 if (SPEC_OCLS(etype) == idata )
8119 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8120 /* p_type = IPOINTER; */
8122 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8123 /* p_type = POINTER ; */
8126 /* now that we have the pointer type we assign
8127 the pointer values */
8132 genNearPointerGet (left,result,ic);
8136 genPagedPointerGet(left,result,ic);
8140 genFarPointerGet (left,result,ic);
8144 genConstPointerGet (left,result,ic);
8145 //pic14_emitcodePointerGet (left,result,ic);
8149 if (IS_PTR_CONST(type))
8150 genConstPointerGet (left,result,ic);
8152 genGenPointerGet (left,result,ic);
8158 /*-----------------------------------------------------------------*/
8159 /* genPackBits - generates code for packed bit storage */
8160 /*-----------------------------------------------------------------*/
8161 static void genPackBits (sym_link *etype ,
8163 char *rname, int p_type)
8171 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8172 blen = SPEC_BLEN(etype);
8173 bstr = SPEC_BSTR(etype);
8175 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8178 /* if the bit lenth is less than or */
8179 /* it exactly fits a byte then */
8180 if (SPEC_BLEN(etype) <= 8 ) {
8181 shCount = SPEC_BSTR(etype) ;
8183 /* shift left acc */
8186 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8191 pic14_emitcode ("mov","b,a");
8192 pic14_emitcode("mov","a,@%s",rname);
8196 pic14_emitcode ("mov","b,a");
8197 pic14_emitcode("movx","a,@dptr");
8201 pic14_emitcode ("push","b");
8202 pic14_emitcode ("push","acc");
8203 pic14_emitcode ("lcall","__gptrget");
8204 pic14_emitcode ("pop","b");
8208 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8209 ((unsigned char)(0xFF << (blen+bstr)) |
8210 (unsigned char)(0xFF >> (8-bstr)) ) );
8211 pic14_emitcode ("orl","a,b");
8212 if (p_type == GPOINTER)
8213 pic14_emitcode("pop","b");
8219 pic14_emitcode("mov","@%s,a",rname);
8223 pic14_emitcode("movx","@dptr,a");
8227 DEBUGpic14_emitcode(";lcall","__gptrput");
8232 if ( SPEC_BLEN(etype) <= 8 )
8235 pic14_emitcode("inc","%s",rname);
8236 rLen = SPEC_BLEN(etype) ;
8238 /* now generate for lengths greater than one byte */
8241 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8251 pic14_emitcode("mov","@%s,a",rname);
8253 pic14_emitcode("mov","@%s,%s",rname,l);
8258 pic14_emitcode("movx","@dptr,a");
8263 DEBUGpic14_emitcode(";lcall","__gptrput");
8266 pic14_emitcode ("inc","%s",rname);
8271 /* last last was not complete */
8273 /* save the byte & read byte */
8276 pic14_emitcode ("mov","b,a");
8277 pic14_emitcode("mov","a,@%s",rname);
8281 pic14_emitcode ("mov","b,a");
8282 pic14_emitcode("movx","a,@dptr");
8286 pic14_emitcode ("push","b");
8287 pic14_emitcode ("push","acc");
8288 pic14_emitcode ("lcall","__gptrget");
8289 pic14_emitcode ("pop","b");
8293 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8294 pic14_emitcode ("orl","a,b");
8297 if (p_type == GPOINTER)
8298 pic14_emitcode("pop","b");
8303 pic14_emitcode("mov","@%s,a",rname);
8307 pic14_emitcode("movx","@dptr,a");
8311 DEBUGpic14_emitcode(";lcall","__gptrput");
8315 /*-----------------------------------------------------------------*/
8316 /* genDataPointerSet - remat pointer to data space */
8317 /*-----------------------------------------------------------------*/
8318 static void genDataPointerSet(operand *right,
8322 int size, offset = 0 ;
8323 char *l, buffer[256];
8325 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8326 aopOp(right,ic,FALSE);
8328 l = aopGet(AOP(result),0,FALSE,TRUE);
8329 size = AOP_SIZE(right);
8331 if ( AOP_TYPE(result) == AOP_PCODE) {
8332 fprintf(stderr,"genDataPointerSet %s, %d\n",
8333 AOP(result)->aopu.pcop->name,
8334 PCOI(AOP(result)->aopu.pcop)->offset);
8338 // tsd, was l+1 - the underline `_' prefix was being stripped
8341 sprintf(buffer,"(%s + %d)",l,offset);
8342 fprintf(stderr,"oops %s\n",buffer);
8344 sprintf(buffer,"%s",l);
8346 if (AOP_TYPE(right) == AOP_LIT) {
8347 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8348 lit = lit >> (8*offset);
8350 pic14_emitcode("movlw","%d",lit);
8351 pic14_emitcode("movwf","%s",buffer);
8353 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8354 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8355 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8358 pic14_emitcode("clrf","%s",buffer);
8359 //emitpcode(POC_CLRF, popRegFromString(buffer));
8360 emitpcode(POC_CLRF, popGet(AOP(result),0));
8363 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8364 pic14_emitcode("movwf","%s",buffer);
8366 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8367 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8368 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8375 freeAsmop(right,NULL,ic,TRUE);
8376 freeAsmop(result,NULL,ic,TRUE);
8379 /*-----------------------------------------------------------------*/
8380 /* genNearPointerSet - pic14_emitcode for near pointer put */
8381 /*-----------------------------------------------------------------*/
8382 static void genNearPointerSet (operand *right,
8389 sym_link *ptype = operandType(result);
8392 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8393 retype= getSpec(operandType(right));
8395 aopOp(result,ic,FALSE);
8397 /* if the result is rematerializable &
8398 in data space & not a bit variable */
8399 //if (AOP_TYPE(result) == AOP_IMMD &&
8400 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8401 DCL_TYPE(ptype) == POINTER &&
8402 !IS_BITVAR(retype)) {
8403 genDataPointerSet (right,result,ic);
8407 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8409 /* if the value is already in a pointer register
8410 then don't need anything more */
8411 if (!AOP_INPREG(AOP(result))) {
8412 /* otherwise get a free pointer register */
8413 //aop = newAsmop(0);
8414 //preg = getFreePtr(ic,&aop,FALSE);
8415 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8416 //pic14_emitcode("mov","%s,%s",
8418 // aopGet(AOP(result),0,FALSE,TRUE));
8419 //rname = preg->name ;
8420 pic14_emitcode("movwf","fsr");
8422 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8424 freeAsmop(result,NULL,ic,TRUE);
8425 aopOp (right,ic,FALSE);
8426 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8428 /* if bitfield then unpack the bits */
8429 if (IS_BITVAR(retype)) {
8430 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8431 "The programmer is obviously confused");
8432 //genPackBits (retype,right,rname,POINTER);
8436 /* we have can just get the values */
8437 int size = AOP_SIZE(right);
8440 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8442 l = aopGet(AOP(right),offset,FALSE,TRUE);
8445 //pic14_emitcode("mov","@%s,a",rname);
8446 pic14_emitcode("movf","indf,w ;1");
8449 if (AOP_TYPE(right) == AOP_LIT) {
8450 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8452 pic14_emitcode("movlw","%s",l);
8453 pic14_emitcode("movwf","indf ;2");
8455 pic14_emitcode("clrf","indf");
8457 pic14_emitcode("movf","%s,w",l);
8458 pic14_emitcode("movwf","indf ;2");
8460 //pic14_emitcode("mov","@%s,%s",rname,l);
8463 pic14_emitcode("incf","fsr,f ;3");
8464 //pic14_emitcode("inc","%s",rname);
8469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8470 /* now some housekeeping stuff */
8472 /* we had to allocate for this iCode */
8473 freeAsmop(NULL,aop,ic,TRUE);
8475 /* we did not allocate which means left
8476 already in a pointer register, then
8477 if size > 0 && this could be used again
8478 we have to point it back to where it
8480 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8481 if (AOP_SIZE(right) > 1 &&
8482 !OP_SYMBOL(result)->remat &&
8483 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8485 int size = AOP_SIZE(right) - 1;
8487 pic14_emitcode("decf","fsr,f");
8488 //pic14_emitcode("dec","%s",rname);
8492 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8494 freeAsmop(right,NULL,ic,TRUE);
8499 /*-----------------------------------------------------------------*/
8500 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8501 /*-----------------------------------------------------------------*/
8502 static void genPagedPointerSet (operand *right,
8511 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8513 retype= getSpec(operandType(right));
8515 aopOp(result,ic,FALSE);
8517 /* if the value is already in a pointer register
8518 then don't need anything more */
8519 if (!AOP_INPREG(AOP(result))) {
8520 /* otherwise get a free pointer register */
8522 preg = getFreePtr(ic,&aop,FALSE);
8523 pic14_emitcode("mov","%s,%s",
8525 aopGet(AOP(result),0,FALSE,TRUE));
8526 rname = preg->name ;
8528 rname = aopGet(AOP(result),0,FALSE,FALSE);
8530 freeAsmop(result,NULL,ic,TRUE);
8531 aopOp (right,ic,FALSE);
8533 /* if bitfield then unpack the bits */
8534 if (IS_BITVAR(retype))
8535 genPackBits (retype,right,rname,PPOINTER);
8537 /* we have can just get the values */
8538 int size = AOP_SIZE(right);
8542 l = aopGet(AOP(right),offset,FALSE,TRUE);
8545 pic14_emitcode("movx","@%s,a",rname);
8548 pic14_emitcode("inc","%s",rname);
8554 /* now some housekeeping stuff */
8556 /* we had to allocate for this iCode */
8557 freeAsmop(NULL,aop,ic,TRUE);
8559 /* we did not allocate which means left
8560 already in a pointer register, then
8561 if size > 0 && this could be used again
8562 we have to point it back to where it
8564 if (AOP_SIZE(right) > 1 &&
8565 !OP_SYMBOL(result)->remat &&
8566 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8568 int size = AOP_SIZE(right) - 1;
8570 pic14_emitcode("dec","%s",rname);
8575 freeAsmop(right,NULL,ic,TRUE);
8580 /*-----------------------------------------------------------------*/
8581 /* genFarPointerSet - set value from far space */
8582 /*-----------------------------------------------------------------*/
8583 static void genFarPointerSet (operand *right,
8584 operand *result, iCode *ic)
8587 sym_link *retype = getSpec(operandType(right));
8589 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8590 aopOp(result,ic,FALSE);
8592 /* if the operand is already in dptr
8593 then we do nothing else we move the value to dptr */
8594 if (AOP_TYPE(result) != AOP_STR) {
8595 /* if this is remateriazable */
8596 if (AOP_TYPE(result) == AOP_IMMD)
8597 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8598 else { /* we need to get it byte by byte */
8599 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8600 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8601 if (options.model == MODEL_FLAT24)
8603 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8607 /* so dptr know contains the address */
8608 freeAsmop(result,NULL,ic,TRUE);
8609 aopOp(right,ic,FALSE);
8611 /* if bit then unpack */
8612 if (IS_BITVAR(retype))
8613 genPackBits(retype,right,"dptr",FPOINTER);
8615 size = AOP_SIZE(right);
8619 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8621 pic14_emitcode("movx","@dptr,a");
8623 pic14_emitcode("inc","dptr");
8627 freeAsmop(right,NULL,ic,TRUE);
8630 /*-----------------------------------------------------------------*/
8631 /* genGenPointerSet - set value from generic pointer space */
8632 /*-----------------------------------------------------------------*/
8633 static void genGenPointerSet (operand *right,
8634 operand *result, iCode *ic)
8637 sym_link *retype = getSpec(operandType(right));
8639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8641 aopOp(result,ic,FALSE);
8642 aopOp(right,ic,FALSE);
8643 size = AOP_SIZE(right);
8645 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8647 /* if the operand is already in dptr
8648 then we do nothing else we move the value to dptr */
8649 if (AOP_TYPE(result) != AOP_STR) {
8650 /* if this is remateriazable */
8651 if (AOP_TYPE(result) == AOP_IMMD) {
8652 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8653 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8655 else { /* we need to get it byte by byte */
8656 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8657 size = AOP_SIZE(right);
8660 /* hack hack! see if this the FSR. If so don't load W */
8661 if(AOP_TYPE(right) != AOP_ACC) {
8663 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8664 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8667 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8669 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8670 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8674 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8675 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8678 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8685 if(aopIdx(AOP(result),0) != 4) {
8687 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8691 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8696 /* so dptr know contains the address */
8699 /* if bit then unpack */
8700 if (IS_BITVAR(retype))
8701 genPackBits(retype,right,"dptr",GPOINTER);
8703 size = AOP_SIZE(right);
8707 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8709 pic14_emitcode("incf","fsr,f");
8710 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8711 pic14_emitcode("movwf","indf");
8713 //DEBUGpic14_emitcode(";lcall","__gptrput");
8715 // pic14_emitcode("inc","dptr");
8720 freeAsmop(right,NULL,ic,TRUE);
8721 freeAsmop(result,NULL,ic,TRUE);
8724 /*-----------------------------------------------------------------*/
8725 /* genPointerSet - stores the value into a pointer location */
8726 /*-----------------------------------------------------------------*/
8727 static void genPointerSet (iCode *ic)
8729 operand *right, *result ;
8730 sym_link *type, *etype;
8733 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8735 right = IC_RIGHT(ic);
8736 result = IC_RESULT(ic) ;
8738 /* depending on the type of pointer we need to
8739 move it to the correct pointer register */
8740 type = operandType(result);
8741 etype = getSpec(type);
8742 /* if left is of type of pointer then it is simple */
8743 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8744 p_type = DCL_TYPE(type);
8747 /* we have to go by the storage class */
8748 p_type = PTR_TYPE(SPEC_OCLS(etype));
8750 /* if (SPEC_OCLS(etype)->codesp ) { */
8751 /* p_type = CPOINTER ; */
8754 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8755 /* p_type = FPOINTER ; */
8757 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8758 /* p_type = PPOINTER ; */
8760 /* if (SPEC_OCLS(etype) == idata ) */
8761 /* p_type = IPOINTER ; */
8763 /* p_type = POINTER ; */
8766 /* now that we have the pointer type we assign
8767 the pointer values */
8772 genNearPointerSet (right,result,ic);
8776 genPagedPointerSet (right,result,ic);
8780 genFarPointerSet (right,result,ic);
8784 genGenPointerSet (right,result,ic);
8788 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8789 "genPointerSet: illegal pointer type");
8793 /*-----------------------------------------------------------------*/
8794 /* genIfx - generate code for Ifx statement */
8795 /*-----------------------------------------------------------------*/
8796 static void genIfx (iCode *ic, iCode *popIc)
8798 operand *cond = IC_COND(ic);
8801 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8803 aopOp(cond,ic,FALSE);
8805 /* get the value into acc */
8806 if (AOP_TYPE(cond) != AOP_CRY)
8807 pic14_toBoolean(cond);
8810 /* the result is now in the accumulator */
8811 freeAsmop(cond,NULL,ic,TRUE);
8813 /* if there was something to be popped then do it */
8817 /* if the condition is a bit variable */
8818 if (isbit && IS_ITEMP(cond) &&
8820 genIfxJump(ic,SPIL_LOC(cond)->rname);
8821 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8824 if (isbit && !IS_ITEMP(cond))
8825 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8833 /*-----------------------------------------------------------------*/
8834 /* genAddrOf - generates code for address of */
8835 /*-----------------------------------------------------------------*/
8836 static void genAddrOf (iCode *ic)
8838 operand *right, *result, *left;
8841 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8844 //aopOp(IC_RESULT(ic),ic,FALSE);
8846 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8847 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8848 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8850 DEBUGpic14_AopType(__LINE__,left,right,result);
8852 size = AOP_SIZE(IC_RESULT(ic));
8856 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
8857 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8861 freeAsmop(left,NULL,ic,FALSE);
8862 freeAsmop(result,NULL,ic,TRUE);
8867 /*-----------------------------------------------------------------*/
8868 /* genFarFarAssign - assignment when both are in far space */
8869 /*-----------------------------------------------------------------*/
8870 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8872 int size = AOP_SIZE(right);
8875 /* first push the right side on to the stack */
8877 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8879 pic14_emitcode ("push","acc");
8882 freeAsmop(right,NULL,ic,FALSE);
8883 /* now assign DPTR to result */
8884 aopOp(result,ic,FALSE);
8885 size = AOP_SIZE(result);
8887 pic14_emitcode ("pop","acc");
8888 aopPut(AOP(result),"a",--offset);
8890 freeAsmop(result,NULL,ic,FALSE);
8895 /*-----------------------------------------------------------------*/
8896 /* genAssign - generate code for assignment */
8897 /*-----------------------------------------------------------------*/
8898 static void genAssign (iCode *ic)
8900 operand *result, *right;
8901 int size, offset,know_W;
8902 unsigned long lit = 0L;
8904 result = IC_RESULT(ic);
8905 right = IC_RIGHT(ic) ;
8907 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8909 /* if they are the same */
8910 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8913 aopOp(right,ic,FALSE);
8914 aopOp(result,ic,TRUE);
8916 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8918 /* if they are the same registers */
8919 if (pic14_sameRegs(AOP(right),AOP(result)))
8922 /* if the result is a bit */
8923 if (AOP_TYPE(result) == AOP_CRY) {
8925 /* if the right size is a literal then
8926 we know what the value is */
8927 if (AOP_TYPE(right) == AOP_LIT) {
8929 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8930 popGet(AOP(result),0));
8932 if (((int) operandLitValue(right)))
8933 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8934 AOP(result)->aopu.aop_dir,
8935 AOP(result)->aopu.aop_dir);
8937 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8938 AOP(result)->aopu.aop_dir,
8939 AOP(result)->aopu.aop_dir);
8943 /* the right is also a bit variable */
8944 if (AOP_TYPE(right) == AOP_CRY) {
8945 emitpcode(POC_BCF, popGet(AOP(result),0));
8946 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8947 emitpcode(POC_BSF, popGet(AOP(result),0));
8949 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8950 AOP(result)->aopu.aop_dir,
8951 AOP(result)->aopu.aop_dir);
8952 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8953 AOP(right)->aopu.aop_dir,
8954 AOP(right)->aopu.aop_dir);
8955 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8956 AOP(result)->aopu.aop_dir,
8957 AOP(result)->aopu.aop_dir);
8962 emitpcode(POC_BCF, popGet(AOP(result),0));
8963 pic14_toBoolean(right);
8965 emitpcode(POC_BSF, popGet(AOP(result),0));
8966 //aopPut(AOP(result),"a",0);
8970 /* bit variables done */
8972 size = AOP_SIZE(result);
8974 if(AOP_TYPE(right) == AOP_LIT)
8975 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8977 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8978 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8979 if(aopIdx(AOP(result),0) == 4) {
8980 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8981 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8982 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8985 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8991 if(AOP_TYPE(right) == AOP_LIT) {
8993 if(know_W != (lit&0xff))
8994 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8996 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8998 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9002 } else if (AOP_TYPE(right) == AOP_CRY) {
9003 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9005 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9006 emitpcode(POC_INCF, popGet(AOP(result),0));
9009 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9010 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9011 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9019 freeAsmop (right,NULL,ic,FALSE);
9020 freeAsmop (result,NULL,ic,TRUE);
9023 /*-----------------------------------------------------------------*/
9024 /* genJumpTab - genrates code for jump table */
9025 /*-----------------------------------------------------------------*/
9026 static void genJumpTab (iCode *ic)
9031 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9033 aopOp(IC_JTCOND(ic),ic,FALSE);
9034 /* get the condition into accumulator */
9035 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9037 /* multiply by three */
9038 pic14_emitcode("add","a,acc");
9039 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9041 jtab = newiTempLabel(NULL);
9042 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9043 pic14_emitcode("jmp","@a+dptr");
9044 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9046 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9047 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9049 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9050 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9051 emitpLabel(jtab->key);
9053 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9055 /* now generate the jump labels */
9056 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9057 jtab = setNextItem(IC_JTLABELS(ic))) {
9058 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9059 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9065 /*-----------------------------------------------------------------*/
9066 /* genMixedOperation - gen code for operators between mixed types */
9067 /*-----------------------------------------------------------------*/
9069 TSD - Written for the PIC port - but this unfortunately is buggy.
9070 This routine is good in that it is able to efficiently promote
9071 types to different (larger) sizes. Unfortunately, the temporary
9072 variables that are optimized out by this routine are sometimes
9073 used in other places. So until I know how to really parse the
9074 iCode tree, I'm going to not be using this routine :(.
9076 static int genMixedOperation (iCode *ic)
9079 operand *result = IC_RESULT(ic);
9080 sym_link *ctype = operandType(IC_LEFT(ic));
9081 operand *right = IC_RIGHT(ic);
9087 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9089 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9095 nextright = IC_RIGHT(nextic);
9096 nextleft = IC_LEFT(nextic);
9097 nextresult = IC_RESULT(nextic);
9099 aopOp(right,ic,FALSE);
9100 aopOp(result,ic,FALSE);
9101 aopOp(nextright, nextic, FALSE);
9102 aopOp(nextleft, nextic, FALSE);
9103 aopOp(nextresult, nextic, FALSE);
9105 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9111 pic14_emitcode(";remove right +","");
9113 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9119 pic14_emitcode(";remove left +","");
9123 big = AOP_SIZE(nextleft);
9124 small = AOP_SIZE(nextright);
9126 switch(nextic->op) {
9129 pic14_emitcode(";optimize a +","");
9130 /* if unsigned or not an integral type */
9131 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9132 pic14_emitcode(";add a bit to something","");
9135 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9137 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9138 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9139 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9141 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9149 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9150 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9151 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9154 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9156 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9157 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9158 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9159 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9160 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9163 pic14_emitcode("rlf","known_zero,w");
9170 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9171 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9172 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9174 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9184 freeAsmop(right,NULL,ic,TRUE);
9185 freeAsmop(result,NULL,ic,TRUE);
9186 freeAsmop(nextright,NULL,ic,TRUE);
9187 freeAsmop(nextleft,NULL,ic,TRUE);
9189 nextic->generated = 1;
9196 /*-----------------------------------------------------------------*/
9197 /* genCast - gen code for casting */
9198 /*-----------------------------------------------------------------*/
9199 static void genCast (iCode *ic)
9201 operand *result = IC_RESULT(ic);
9202 sym_link *ctype = operandType(IC_LEFT(ic));
9203 sym_link *rtype = operandType(IC_RIGHT(ic));
9204 operand *right = IC_RIGHT(ic);
9207 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9208 /* if they are equivalent then do nothing */
9209 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9212 aopOp(right,ic,FALSE) ;
9213 aopOp(result,ic,FALSE);
9215 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9217 /* if the result is a bit */
9218 if (AOP_TYPE(result) == AOP_CRY) {
9219 /* if the right size is a literal then
9220 we know what the value is */
9221 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9222 if (AOP_TYPE(right) == AOP_LIT) {
9224 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9225 popGet(AOP(result),0));
9227 if (((int) operandLitValue(right)))
9228 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9229 AOP(result)->aopu.aop_dir,
9230 AOP(result)->aopu.aop_dir);
9232 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9233 AOP(result)->aopu.aop_dir,
9234 AOP(result)->aopu.aop_dir);
9239 /* the right is also a bit variable */
9240 if (AOP_TYPE(right) == AOP_CRY) {
9243 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9245 pic14_emitcode("clrc","");
9246 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9247 AOP(right)->aopu.aop_dir,
9248 AOP(right)->aopu.aop_dir);
9249 aopPut(AOP(result),"c",0);
9254 if (AOP_TYPE(right) == AOP_REG) {
9255 emitpcode(POC_BCF, popGet(AOP(result),0));
9256 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9257 emitpcode(POC_BSF, popGet(AOP(result),0));
9259 pic14_toBoolean(right);
9260 aopPut(AOP(result),"a",0);
9264 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9266 size = AOP_SIZE(result);
9268 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9270 emitpcode(POC_CLRF, popGet(AOP(result),0));
9271 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9272 emitpcode(POC_INCF, popGet(AOP(result),0));
9275 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9280 /* if they are the same size : or less */
9281 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9283 /* if they are in the same place */
9284 if (pic14_sameRegs(AOP(right),AOP(result)))
9287 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9288 if (IS_PTR_CONST(rtype))
9289 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9290 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9291 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9293 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9294 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9295 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9296 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9297 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9298 if(AOP_SIZE(result) <2)
9299 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9303 /* if they in different places then copy */
9304 size = AOP_SIZE(result);
9307 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9308 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9310 //aopPut(AOP(result),
9311 // aopGet(AOP(right),offset,FALSE,FALSE),
9321 /* if the result is of type pointer */
9322 if (IS_PTR(ctype)) {
9325 sym_link *type = operandType(right);
9326 sym_link *etype = getSpec(type);
9327 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9329 /* pointer to generic pointer */
9330 if (IS_GENPTR(ctype)) {
9334 p_type = DCL_TYPE(type);
9336 /* we have to go by the storage class */
9337 p_type = PTR_TYPE(SPEC_OCLS(etype));
9339 /* if (SPEC_OCLS(etype)->codesp ) */
9340 /* p_type = CPOINTER ; */
9342 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9343 /* p_type = FPOINTER ; */
9345 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9346 /* p_type = PPOINTER; */
9348 /* if (SPEC_OCLS(etype) == idata ) */
9349 /* p_type = IPOINTER ; */
9351 /* p_type = POINTER ; */
9354 /* the first two bytes are known */
9355 size = GPTRSIZE - 1;
9358 if(offset < AOP_SIZE(right))
9360 aopGet(AOP(right),offset,FALSE,FALSE),
9363 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9366 /* the last byte depending on type */
9370 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9373 pic14_emitcode(";BUG!? ","%d",__LINE__);
9377 pic14_emitcode(";BUG!? ","%d",__LINE__);
9381 pic14_emitcode(";BUG!? ","%d",__LINE__);
9386 /* this should never happen */
9387 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9388 "got unknown pointer type");
9391 //aopPut(AOP(result),l, GPTRSIZE - 1);
9395 /* just copy the pointers */
9396 size = AOP_SIZE(result);
9400 aopGet(AOP(right),offset,FALSE,FALSE),
9409 /* so we now know that the size of destination is greater
9410 than the size of the source.
9411 Now, if the next iCode is an operator then we might be
9412 able to optimize the operation without performing a cast.
9414 if(genMixedOperation(ic))
9417 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9419 /* we move to result for the size of source */
9420 size = AOP_SIZE(right);
9423 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9424 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9428 /* now depending on the sign of the destination */
9429 size = AOP_SIZE(result) - AOP_SIZE(right);
9430 /* if unsigned or not an integral type */
9431 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9433 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9435 /* we need to extend the sign :{ */
9438 /* Save one instruction of casting char to int */
9439 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9440 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9441 emitpcode(POC_DECF, popGet(AOP(result),offset));
9443 emitpcodeNULLop(POC_CLRW);
9446 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9448 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9450 emitpcode(POC_MOVLW, popGetLit(0xff));
9453 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9458 freeAsmop(right,NULL,ic,TRUE);
9459 freeAsmop(result,NULL,ic,TRUE);
9463 /*-----------------------------------------------------------------*/
9464 /* genDjnz - generate decrement & jump if not zero instrucion */
9465 /*-----------------------------------------------------------------*/
9466 static int genDjnz (iCode *ic, iCode *ifx)
9469 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9474 /* if the if condition has a false label
9475 then we cannot save */
9479 /* if the minus is not of the form
9481 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9482 !IS_OP_LITERAL(IC_RIGHT(ic)))
9485 if (operandLitValue(IC_RIGHT(ic)) != 1)
9488 /* if the size of this greater than one then no
9490 if (getSize(operandType(IC_RESULT(ic))) > 1)
9493 /* otherwise we can save BIG */
9494 lbl = newiTempLabel(NULL);
9495 lbl1= newiTempLabel(NULL);
9497 aopOp(IC_RESULT(ic),ic,FALSE);
9499 if (IS_AOP_PREG(IC_RESULT(ic))) {
9500 pic14_emitcode("dec","%s",
9501 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9502 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9503 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9507 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9508 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9510 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9511 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9514 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9515 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9516 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9517 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9520 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9525 /*-----------------------------------------------------------------*/
9526 /* genReceive - generate code for a receive iCode */
9527 /*-----------------------------------------------------------------*/
9528 static void genReceive (iCode *ic)
9530 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9532 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9533 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9534 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9536 int size = getSize(operandType(IC_RESULT(ic)));
9537 int offset = fReturnSizePic - size;
9539 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9540 fReturn[fReturnSizePic - offset - 1] : "acc"));
9543 aopOp(IC_RESULT(ic),ic,FALSE);
9544 size = AOP_SIZE(IC_RESULT(ic));
9547 pic14_emitcode ("pop","acc");
9548 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9553 aopOp(IC_RESULT(ic),ic,FALSE);
9555 assignResultValue(IC_RESULT(ic));
9558 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9561 /*-----------------------------------------------------------------*/
9562 /* genpic14Code - generate code for pic14 based controllers */
9563 /*-----------------------------------------------------------------*/
9565 * At this point, ralloc.c has gone through the iCode and attempted
9566 * to optimize in a way suitable for a PIC. Now we've got to generate
9567 * PIC instructions that correspond to the iCode.
9569 * Once the instructions are generated, we'll pass through both the
9570 * peep hole optimizer and the pCode optimizer.
9571 *-----------------------------------------------------------------*/
9573 void genpic14Code (iCode *lic)
9578 lineHead = lineCurr = NULL;
9580 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9583 /* if debug information required */
9584 if (options.debug && currFunc) {
9586 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9588 if (IS_STATIC(currFunc->etype)) {
9589 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9590 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9592 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9593 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9600 for (ic = lic ; ic ; ic = ic->next ) {
9602 DEBUGpic14_emitcode(";ic","");
9603 if ( cln != ic->lineno ) {
9604 if ( options.debug ) {
9606 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9607 FileBaseName(ic->filename),ic->lineno,
9608 ic->level,ic->block);
9611 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9612 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9613 printCLine(ic->filename, ic->lineno));
9617 /* if the result is marked as
9618 spilt and rematerializable or code for
9619 this has already been generated then
9621 if (resultRemat(ic) || ic->generated )
9624 /* depending on the operation */
9643 /* IPOP happens only when trying to restore a
9644 spilt live range, if there is an ifx statement
9645 following this pop then the if statement might
9646 be using some of the registers being popped which
9647 would destory the contents of the register so
9648 we need to check for this condition and handle it */
9650 ic->next->op == IFX &&
9651 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9652 genIfx (ic->next,ic);
9670 genEndFunction (ic);
9690 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9707 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9711 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9718 /* note these two are xlated by algebraic equivalence
9719 during parsing SDCC.y */
9720 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9721 "got '>=' or '<=' shouldn't have come here");
9725 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9737 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9741 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9745 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9772 case GET_VALUE_AT_ADDRESS:
9777 if (POINTER_SET(ic))
9804 addSet(&_G.sendSet,ic);
9813 /* now we are ready to call the
9814 peep hole optimizer */
9815 if (!options.nopeep) {
9816 peepHole (&lineHead);
9818 /* now do the actual printing */
9819 printLine (lineHead,codeOutFile);
9822 DFPRINTF((stderr,"printing pBlock\n\n"));
9823 printpBlock(stdout,pb);