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),offr));
6151 emitpcode(POC_RRF, popGet(AOP(result),offr));
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(left),offl));
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));
6196 emitpcode(POC_MOVLW, popGetLit(0x00));
6197 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6198 emitpcode(POC_MOVLW, popGetLit(0xfe));
6199 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6200 emitpcode(POC_IORLW, popGetLit(0x01));
6201 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6203 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6204 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6205 emitpcode(POC_DECF, popGet(AOP(result),offr));
6206 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6207 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6213 emitpcode(POC_MOVLW, popGetLit(0x00));
6214 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6215 emitpcode(POC_MOVLW, popGetLit(0xff));
6216 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6218 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6219 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6220 emitpcode(POC_DECF, popGet(AOP(result),offr));
6228 /*-----------------------------------------------------------------*/
6229 /* shiftR1Left2Result - shift right one byte from left to result */
6230 /*-----------------------------------------------------------------*/
6231 static void shiftR1Left2Result (operand *left, int offl,
6232 operand *result, int offr,
6233 int shCount, int sign)
6237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6239 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6241 /* Copy the msb into the carry if signed. */
6243 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6253 emitpcode(POC_RRF, popGet(AOP(result),offr));
6255 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6256 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6262 emitpcode(POC_RRF, popGet(AOP(result),offr));
6264 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6265 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6268 emitpcode(POC_RRF, popGet(AOP(result),offr));
6273 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6275 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6276 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6279 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6280 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6281 emitpcode(POC_ANDLW, popGetLit(0x1f));
6282 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6286 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6287 emitpcode(POC_ANDLW, popGetLit(0x0f));
6288 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6292 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6293 emitpcode(POC_ANDLW, popGetLit(0x0f));
6294 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6296 emitpcode(POC_RRF, popGet(AOP(result),offr));
6301 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6302 emitpcode(POC_ANDLW, popGetLit(0x80));
6303 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6304 emitpcode(POC_RLF, popGet(AOP(result),offr));
6305 emitpcode(POC_RLF, popGet(AOP(result),offr));
6310 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6311 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6312 emitpcode(POC_RLF, popGet(AOP(result),offr));
6321 /*-----------------------------------------------------------------*/
6322 /* shiftL1Left2Result - shift left one byte from left to result */
6323 /*-----------------------------------------------------------------*/
6324 static void shiftL1Left2Result (operand *left, int offl,
6325 operand *result, int offr, int shCount)
6330 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6332 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6333 DEBUGpic14_emitcode ("; ***","same = %d",same);
6334 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6336 /* shift left accumulator */
6337 //AccLsh(shCount); // don't comment out just yet...
6338 // aopPut(AOP(result),"a",offr);
6342 /* Shift left 1 bit position */
6343 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6345 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6347 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6348 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6352 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6353 emitpcode(POC_ANDLW,popGetLit(0x7e));
6354 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6355 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6358 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6359 emitpcode(POC_ANDLW,popGetLit(0x3e));
6360 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6361 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6362 emitpcode(POC_RLF, popGet(AOP(result),offr));
6365 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6366 emitpcode(POC_ANDLW, popGetLit(0xf0));
6367 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6370 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6371 emitpcode(POC_ANDLW, popGetLit(0xf0));
6372 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6373 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6376 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6377 emitpcode(POC_ANDLW, popGetLit(0x30));
6378 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6379 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6380 emitpcode(POC_RLF, popGet(AOP(result),offr));
6383 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6384 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6385 emitpcode(POC_RRF, popGet(AOP(result),offr));
6389 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6394 /*-----------------------------------------------------------------*/
6395 /* movLeft2Result - move byte from left to result */
6396 /*-----------------------------------------------------------------*/
6397 static void movLeft2Result (operand *left, int offl,
6398 operand *result, int offr)
6401 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6402 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6403 l = aopGet(AOP(left),offl,FALSE,FALSE);
6405 if (*l == '@' && (IS_AOP_PREG(result))) {
6406 pic14_emitcode("mov","a,%s",l);
6407 aopPut(AOP(result),"a",offr);
6409 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6410 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6415 /*-----------------------------------------------------------------*/
6416 /* shiftL2Left2Result - shift left two bytes from left to result */
6417 /*-----------------------------------------------------------------*/
6418 static void shiftL2Left2Result (operand *left, int offl,
6419 operand *result, int offr, int shCount)
6423 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6425 if(pic14_sameRegs(AOP(result), AOP(left))) {
6433 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6434 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6435 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6439 emitpcode(POC_RLF, popGet(AOP(result),offr));
6440 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6446 emitpcode(POC_MOVLW, popGetLit(0x0f));
6447 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6448 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6449 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6450 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6451 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6452 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6454 emitpcode(POC_RLF, popGet(AOP(result),offr));
6455 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6459 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6460 emitpcode(POC_RRF, popGet(AOP(result),offr));
6461 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6462 emitpcode(POC_RRF, popGet(AOP(result),offr));
6463 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6464 emitpcode(POC_ANDLW,popGetLit(0xc0));
6465 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6466 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6467 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6468 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6471 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6472 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6473 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6474 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6475 emitpcode(POC_RRF, popGet(AOP(result),offr));
6485 /* note, use a mov/add for the shift since the mov has a
6486 chance of getting optimized out */
6487 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6488 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6489 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6490 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6491 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6495 emitpcode(POC_RLF, popGet(AOP(result),offr));
6496 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6502 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6503 emitpcode(POC_ANDLW, popGetLit(0xF0));
6504 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6505 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6506 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6507 emitpcode(POC_ANDLW, popGetLit(0xF0));
6508 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6509 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6513 emitpcode(POC_RLF, popGet(AOP(result),offr));
6514 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6518 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6519 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6520 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6521 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6523 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6524 emitpcode(POC_RRF, popGet(AOP(result),offr));
6525 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6526 emitpcode(POC_ANDLW,popGetLit(0xc0));
6527 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6528 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6529 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6530 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6533 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6534 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6535 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6536 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6537 emitpcode(POC_RRF, popGet(AOP(result),offr));
6542 /*-----------------------------------------------------------------*/
6543 /* shiftR2Left2Result - shift right two bytes from left to result */
6544 /*-----------------------------------------------------------------*/
6545 static void shiftR2Left2Result (operand *left, int offl,
6546 operand *result, int offr,
6547 int shCount, int sign)
6551 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6552 same = pic14_sameRegs(AOP(result), AOP(left));
6554 if(same && ((offl + MSB16) == offr)){
6556 /* don't crash result[offr] */
6557 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6558 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6560 movLeft2Result(left,offl, result, offr);
6561 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6563 /* a:x >> shCount (x = lsb(result))*/
6566 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6568 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6577 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6582 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6583 emitpcode(POC_RRF,popGet(AOP(result),offr));
6585 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6586 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6587 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6588 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6593 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6596 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6597 emitpcode(POC_RRF,popGet(AOP(result),offr));
6604 emitpcode(POC_MOVLW, popGetLit(0xf0));
6605 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6606 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6608 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6609 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6610 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6611 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6613 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6614 emitpcode(POC_ANDLW, popGetLit(0x0f));
6615 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6617 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6618 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6619 emitpcode(POC_ANDLW, popGetLit(0xf0));
6620 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6621 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6625 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6626 emitpcode(POC_RRF, popGet(AOP(result),offr));
6630 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6631 emitpcode(POC_BTFSC,
6632 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6633 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
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));
6649 emitpcode(POC_BTFSC,
6650 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6651 emitpcode(POC_IORLW,popGetLit(0xfc));
6653 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6654 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6655 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6656 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6658 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6659 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6660 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6661 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6662 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6663 emitpcode(POC_ANDLW,popGetLit(0x03));
6665 emitpcode(POC_BTFSC,
6666 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6667 emitpcode(POC_IORLW,popGetLit(0xfc));
6669 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6670 emitpcode(POC_RLF, popGet(AOP(result),offr));
6677 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6678 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6679 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6680 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6683 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6685 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6690 /*-----------------------------------------------------------------*/
6691 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6692 /*-----------------------------------------------------------------*/
6693 static void shiftLLeftOrResult (operand *left, int offl,
6694 operand *result, int offr, int shCount)
6696 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6697 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6698 /* shift left accumulator */
6700 /* or with result */
6701 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6702 /* back to result */
6703 aopPut(AOP(result),"a",offr);
6706 /*-----------------------------------------------------------------*/
6707 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6708 /*-----------------------------------------------------------------*/
6709 static void shiftRLeftOrResult (operand *left, int offl,
6710 operand *result, int offr, int shCount)
6712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6713 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6714 /* shift right accumulator */
6716 /* or with result */
6717 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6718 /* back to result */
6719 aopPut(AOP(result),"a",offr);
6722 /*-----------------------------------------------------------------*/
6723 /* genlshOne - left shift a one byte quantity by known count */
6724 /*-----------------------------------------------------------------*/
6725 static void genlshOne (operand *result, operand *left, int shCount)
6727 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6728 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6731 /*-----------------------------------------------------------------*/
6732 /* genlshTwo - left shift two bytes by known amount != 0 */
6733 /*-----------------------------------------------------------------*/
6734 static void genlshTwo (operand *result,operand *left, int shCount)
6738 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6739 size = pic14_getDataSize(result);
6741 /* if shCount >= 8 */
6747 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6749 movLeft2Result(left, LSB, result, MSB16);
6751 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6754 /* 1 <= shCount <= 7 */
6757 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6759 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6763 /*-----------------------------------------------------------------*/
6764 /* shiftLLong - shift left one long from left to result */
6765 /* offl = LSB or MSB16 */
6766 /*-----------------------------------------------------------------*/
6767 static void shiftLLong (operand *left, operand *result, int offr )
6770 int size = AOP_SIZE(result);
6772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6773 if(size >= LSB+offr){
6774 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6776 pic14_emitcode("add","a,acc");
6777 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6778 size >= MSB16+offr && offr != LSB )
6779 pic14_emitcode("xch","a,%s",
6780 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6782 aopPut(AOP(result),"a",LSB+offr);
6785 if(size >= MSB16+offr){
6786 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6787 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6790 pic14_emitcode("rlc","a");
6791 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6792 size >= MSB24+offr && offr != LSB)
6793 pic14_emitcode("xch","a,%s",
6794 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6796 aopPut(AOP(result),"a",MSB16+offr);
6799 if(size >= MSB24+offr){
6800 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6801 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6804 pic14_emitcode("rlc","a");
6805 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6806 size >= MSB32+offr && offr != LSB )
6807 pic14_emitcode("xch","a,%s",
6808 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6810 aopPut(AOP(result),"a",MSB24+offr);
6813 if(size > MSB32+offr){
6814 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6815 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6818 pic14_emitcode("rlc","a");
6819 aopPut(AOP(result),"a",MSB32+offr);
6822 aopPut(AOP(result),zero,LSB);
6825 /*-----------------------------------------------------------------*/
6826 /* genlshFour - shift four byte by a known amount != 0 */
6827 /*-----------------------------------------------------------------*/
6828 static void genlshFour (operand *result, operand *left, int shCount)
6832 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6833 size = AOP_SIZE(result);
6835 /* if shifting more that 3 bytes */
6836 if (shCount >= 24 ) {
6839 /* lowest order of left goes to the highest
6840 order of the destination */
6841 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6843 movLeft2Result(left, LSB, result, MSB32);
6844 aopPut(AOP(result),zero,LSB);
6845 aopPut(AOP(result),zero,MSB16);
6846 aopPut(AOP(result),zero,MSB32);
6850 /* more than two bytes */
6851 else if ( shCount >= 16 ) {
6852 /* lower order two bytes goes to higher order two bytes */
6854 /* if some more remaining */
6856 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6858 movLeft2Result(left, MSB16, result, MSB32);
6859 movLeft2Result(left, LSB, result, MSB24);
6861 aopPut(AOP(result),zero,MSB16);
6862 aopPut(AOP(result),zero,LSB);
6866 /* if more than 1 byte */
6867 else if ( shCount >= 8 ) {
6868 /* lower order three bytes goes to higher order three bytes */
6872 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6874 movLeft2Result(left, LSB, result, MSB16);
6876 else{ /* size = 4 */
6878 movLeft2Result(left, MSB24, result, MSB32);
6879 movLeft2Result(left, MSB16, result, MSB24);
6880 movLeft2Result(left, LSB, result, MSB16);
6881 aopPut(AOP(result),zero,LSB);
6883 else if(shCount == 1)
6884 shiftLLong(left, result, MSB16);
6886 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6887 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6888 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6889 aopPut(AOP(result),zero,LSB);
6894 /* 1 <= shCount <= 7 */
6895 else if(shCount <= 2){
6896 shiftLLong(left, result, LSB);
6898 shiftLLong(result, result, LSB);
6900 /* 3 <= shCount <= 7, optimize */
6902 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6903 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6904 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6908 /*-----------------------------------------------------------------*/
6909 /* genLeftShiftLiteral - left shifting by known count */
6910 /*-----------------------------------------------------------------*/
6911 static void genLeftShiftLiteral (operand *left,
6916 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6919 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6920 freeAsmop(right,NULL,ic,TRUE);
6922 aopOp(left,ic,FALSE);
6923 aopOp(result,ic,FALSE);
6925 size = getSize(operandType(result));
6928 pic14_emitcode("; shift left ","result %d, left %d",size,
6932 /* I suppose that the left size >= result size */
6935 movLeft2Result(left, size, result, size);
6939 else if(shCount >= (size * 8))
6941 aopPut(AOP(result),zero,size);
6945 genlshOne (result,left,shCount);
6950 genlshTwo (result,left,shCount);
6954 genlshFour (result,left,shCount);
6958 freeAsmop(left,NULL,ic,TRUE);
6959 freeAsmop(result,NULL,ic,TRUE);
6962 /*-----------------------------------------------------------------*
6963 * genMultiAsm - repeat assembly instruction for size of register.
6964 * if endian == 1, then the high byte (i.e base address + size of
6965 * register) is used first else the low byte is used first;
6966 *-----------------------------------------------------------------*/
6967 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
6972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6985 emitpcode(poc, popGet(AOP(reg),offset));
6990 /*-----------------------------------------------------------------*/
6991 /* genLeftShift - generates code for left shifting */
6992 /*-----------------------------------------------------------------*/
6993 static void genLeftShift (iCode *ic)
6995 operand *left,*right, *result;
6998 symbol *tlbl , *tlbl1;
7001 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7003 right = IC_RIGHT(ic);
7005 result = IC_RESULT(ic);
7007 aopOp(right,ic,FALSE);
7009 /* if the shift count is known then do it
7010 as efficiently as possible */
7011 if (AOP_TYPE(right) == AOP_LIT) {
7012 genLeftShiftLiteral (left,right,result,ic);
7016 /* shift count is unknown then we have to form
7017 a loop get the loop count in B : Note: we take
7018 only the lower order byte since shifting
7019 more that 32 bits make no sense anyway, ( the
7020 largest size of an object can be only 32 bits ) */
7023 aopOp(left,ic,FALSE);
7024 aopOp(result,ic,FALSE);
7026 /* now move the left to the result if they are not the
7028 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7029 AOP_SIZE(result) > 1) {
7031 size = AOP_SIZE(result);
7034 l = aopGet(AOP(left),offset,FALSE,TRUE);
7035 if (*l == '@' && (IS_AOP_PREG(result))) {
7037 pic14_emitcode("mov","a,%s",l);
7038 aopPut(AOP(result),"a",offset);
7040 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7041 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7042 //aopPut(AOP(result),l,offset);
7048 size = AOP_SIZE(result);
7050 /* if it is only one byte then */
7052 if(optimized_for_speed) {
7053 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7054 emitpcode(POC_ANDLW, popGetLit(0xf0));
7055 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7056 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7057 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7058 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7059 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7060 emitpcode(POC_RLFW, popGet(AOP(result),0));
7061 emitpcode(POC_ANDLW, popGetLit(0xfe));
7062 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7063 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7064 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7067 tlbl = newiTempLabel(NULL);
7068 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7069 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7070 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7073 emitpcode(POC_COMFW, popGet(AOP(right),0));
7074 emitpcode(POC_RRF, popGet(AOP(result),0));
7075 emitpLabel(tlbl->key);
7076 emitpcode(POC_RLF, popGet(AOP(result),0));
7077 emitpcode(POC_ADDLW, popGetLit(1));
7079 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7084 if (pic14_sameRegs(AOP(left),AOP(result))) {
7086 tlbl = newiTempLabel(NULL);
7087 emitpcode(POC_COMFW, popGet(AOP(right),0));
7088 genMultiAsm(POC_RRF, result, size,1);
7089 emitpLabel(tlbl->key);
7090 genMultiAsm(POC_RLF, result, size,0);
7091 emitpcode(POC_ADDLW, popGetLit(1));
7093 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7097 //tlbl = newiTempLabel(NULL);
7099 //tlbl1 = newiTempLabel(NULL);
7101 //reAdjustPreg(AOP(result));
7103 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7104 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7105 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7107 //pic14_emitcode("add","a,acc");
7108 //aopPut(AOP(result),"a",offset++);
7110 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7112 // pic14_emitcode("rlc","a");
7113 // aopPut(AOP(result),"a",offset++);
7115 //reAdjustPreg(AOP(result));
7117 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7118 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7121 tlbl = newiTempLabel(NULL);
7122 tlbl1= newiTempLabel(NULL);
7124 size = AOP_SIZE(result);
7127 pctemp = popGetTempReg(); /* grab a temporary working register. */
7129 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7131 /* offset should be 0, 1 or 3 */
7132 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7134 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7136 emitpcode(POC_MOVWF, pctemp);
7139 emitpLabel(tlbl->key);
7142 emitpcode(POC_RLF, popGet(AOP(result),0));
7144 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7146 emitpcode(POC_DECFSZ, pctemp);
7147 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7148 emitpLabel(tlbl1->key);
7150 popReleaseTempReg(pctemp);
7154 freeAsmop (right,NULL,ic,TRUE);
7155 freeAsmop(left,NULL,ic,TRUE);
7156 freeAsmop(result,NULL,ic,TRUE);
7159 /*-----------------------------------------------------------------*/
7160 /* genrshOne - right shift a one byte quantity by known count */
7161 /*-----------------------------------------------------------------*/
7162 static void genrshOne (operand *result, operand *left,
7163 int shCount, int sign)
7165 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7166 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7169 /*-----------------------------------------------------------------*/
7170 /* genrshTwo - right shift two bytes by known amount != 0 */
7171 /*-----------------------------------------------------------------*/
7172 static void genrshTwo (operand *result,operand *left,
7173 int shCount, int sign)
7175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7176 /* if shCount >= 8 */
7180 shiftR1Left2Result(left, MSB16, result, LSB,
7183 movLeft2Result(left, MSB16, result, LSB);
7185 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7188 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7189 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7193 /* 1 <= shCount <= 7 */
7195 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7198 /*-----------------------------------------------------------------*/
7199 /* shiftRLong - shift right one long from left to result */
7200 /* offl = LSB or MSB16 */
7201 /*-----------------------------------------------------------------*/
7202 static void shiftRLong (operand *left, int offl,
7203 operand *result, int sign)
7205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7207 pic14_emitcode("clr","c");
7208 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7210 pic14_emitcode("mov","c,acc.7");
7211 pic14_emitcode("rrc","a");
7212 aopPut(AOP(result),"a",MSB32-offl);
7214 /* add sign of "a" */
7215 addSign(result, MSB32, sign);
7217 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7218 pic14_emitcode("rrc","a");
7219 aopPut(AOP(result),"a",MSB24-offl);
7221 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7222 pic14_emitcode("rrc","a");
7223 aopPut(AOP(result),"a",MSB16-offl);
7226 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7227 pic14_emitcode("rrc","a");
7228 aopPut(AOP(result),"a",LSB);
7232 /*-----------------------------------------------------------------*/
7233 /* genrshFour - shift four byte by a known amount != 0 */
7234 /*-----------------------------------------------------------------*/
7235 static void genrshFour (operand *result, operand *left,
7236 int shCount, int sign)
7238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7239 /* if shifting more that 3 bytes */
7240 if(shCount >= 24 ) {
7243 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7245 movLeft2Result(left, MSB32, result, LSB);
7247 addSign(result, MSB16, sign);
7249 else if(shCount >= 16){
7252 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7254 movLeft2Result(left, MSB24, result, LSB);
7255 movLeft2Result(left, MSB32, result, MSB16);
7257 addSign(result, MSB24, sign);
7259 else if(shCount >= 8){
7262 shiftRLong(left, MSB16, result, sign);
7263 else if(shCount == 0){
7264 movLeft2Result(left, MSB16, result, LSB);
7265 movLeft2Result(left, MSB24, result, MSB16);
7266 movLeft2Result(left, MSB32, result, MSB24);
7267 addSign(result, MSB32, sign);
7270 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7271 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7272 /* the last shift is signed */
7273 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7274 addSign(result, MSB32, sign);
7277 else{ /* 1 <= shCount <= 7 */
7279 shiftRLong(left, LSB, result, sign);
7281 shiftRLong(result, LSB, result, sign);
7284 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7285 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7286 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7291 /*-----------------------------------------------------------------*/
7292 /* genRightShiftLiteral - right shifting by known count */
7293 /*-----------------------------------------------------------------*/
7294 static void genRightShiftLiteral (operand *left,
7300 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7304 freeAsmop(right,NULL,ic,TRUE);
7306 aopOp(left,ic,FALSE);
7307 aopOp(result,ic,FALSE);
7310 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7314 lsize = pic14_getDataSize(left);
7315 res_size = pic14_getDataSize(result);
7316 /* test the LEFT size !!! */
7318 /* I suppose that the left size >= result size */
7321 movLeft2Result(left, lsize, result, res_size);
7324 else if(shCount >= (lsize * 8)){
7327 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7329 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7330 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7335 emitpcode(POC_MOVLW, popGetLit(0));
7336 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7337 emitpcode(POC_MOVLW, popGetLit(0xff));
7339 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7344 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7351 genrshOne (result,left,shCount,sign);
7355 genrshTwo (result,left,shCount,sign);
7359 genrshFour (result,left,shCount,sign);
7367 freeAsmop(left,NULL,ic,TRUE);
7368 freeAsmop(result,NULL,ic,TRUE);
7371 /*-----------------------------------------------------------------*/
7372 /* genSignedRightShift - right shift of signed number */
7373 /*-----------------------------------------------------------------*/
7374 static void genSignedRightShift (iCode *ic)
7376 operand *right, *left, *result;
7379 symbol *tlbl, *tlbl1 ;
7382 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7384 /* we do it the hard way put the shift count in b
7385 and loop thru preserving the sign */
7386 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7388 right = IC_RIGHT(ic);
7390 result = IC_RESULT(ic);
7392 aopOp(right,ic,FALSE);
7393 aopOp(left,ic,FALSE);
7394 aopOp(result,ic,FALSE);
7397 if ( AOP_TYPE(right) == AOP_LIT) {
7398 genRightShiftLiteral (left,right,result,ic,1);
7401 /* shift count is unknown then we have to form
7402 a loop get the loop count in B : Note: we take
7403 only the lower order byte since shifting
7404 more that 32 bits make no sense anyway, ( the
7405 largest size of an object can be only 32 bits ) */
7407 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7408 //pic14_emitcode("inc","b");
7409 //freeAsmop (right,NULL,ic,TRUE);
7410 //aopOp(left,ic,FALSE);
7411 //aopOp(result,ic,FALSE);
7413 /* now move the left to the result if they are not the
7415 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7416 AOP_SIZE(result) > 1) {
7418 size = AOP_SIZE(result);
7422 l = aopGet(AOP(left),offset,FALSE,TRUE);
7423 if (*l == '@' && IS_AOP_PREG(result)) {
7425 pic14_emitcode("mov","a,%s",l);
7426 aopPut(AOP(result),"a",offset);
7428 aopPut(AOP(result),l,offset);
7430 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7431 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7437 /* mov the highest order bit to OVR */
7438 tlbl = newiTempLabel(NULL);
7439 tlbl1= newiTempLabel(NULL);
7441 size = AOP_SIZE(result);
7444 pctemp = popGetTempReg(); /* grab a temporary working register. */
7446 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7448 /* offset should be 0, 1 or 3 */
7449 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7451 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7453 emitpcode(POC_MOVWF, pctemp);
7456 emitpLabel(tlbl->key);
7458 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7459 emitpcode(POC_RRF, popGet(AOP(result),offset));
7462 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7465 emitpcode(POC_DECFSZ, pctemp);
7466 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7467 emitpLabel(tlbl1->key);
7469 popReleaseTempReg(pctemp);
7471 size = AOP_SIZE(result);
7473 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7474 pic14_emitcode("rlc","a");
7475 pic14_emitcode("mov","ov,c");
7476 /* if it is only one byte then */
7478 l = aopGet(AOP(left),0,FALSE,FALSE);
7480 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7481 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7482 pic14_emitcode("mov","c,ov");
7483 pic14_emitcode("rrc","a");
7484 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7485 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7486 aopPut(AOP(result),"a",0);
7490 reAdjustPreg(AOP(result));
7491 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7492 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7493 pic14_emitcode("mov","c,ov");
7495 l = aopGet(AOP(result),offset,FALSE,FALSE);
7497 pic14_emitcode("rrc","a");
7498 aopPut(AOP(result),"a",offset--);
7500 reAdjustPreg(AOP(result));
7501 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7502 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7507 freeAsmop(left,NULL,ic,TRUE);
7508 freeAsmop(result,NULL,ic,TRUE);
7509 freeAsmop(right,NULL,ic,TRUE);
7512 /*-----------------------------------------------------------------*/
7513 /* genRightShift - generate code for right shifting */
7514 /*-----------------------------------------------------------------*/
7515 static void genRightShift (iCode *ic)
7517 operand *right, *left, *result;
7521 symbol *tlbl, *tlbl1 ;
7523 /* if signed then we do it the hard way preserve the
7524 sign bit moving it inwards */
7525 retype = getSpec(operandType(IC_RESULT(ic)));
7526 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7528 if (!SPEC_USIGN(retype)) {
7529 genSignedRightShift (ic);
7533 /* signed & unsigned types are treated the same : i.e. the
7534 signed is NOT propagated inwards : quoting from the
7535 ANSI - standard : "for E1 >> E2, is equivalent to division
7536 by 2**E2 if unsigned or if it has a non-negative value,
7537 otherwise the result is implementation defined ", MY definition
7538 is that the sign does not get propagated */
7540 right = IC_RIGHT(ic);
7542 result = IC_RESULT(ic);
7544 aopOp(right,ic,FALSE);
7546 /* if the shift count is known then do it
7547 as efficiently as possible */
7548 if (AOP_TYPE(right) == AOP_LIT) {
7549 genRightShiftLiteral (left,right,result,ic, 0);
7553 /* shift count is unknown then we have to form
7554 a loop get the loop count in B : Note: we take
7555 only the lower order byte since shifting
7556 more that 32 bits make no sense anyway, ( the
7557 largest size of an object can be only 32 bits ) */
7559 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7560 pic14_emitcode("inc","b");
7561 aopOp(left,ic,FALSE);
7562 aopOp(result,ic,FALSE);
7564 /* now move the left to the result if they are not the
7566 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7567 AOP_SIZE(result) > 1) {
7569 size = AOP_SIZE(result);
7572 l = aopGet(AOP(left),offset,FALSE,TRUE);
7573 if (*l == '@' && IS_AOP_PREG(result)) {
7575 pic14_emitcode("mov","a,%s",l);
7576 aopPut(AOP(result),"a",offset);
7578 aopPut(AOP(result),l,offset);
7583 tlbl = newiTempLabel(NULL);
7584 tlbl1= newiTempLabel(NULL);
7585 size = AOP_SIZE(result);
7588 /* if it is only one byte then */
7591 tlbl = newiTempLabel(NULL);
7592 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7593 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7594 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7597 emitpcode(POC_COMFW, popGet(AOP(right),0));
7598 emitpcode(POC_RLF, popGet(AOP(result),0));
7599 emitpLabel(tlbl->key);
7600 emitpcode(POC_RRF, popGet(AOP(result),0));
7601 emitpcode(POC_ADDLW, popGetLit(1));
7603 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7608 reAdjustPreg(AOP(result));
7609 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7610 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7613 l = aopGet(AOP(result),offset,FALSE,FALSE);
7615 pic14_emitcode("rrc","a");
7616 aopPut(AOP(result),"a",offset--);
7618 reAdjustPreg(AOP(result));
7620 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7621 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7624 freeAsmop(left,NULL,ic,TRUE);
7625 freeAsmop (right,NULL,ic,TRUE);
7626 freeAsmop(result,NULL,ic,TRUE);
7629 /*-----------------------------------------------------------------*/
7630 /* genUnpackBits - generates code for unpacking bits */
7631 /*-----------------------------------------------------------------*/
7632 static void genUnpackBits (operand *result, char *rname, int ptype)
7639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7640 etype = getSpec(operandType(result));
7642 /* read the first byte */
7647 pic14_emitcode("mov","a,@%s",rname);
7651 pic14_emitcode("movx","a,@%s",rname);
7655 pic14_emitcode("movx","a,@dptr");
7659 pic14_emitcode("clr","a");
7660 pic14_emitcode("movc","a","@a+dptr");
7664 pic14_emitcode("lcall","__gptrget");
7668 /* if we have bitdisplacement then it fits */
7669 /* into this byte completely or if length is */
7670 /* less than a byte */
7671 if ((shCnt = SPEC_BSTR(etype)) ||
7672 (SPEC_BLEN(etype) <= 8)) {
7674 /* shift right acc */
7677 pic14_emitcode("anl","a,#0x%02x",
7678 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7679 aopPut(AOP(result),"a",offset);
7683 /* bit field did not fit in a byte */
7684 rlen = SPEC_BLEN(etype) - 8;
7685 aopPut(AOP(result),"a",offset++);
7692 pic14_emitcode("inc","%s",rname);
7693 pic14_emitcode("mov","a,@%s",rname);
7697 pic14_emitcode("inc","%s",rname);
7698 pic14_emitcode("movx","a,@%s",rname);
7702 pic14_emitcode("inc","dptr");
7703 pic14_emitcode("movx","a,@dptr");
7707 pic14_emitcode("clr","a");
7708 pic14_emitcode("inc","dptr");
7709 pic14_emitcode("movc","a","@a+dptr");
7713 pic14_emitcode("inc","dptr");
7714 pic14_emitcode("lcall","__gptrget");
7719 /* if we are done */
7723 aopPut(AOP(result),"a",offset++);
7728 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7729 aopPut(AOP(result),"a",offset);
7736 /*-----------------------------------------------------------------*/
7737 /* genDataPointerGet - generates code when ptr offset is known */
7738 /*-----------------------------------------------------------------*/
7739 static void genDataPointerGet (operand *left,
7743 int size , offset = 0;
7746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7749 /* optimization - most of the time, left and result are the same
7750 * address, but different types. for the pic code, we could omit
7754 aopOp(result,ic,TRUE);
7756 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7758 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7760 size = AOP_SIZE(result);
7763 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7767 freeAsmop(left,NULL,ic,TRUE);
7768 freeAsmop(result,NULL,ic,TRUE);
7771 /*-----------------------------------------------------------------*/
7772 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7773 /*-----------------------------------------------------------------*/
7774 static void genNearPointerGet (operand *left,
7781 sym_link *rtype, *retype;
7782 sym_link *ltype = operandType(left);
7785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7787 rtype = operandType(result);
7788 retype= getSpec(rtype);
7790 aopOp(left,ic,FALSE);
7792 /* if left is rematerialisable and
7793 result is not bit variable type and
7794 the left is pointer to data space i.e
7795 lower 128 bytes of space */
7796 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7797 !IS_BITVAR(retype) &&
7798 DCL_TYPE(ltype) == POINTER) {
7799 //genDataPointerGet (left,result,ic);
7803 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7805 /* if the value is already in a pointer register
7806 then don't need anything more */
7807 if (!AOP_INPREG(AOP(left))) {
7808 /* otherwise get a free pointer register */
7809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7811 preg = getFreePtr(ic,&aop,FALSE);
7812 pic14_emitcode("mov","%s,%s",
7814 aopGet(AOP(left),0,FALSE,TRUE));
7815 rname = preg->name ;
7817 rname = aopGet(AOP(left),0,FALSE,FALSE);
7819 freeAsmop(left,NULL,ic,TRUE);
7820 aopOp (result,ic,FALSE);
7822 /* if bitfield then unpack the bits */
7823 if (IS_BITVAR(retype))
7824 genUnpackBits (result,rname,POINTER);
7826 /* we have can just get the values */
7827 int size = AOP_SIZE(result);
7830 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7832 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7834 pic14_emitcode("mov","a,@%s",rname);
7835 aopPut(AOP(result),"a",offset);
7837 sprintf(buffer,"@%s",rname);
7838 aopPut(AOP(result),buffer,offset);
7842 pic14_emitcode("inc","%s",rname);
7846 /* now some housekeeping stuff */
7848 /* we had to allocate for this iCode */
7849 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7850 freeAsmop(NULL,aop,ic,TRUE);
7852 /* we did not allocate which means left
7853 already in a pointer register, then
7854 if size > 0 && this could be used again
7855 we have to point it back to where it
7857 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7858 if (AOP_SIZE(result) > 1 &&
7859 !OP_SYMBOL(left)->remat &&
7860 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7862 int size = AOP_SIZE(result) - 1;
7864 pic14_emitcode("dec","%s",rname);
7869 freeAsmop(result,NULL,ic,TRUE);
7873 /*-----------------------------------------------------------------*/
7874 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7875 /*-----------------------------------------------------------------*/
7876 static void genPagedPointerGet (operand *left,
7883 sym_link *rtype, *retype;
7885 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7887 rtype = operandType(result);
7888 retype= getSpec(rtype);
7890 aopOp(left,ic,FALSE);
7892 /* if the value is already in a pointer register
7893 then don't need anything more */
7894 if (!AOP_INPREG(AOP(left))) {
7895 /* otherwise get a free pointer register */
7897 preg = getFreePtr(ic,&aop,FALSE);
7898 pic14_emitcode("mov","%s,%s",
7900 aopGet(AOP(left),0,FALSE,TRUE));
7901 rname = preg->name ;
7903 rname = aopGet(AOP(left),0,FALSE,FALSE);
7905 freeAsmop(left,NULL,ic,TRUE);
7906 aopOp (result,ic,FALSE);
7908 /* if bitfield then unpack the bits */
7909 if (IS_BITVAR(retype))
7910 genUnpackBits (result,rname,PPOINTER);
7912 /* we have can just get the values */
7913 int size = AOP_SIZE(result);
7918 pic14_emitcode("movx","a,@%s",rname);
7919 aopPut(AOP(result),"a",offset);
7924 pic14_emitcode("inc","%s",rname);
7928 /* now some housekeeping stuff */
7930 /* we had to allocate for this iCode */
7931 freeAsmop(NULL,aop,ic,TRUE);
7933 /* we did not allocate which means left
7934 already in a pointer register, then
7935 if size > 0 && this could be used again
7936 we have to point it back to where it
7938 if (AOP_SIZE(result) > 1 &&
7939 !OP_SYMBOL(left)->remat &&
7940 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7942 int size = AOP_SIZE(result) - 1;
7944 pic14_emitcode("dec","%s",rname);
7949 freeAsmop(result,NULL,ic,TRUE);
7954 /*-----------------------------------------------------------------*/
7955 /* genFarPointerGet - gget value from far space */
7956 /*-----------------------------------------------------------------*/
7957 static void genFarPointerGet (operand *left,
7958 operand *result, iCode *ic)
7961 sym_link *retype = getSpec(operandType(result));
7963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7965 aopOp(left,ic,FALSE);
7967 /* if the operand is already in dptr
7968 then we do nothing else we move the value to dptr */
7969 if (AOP_TYPE(left) != AOP_STR) {
7970 /* if this is remateriazable */
7971 if (AOP_TYPE(left) == AOP_IMMD)
7972 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7973 else { /* we need to get it byte by byte */
7974 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7975 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7976 if (options.model == MODEL_FLAT24)
7978 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7982 /* so dptr know contains the address */
7983 freeAsmop(left,NULL,ic,TRUE);
7984 aopOp(result,ic,FALSE);
7986 /* if bit then unpack */
7987 if (IS_BITVAR(retype))
7988 genUnpackBits(result,"dptr",FPOINTER);
7990 size = AOP_SIZE(result);
7994 pic14_emitcode("movx","a,@dptr");
7995 aopPut(AOP(result),"a",offset++);
7997 pic14_emitcode("inc","dptr");
8001 freeAsmop(result,NULL,ic,TRUE);
8004 /*-----------------------------------------------------------------*/
8005 /* genCodePointerGet - get value from code space */
8006 /*-----------------------------------------------------------------*/
8007 static void genCodePointerGet (operand *left,
8008 operand *result, iCode *ic)
8011 sym_link *retype = getSpec(operandType(result));
8013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8015 aopOp(left,ic,FALSE);
8017 /* if the operand is already in dptr
8018 then we do nothing else we move the value to dptr */
8019 if (AOP_TYPE(left) != AOP_STR) {
8020 /* if this is remateriazable */
8021 if (AOP_TYPE(left) == AOP_IMMD)
8022 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8023 else { /* we need to get it byte by byte */
8024 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8025 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8026 if (options.model == MODEL_FLAT24)
8028 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8032 /* so dptr know contains the address */
8033 freeAsmop(left,NULL,ic,TRUE);
8034 aopOp(result,ic,FALSE);
8036 /* if bit then unpack */
8037 if (IS_BITVAR(retype))
8038 genUnpackBits(result,"dptr",CPOINTER);
8040 size = AOP_SIZE(result);
8044 pic14_emitcode("clr","a");
8045 pic14_emitcode("movc","a,@a+dptr");
8046 aopPut(AOP(result),"a",offset++);
8048 pic14_emitcode("inc","dptr");
8052 freeAsmop(result,NULL,ic,TRUE);
8055 /*-----------------------------------------------------------------*/
8056 /* genGenPointerGet - gget value from generic pointer space */
8057 /*-----------------------------------------------------------------*/
8058 static void genGenPointerGet (operand *left,
8059 operand *result, iCode *ic)
8062 sym_link *retype = getSpec(operandType(result));
8064 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8065 aopOp(left,ic,FALSE);
8066 aopOp(result,ic,FALSE);
8069 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8071 /* if the operand is already in dptr
8072 then we do nothing else we move the value to dptr */
8073 // if (AOP_TYPE(left) != AOP_STR) {
8074 /* if this is remateriazable */
8075 if (AOP_TYPE(left) == AOP_IMMD) {
8076 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8077 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8079 else { /* we need to get it byte by byte */
8081 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8082 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8084 size = AOP_SIZE(result);
8088 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8089 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8091 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8096 /* so dptr know contains the address */
8098 /* if bit then unpack */
8099 //if (IS_BITVAR(retype))
8100 // genUnpackBits(result,"dptr",GPOINTER);
8103 freeAsmop(left,NULL,ic,TRUE);
8104 freeAsmop(result,NULL,ic,TRUE);
8108 /*-----------------------------------------------------------------*/
8109 /* genConstPointerGet - get value from const generic pointer space */
8110 /*-----------------------------------------------------------------*/
8111 static void genConstPointerGet (operand *left,
8112 operand *result, iCode *ic)
8114 //sym_link *retype = getSpec(operandType(result));
8115 symbol *albl = newiTempLabel(NULL);
8116 symbol *blbl = newiTempLabel(NULL);
8119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8120 aopOp(left,ic,FALSE);
8121 aopOp(result,ic,FALSE);
8124 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8126 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8128 emitpcode(POC_CALL,popGetLabel(albl->key));
8129 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8130 emitpLabel(albl->key);
8132 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8134 emitpcode(poc,popGet(AOP(left),1));
8135 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8136 emitpcode(poc,popGet(AOP(left),0));
8137 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8139 emitpLabel(blbl->key);
8141 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8144 freeAsmop(left,NULL,ic,TRUE);
8145 freeAsmop(result,NULL,ic,TRUE);
8148 /*-----------------------------------------------------------------*/
8149 /* genPointerGet - generate code for pointer get */
8150 /*-----------------------------------------------------------------*/
8151 static void genPointerGet (iCode *ic)
8153 operand *left, *result ;
8154 sym_link *type, *etype;
8157 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8160 result = IC_RESULT(ic) ;
8162 /* depending on the type of pointer we need to
8163 move it to the correct pointer register */
8164 type = operandType(left);
8165 etype = getSpec(type);
8167 if (IS_PTR_CONST(type))
8168 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8170 /* if left is of type of pointer then it is simple */
8171 if (IS_PTR(type) && !IS_FUNC(type->next))
8172 p_type = DCL_TYPE(type);
8174 /* we have to go by the storage class */
8175 p_type = PTR_TYPE(SPEC_OCLS(etype));
8177 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8179 if (SPEC_OCLS(etype)->codesp ) {
8180 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8181 //p_type = CPOINTER ;
8184 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8185 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8186 /*p_type = FPOINTER ;*/
8188 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8189 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8190 /* p_type = PPOINTER; */
8192 if (SPEC_OCLS(etype) == idata )
8193 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8194 /* p_type = IPOINTER; */
8196 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8197 /* p_type = POINTER ; */
8200 /* now that we have the pointer type we assign
8201 the pointer values */
8206 genNearPointerGet (left,result,ic);
8210 genPagedPointerGet(left,result,ic);
8214 genFarPointerGet (left,result,ic);
8218 genConstPointerGet (left,result,ic);
8219 //pic14_emitcodePointerGet (left,result,ic);
8223 if (IS_PTR_CONST(type))
8224 genConstPointerGet (left,result,ic);
8226 genGenPointerGet (left,result,ic);
8232 /*-----------------------------------------------------------------*/
8233 /* genPackBits - generates code for packed bit storage */
8234 /*-----------------------------------------------------------------*/
8235 static void genPackBits (sym_link *etype ,
8237 char *rname, int p_type)
8245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8246 blen = SPEC_BLEN(etype);
8247 bstr = SPEC_BSTR(etype);
8249 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8252 /* if the bit lenth is less than or */
8253 /* it exactly fits a byte then */
8254 if (SPEC_BLEN(etype) <= 8 ) {
8255 shCount = SPEC_BSTR(etype) ;
8257 /* shift left acc */
8260 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8265 pic14_emitcode ("mov","b,a");
8266 pic14_emitcode("mov","a,@%s",rname);
8270 pic14_emitcode ("mov","b,a");
8271 pic14_emitcode("movx","a,@dptr");
8275 pic14_emitcode ("push","b");
8276 pic14_emitcode ("push","acc");
8277 pic14_emitcode ("lcall","__gptrget");
8278 pic14_emitcode ("pop","b");
8282 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8283 ((unsigned char)(0xFF << (blen+bstr)) |
8284 (unsigned char)(0xFF >> (8-bstr)) ) );
8285 pic14_emitcode ("orl","a,b");
8286 if (p_type == GPOINTER)
8287 pic14_emitcode("pop","b");
8293 pic14_emitcode("mov","@%s,a",rname);
8297 pic14_emitcode("movx","@dptr,a");
8301 DEBUGpic14_emitcode(";lcall","__gptrput");
8306 if ( SPEC_BLEN(etype) <= 8 )
8309 pic14_emitcode("inc","%s",rname);
8310 rLen = SPEC_BLEN(etype) ;
8312 /* now generate for lengths greater than one byte */
8315 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8325 pic14_emitcode("mov","@%s,a",rname);
8327 pic14_emitcode("mov","@%s,%s",rname,l);
8332 pic14_emitcode("movx","@dptr,a");
8337 DEBUGpic14_emitcode(";lcall","__gptrput");
8340 pic14_emitcode ("inc","%s",rname);
8345 /* last last was not complete */
8347 /* save the byte & read byte */
8350 pic14_emitcode ("mov","b,a");
8351 pic14_emitcode("mov","a,@%s",rname);
8355 pic14_emitcode ("mov","b,a");
8356 pic14_emitcode("movx","a,@dptr");
8360 pic14_emitcode ("push","b");
8361 pic14_emitcode ("push","acc");
8362 pic14_emitcode ("lcall","__gptrget");
8363 pic14_emitcode ("pop","b");
8367 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8368 pic14_emitcode ("orl","a,b");
8371 if (p_type == GPOINTER)
8372 pic14_emitcode("pop","b");
8377 pic14_emitcode("mov","@%s,a",rname);
8381 pic14_emitcode("movx","@dptr,a");
8385 DEBUGpic14_emitcode(";lcall","__gptrput");
8389 /*-----------------------------------------------------------------*/
8390 /* genDataPointerSet - remat pointer to data space */
8391 /*-----------------------------------------------------------------*/
8392 static void genDataPointerSet(operand *right,
8396 int size, offset = 0 ;
8397 char *l, buffer[256];
8399 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8400 aopOp(right,ic,FALSE);
8402 l = aopGet(AOP(result),0,FALSE,TRUE);
8403 size = AOP_SIZE(right);
8405 if ( AOP_TYPE(result) == AOP_PCODE) {
8406 fprintf(stderr,"genDataPointerSet %s, %d\n",
8407 AOP(result)->aopu.pcop->name,
8408 PCOI(AOP(result)->aopu.pcop)->offset);
8412 // tsd, was l+1 - the underline `_' prefix was being stripped
8415 sprintf(buffer,"(%s + %d)",l,offset);
8416 fprintf(stderr,"oops %s\n",buffer);
8418 sprintf(buffer,"%s",l);
8420 if (AOP_TYPE(right) == AOP_LIT) {
8421 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8422 lit = lit >> (8*offset);
8424 pic14_emitcode("movlw","%d",lit);
8425 pic14_emitcode("movwf","%s",buffer);
8427 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8428 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8429 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8432 pic14_emitcode("clrf","%s",buffer);
8433 //emitpcode(POC_CLRF, popRegFromString(buffer));
8434 emitpcode(POC_CLRF, popGet(AOP(result),0));
8437 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8438 pic14_emitcode("movwf","%s",buffer);
8440 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8441 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8442 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8449 freeAsmop(right,NULL,ic,TRUE);
8450 freeAsmop(result,NULL,ic,TRUE);
8453 /*-----------------------------------------------------------------*/
8454 /* genNearPointerSet - pic14_emitcode for near pointer put */
8455 /*-----------------------------------------------------------------*/
8456 static void genNearPointerSet (operand *right,
8463 sym_link *ptype = operandType(result);
8466 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8467 retype= getSpec(operandType(right));
8469 aopOp(result,ic,FALSE);
8471 /* if the result is rematerializable &
8472 in data space & not a bit variable */
8473 //if (AOP_TYPE(result) == AOP_IMMD &&
8474 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8475 DCL_TYPE(ptype) == POINTER &&
8476 !IS_BITVAR(retype)) {
8477 genDataPointerSet (right,result,ic);
8481 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8483 /* if the value is already in a pointer register
8484 then don't need anything more */
8485 if (!AOP_INPREG(AOP(result))) {
8486 /* otherwise get a free pointer register */
8487 //aop = newAsmop(0);
8488 //preg = getFreePtr(ic,&aop,FALSE);
8489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8490 //pic14_emitcode("mov","%s,%s",
8492 // aopGet(AOP(result),0,FALSE,TRUE));
8493 //rname = preg->name ;
8494 pic14_emitcode("movwf","fsr");
8496 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8498 freeAsmop(result,NULL,ic,TRUE);
8499 aopOp (right,ic,FALSE);
8500 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8502 /* if bitfield then unpack the bits */
8503 if (IS_BITVAR(retype)) {
8504 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8505 "The programmer is obviously confused");
8506 //genPackBits (retype,right,rname,POINTER);
8510 /* we have can just get the values */
8511 int size = AOP_SIZE(right);
8514 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8516 l = aopGet(AOP(right),offset,FALSE,TRUE);
8519 //pic14_emitcode("mov","@%s,a",rname);
8520 pic14_emitcode("movf","indf,w ;1");
8523 if (AOP_TYPE(right) == AOP_LIT) {
8524 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8526 pic14_emitcode("movlw","%s",l);
8527 pic14_emitcode("movwf","indf ;2");
8529 pic14_emitcode("clrf","indf");
8531 pic14_emitcode("movf","%s,w",l);
8532 pic14_emitcode("movwf","indf ;2");
8534 //pic14_emitcode("mov","@%s,%s",rname,l);
8537 pic14_emitcode("incf","fsr,f ;3");
8538 //pic14_emitcode("inc","%s",rname);
8543 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8544 /* now some housekeeping stuff */
8546 /* we had to allocate for this iCode */
8547 freeAsmop(NULL,aop,ic,TRUE);
8549 /* we did not allocate which means left
8550 already in a pointer register, then
8551 if size > 0 && this could be used again
8552 we have to point it back to where it
8554 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8555 if (AOP_SIZE(right) > 1 &&
8556 !OP_SYMBOL(result)->remat &&
8557 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8559 int size = AOP_SIZE(right) - 1;
8561 pic14_emitcode("decf","fsr,f");
8562 //pic14_emitcode("dec","%s",rname);
8566 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8568 freeAsmop(right,NULL,ic,TRUE);
8573 /*-----------------------------------------------------------------*/
8574 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8575 /*-----------------------------------------------------------------*/
8576 static void genPagedPointerSet (operand *right,
8585 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8587 retype= getSpec(operandType(right));
8589 aopOp(result,ic,FALSE);
8591 /* if the value is already in a pointer register
8592 then don't need anything more */
8593 if (!AOP_INPREG(AOP(result))) {
8594 /* otherwise get a free pointer register */
8596 preg = getFreePtr(ic,&aop,FALSE);
8597 pic14_emitcode("mov","%s,%s",
8599 aopGet(AOP(result),0,FALSE,TRUE));
8600 rname = preg->name ;
8602 rname = aopGet(AOP(result),0,FALSE,FALSE);
8604 freeAsmop(result,NULL,ic,TRUE);
8605 aopOp (right,ic,FALSE);
8607 /* if bitfield then unpack the bits */
8608 if (IS_BITVAR(retype))
8609 genPackBits (retype,right,rname,PPOINTER);
8611 /* we have can just get the values */
8612 int size = AOP_SIZE(right);
8616 l = aopGet(AOP(right),offset,FALSE,TRUE);
8619 pic14_emitcode("movx","@%s,a",rname);
8622 pic14_emitcode("inc","%s",rname);
8628 /* now some housekeeping stuff */
8630 /* we had to allocate for this iCode */
8631 freeAsmop(NULL,aop,ic,TRUE);
8633 /* we did not allocate which means left
8634 already in a pointer register, then
8635 if size > 0 && this could be used again
8636 we have to point it back to where it
8638 if (AOP_SIZE(right) > 1 &&
8639 !OP_SYMBOL(result)->remat &&
8640 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8642 int size = AOP_SIZE(right) - 1;
8644 pic14_emitcode("dec","%s",rname);
8649 freeAsmop(right,NULL,ic,TRUE);
8654 /*-----------------------------------------------------------------*/
8655 /* genFarPointerSet - set value from far space */
8656 /*-----------------------------------------------------------------*/
8657 static void genFarPointerSet (operand *right,
8658 operand *result, iCode *ic)
8661 sym_link *retype = getSpec(operandType(right));
8663 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8664 aopOp(result,ic,FALSE);
8666 /* if the operand is already in dptr
8667 then we do nothing else we move the value to dptr */
8668 if (AOP_TYPE(result) != AOP_STR) {
8669 /* if this is remateriazable */
8670 if (AOP_TYPE(result) == AOP_IMMD)
8671 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8672 else { /* we need to get it byte by byte */
8673 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8674 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8675 if (options.model == MODEL_FLAT24)
8677 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8681 /* so dptr know contains the address */
8682 freeAsmop(result,NULL,ic,TRUE);
8683 aopOp(right,ic,FALSE);
8685 /* if bit then unpack */
8686 if (IS_BITVAR(retype))
8687 genPackBits(retype,right,"dptr",FPOINTER);
8689 size = AOP_SIZE(right);
8693 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8695 pic14_emitcode("movx","@dptr,a");
8697 pic14_emitcode("inc","dptr");
8701 freeAsmop(right,NULL,ic,TRUE);
8704 /*-----------------------------------------------------------------*/
8705 /* genGenPointerSet - set value from generic pointer space */
8706 /*-----------------------------------------------------------------*/
8707 static void genGenPointerSet (operand *right,
8708 operand *result, iCode *ic)
8711 sym_link *retype = getSpec(operandType(right));
8713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8715 aopOp(result,ic,FALSE);
8716 aopOp(right,ic,FALSE);
8717 size = AOP_SIZE(right);
8719 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8721 /* if the operand is already in dptr
8722 then we do nothing else we move the value to dptr */
8723 if (AOP_TYPE(result) != AOP_STR) {
8724 /* if this is remateriazable */
8725 if (AOP_TYPE(result) == AOP_IMMD) {
8726 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8727 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8729 else { /* we need to get it byte by byte */
8730 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8731 size = AOP_SIZE(right);
8734 /* hack hack! see if this the FSR. If so don't load W */
8735 if(AOP_TYPE(right) != AOP_ACC) {
8737 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8738 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8741 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8743 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8744 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8748 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8749 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8752 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8759 if(aopIdx(AOP(result),0) != 4) {
8761 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8765 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8770 /* so dptr know contains the address */
8773 /* if bit then unpack */
8774 if (IS_BITVAR(retype))
8775 genPackBits(retype,right,"dptr",GPOINTER);
8777 size = AOP_SIZE(right);
8781 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8783 pic14_emitcode("incf","fsr,f");
8784 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8785 pic14_emitcode("movwf","indf");
8787 //DEBUGpic14_emitcode(";lcall","__gptrput");
8789 // pic14_emitcode("inc","dptr");
8794 freeAsmop(right,NULL,ic,TRUE);
8795 freeAsmop(result,NULL,ic,TRUE);
8798 /*-----------------------------------------------------------------*/
8799 /* genPointerSet - stores the value into a pointer location */
8800 /*-----------------------------------------------------------------*/
8801 static void genPointerSet (iCode *ic)
8803 operand *right, *result ;
8804 sym_link *type, *etype;
8807 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8809 right = IC_RIGHT(ic);
8810 result = IC_RESULT(ic) ;
8812 /* depending on the type of pointer we need to
8813 move it to the correct pointer register */
8814 type = operandType(result);
8815 etype = getSpec(type);
8816 /* if left is of type of pointer then it is simple */
8817 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8818 p_type = DCL_TYPE(type);
8821 /* we have to go by the storage class */
8822 p_type = PTR_TYPE(SPEC_OCLS(etype));
8824 /* if (SPEC_OCLS(etype)->codesp ) { */
8825 /* p_type = CPOINTER ; */
8828 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8829 /* p_type = FPOINTER ; */
8831 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8832 /* p_type = PPOINTER ; */
8834 /* if (SPEC_OCLS(etype) == idata ) */
8835 /* p_type = IPOINTER ; */
8837 /* p_type = POINTER ; */
8840 /* now that we have the pointer type we assign
8841 the pointer values */
8846 genNearPointerSet (right,result,ic);
8850 genPagedPointerSet (right,result,ic);
8854 genFarPointerSet (right,result,ic);
8858 genGenPointerSet (right,result,ic);
8862 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8863 "genPointerSet: illegal pointer type");
8867 /*-----------------------------------------------------------------*/
8868 /* genIfx - generate code for Ifx statement */
8869 /*-----------------------------------------------------------------*/
8870 static void genIfx (iCode *ic, iCode *popIc)
8872 operand *cond = IC_COND(ic);
8875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8877 aopOp(cond,ic,FALSE);
8879 /* get the value into acc */
8880 if (AOP_TYPE(cond) != AOP_CRY)
8881 pic14_toBoolean(cond);
8884 /* the result is now in the accumulator */
8885 freeAsmop(cond,NULL,ic,TRUE);
8887 /* if there was something to be popped then do it */
8891 /* if the condition is a bit variable */
8892 if (isbit && IS_ITEMP(cond) &&
8894 genIfxJump(ic,SPIL_LOC(cond)->rname);
8895 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8898 if (isbit && !IS_ITEMP(cond))
8899 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8907 /*-----------------------------------------------------------------*/
8908 /* genAddrOf - generates code for address of */
8909 /*-----------------------------------------------------------------*/
8910 static void genAddrOf (iCode *ic)
8912 operand *right, *result, *left;
8915 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8918 //aopOp(IC_RESULT(ic),ic,FALSE);
8920 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8921 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8922 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8924 DEBUGpic14_AopType(__LINE__,left,right,result);
8926 size = AOP_SIZE(IC_RESULT(ic));
8930 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
8931 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8935 freeAsmop(left,NULL,ic,FALSE);
8936 freeAsmop(result,NULL,ic,TRUE);
8941 /*-----------------------------------------------------------------*/
8942 /* genFarFarAssign - assignment when both are in far space */
8943 /*-----------------------------------------------------------------*/
8944 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8946 int size = AOP_SIZE(right);
8949 /* first push the right side on to the stack */
8951 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8953 pic14_emitcode ("push","acc");
8956 freeAsmop(right,NULL,ic,FALSE);
8957 /* now assign DPTR to result */
8958 aopOp(result,ic,FALSE);
8959 size = AOP_SIZE(result);
8961 pic14_emitcode ("pop","acc");
8962 aopPut(AOP(result),"a",--offset);
8964 freeAsmop(result,NULL,ic,FALSE);
8969 /*-----------------------------------------------------------------*/
8970 /* genAssign - generate code for assignment */
8971 /*-----------------------------------------------------------------*/
8972 static void genAssign (iCode *ic)
8974 operand *result, *right;
8975 int size, offset,know_W;
8976 unsigned long lit = 0L;
8978 result = IC_RESULT(ic);
8979 right = IC_RIGHT(ic) ;
8981 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8983 /* if they are the same */
8984 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8987 aopOp(right,ic,FALSE);
8988 aopOp(result,ic,TRUE);
8990 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8992 /* if they are the same registers */
8993 if (pic14_sameRegs(AOP(right),AOP(result)))
8996 /* if the result is a bit */
8997 if (AOP_TYPE(result) == AOP_CRY) {
8999 /* if the right size is a literal then
9000 we know what the value is */
9001 if (AOP_TYPE(right) == AOP_LIT) {
9003 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9004 popGet(AOP(result),0));
9006 if (((int) operandLitValue(right)))
9007 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9008 AOP(result)->aopu.aop_dir,
9009 AOP(result)->aopu.aop_dir);
9011 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9012 AOP(result)->aopu.aop_dir,
9013 AOP(result)->aopu.aop_dir);
9017 /* the right is also a bit variable */
9018 if (AOP_TYPE(right) == AOP_CRY) {
9019 emitpcode(POC_BCF, popGet(AOP(result),0));
9020 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9021 emitpcode(POC_BSF, popGet(AOP(result),0));
9023 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9024 AOP(result)->aopu.aop_dir,
9025 AOP(result)->aopu.aop_dir);
9026 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9027 AOP(right)->aopu.aop_dir,
9028 AOP(right)->aopu.aop_dir);
9029 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9030 AOP(result)->aopu.aop_dir,
9031 AOP(result)->aopu.aop_dir);
9036 emitpcode(POC_BCF, popGet(AOP(result),0));
9037 pic14_toBoolean(right);
9039 emitpcode(POC_BSF, popGet(AOP(result),0));
9040 //aopPut(AOP(result),"a",0);
9044 /* bit variables done */
9046 size = AOP_SIZE(result);
9048 if(AOP_TYPE(right) == AOP_LIT)
9049 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9051 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9053 if(aopIdx(AOP(result),0) == 4) {
9054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9055 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9056 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9059 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9064 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9065 if(AOP_TYPE(right) == AOP_LIT) {
9067 if(know_W != (lit&0xff))
9068 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9070 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9072 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9076 } else if (AOP_TYPE(right) == AOP_CRY) {
9077 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9079 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9080 emitpcode(POC_INCF, popGet(AOP(result),0));
9083 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9084 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9085 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9093 freeAsmop (right,NULL,ic,FALSE);
9094 freeAsmop (result,NULL,ic,TRUE);
9097 /*-----------------------------------------------------------------*/
9098 /* genJumpTab - genrates code for jump table */
9099 /*-----------------------------------------------------------------*/
9100 static void genJumpTab (iCode *ic)
9105 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9107 aopOp(IC_JTCOND(ic),ic,FALSE);
9108 /* get the condition into accumulator */
9109 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9111 /* multiply by three */
9112 pic14_emitcode("add","a,acc");
9113 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9115 jtab = newiTempLabel(NULL);
9116 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9117 pic14_emitcode("jmp","@a+dptr");
9118 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9120 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9121 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9123 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9124 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9125 emitpLabel(jtab->key);
9127 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9129 /* now generate the jump labels */
9130 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9131 jtab = setNextItem(IC_JTLABELS(ic))) {
9132 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9133 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9139 /*-----------------------------------------------------------------*/
9140 /* genMixedOperation - gen code for operators between mixed types */
9141 /*-----------------------------------------------------------------*/
9143 TSD - Written for the PIC port - but this unfortunately is buggy.
9144 This routine is good in that it is able to efficiently promote
9145 types to different (larger) sizes. Unfortunately, the temporary
9146 variables that are optimized out by this routine are sometimes
9147 used in other places. So until I know how to really parse the
9148 iCode tree, I'm going to not be using this routine :(.
9150 static int genMixedOperation (iCode *ic)
9153 operand *result = IC_RESULT(ic);
9154 sym_link *ctype = operandType(IC_LEFT(ic));
9155 operand *right = IC_RIGHT(ic);
9161 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9163 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9169 nextright = IC_RIGHT(nextic);
9170 nextleft = IC_LEFT(nextic);
9171 nextresult = IC_RESULT(nextic);
9173 aopOp(right,ic,FALSE);
9174 aopOp(result,ic,FALSE);
9175 aopOp(nextright, nextic, FALSE);
9176 aopOp(nextleft, nextic, FALSE);
9177 aopOp(nextresult, nextic, FALSE);
9179 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9185 pic14_emitcode(";remove right +","");
9187 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9193 pic14_emitcode(";remove left +","");
9197 big = AOP_SIZE(nextleft);
9198 small = AOP_SIZE(nextright);
9200 switch(nextic->op) {
9203 pic14_emitcode(";optimize a +","");
9204 /* if unsigned or not an integral type */
9205 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9206 pic14_emitcode(";add a bit to something","");
9209 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9211 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9212 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9213 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9215 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9223 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9224 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9225 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9228 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9230 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9231 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9232 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9233 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9234 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9237 pic14_emitcode("rlf","known_zero,w");
9244 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9245 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9246 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9248 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9258 freeAsmop(right,NULL,ic,TRUE);
9259 freeAsmop(result,NULL,ic,TRUE);
9260 freeAsmop(nextright,NULL,ic,TRUE);
9261 freeAsmop(nextleft,NULL,ic,TRUE);
9263 nextic->generated = 1;
9270 /*-----------------------------------------------------------------*/
9271 /* genCast - gen code for casting */
9272 /*-----------------------------------------------------------------*/
9273 static void genCast (iCode *ic)
9275 operand *result = IC_RESULT(ic);
9276 sym_link *ctype = operandType(IC_LEFT(ic));
9277 sym_link *rtype = operandType(IC_RIGHT(ic));
9278 operand *right = IC_RIGHT(ic);
9281 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9282 /* if they are equivalent then do nothing */
9283 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9286 aopOp(right,ic,FALSE) ;
9287 aopOp(result,ic,FALSE);
9289 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9291 /* if the result is a bit */
9292 if (AOP_TYPE(result) == AOP_CRY) {
9293 /* if the right size is a literal then
9294 we know what the value is */
9295 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9296 if (AOP_TYPE(right) == AOP_LIT) {
9298 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9299 popGet(AOP(result),0));
9301 if (((int) operandLitValue(right)))
9302 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9303 AOP(result)->aopu.aop_dir,
9304 AOP(result)->aopu.aop_dir);
9306 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9307 AOP(result)->aopu.aop_dir,
9308 AOP(result)->aopu.aop_dir);
9313 /* the right is also a bit variable */
9314 if (AOP_TYPE(right) == AOP_CRY) {
9317 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9319 pic14_emitcode("clrc","");
9320 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9321 AOP(right)->aopu.aop_dir,
9322 AOP(right)->aopu.aop_dir);
9323 aopPut(AOP(result),"c",0);
9328 if (AOP_TYPE(right) == AOP_REG) {
9329 emitpcode(POC_BCF, popGet(AOP(result),0));
9330 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9331 emitpcode(POC_BSF, popGet(AOP(result),0));
9333 pic14_toBoolean(right);
9334 aopPut(AOP(result),"a",0);
9338 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9340 size = AOP_SIZE(result);
9342 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9344 emitpcode(POC_CLRF, popGet(AOP(result),0));
9345 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9346 emitpcode(POC_INCF, popGet(AOP(result),0));
9349 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9354 /* if they are the same size : or less */
9355 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9357 /* if they are in the same place */
9358 if (pic14_sameRegs(AOP(right),AOP(result)))
9361 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9362 if (IS_PTR_CONST(rtype))
9363 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9364 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9365 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9367 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9368 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9369 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9370 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9371 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9372 if(AOP_SIZE(result) <2)
9373 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9377 /* if they in different places then copy */
9378 size = AOP_SIZE(result);
9381 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9382 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9384 //aopPut(AOP(result),
9385 // aopGet(AOP(right),offset,FALSE,FALSE),
9395 /* if the result is of type pointer */
9396 if (IS_PTR(ctype)) {
9399 sym_link *type = operandType(right);
9400 sym_link *etype = getSpec(type);
9401 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9403 /* pointer to generic pointer */
9404 if (IS_GENPTR(ctype)) {
9408 p_type = DCL_TYPE(type);
9410 /* we have to go by the storage class */
9411 p_type = PTR_TYPE(SPEC_OCLS(etype));
9413 /* if (SPEC_OCLS(etype)->codesp ) */
9414 /* p_type = CPOINTER ; */
9416 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9417 /* p_type = FPOINTER ; */
9419 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9420 /* p_type = PPOINTER; */
9422 /* if (SPEC_OCLS(etype) == idata ) */
9423 /* p_type = IPOINTER ; */
9425 /* p_type = POINTER ; */
9428 /* the first two bytes are known */
9429 size = GPTRSIZE - 1;
9432 if(offset < AOP_SIZE(right))
9434 aopGet(AOP(right),offset,FALSE,FALSE),
9437 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9440 /* the last byte depending on type */
9444 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9447 pic14_emitcode(";BUG!? ","%d",__LINE__);
9451 pic14_emitcode(";BUG!? ","%d",__LINE__);
9455 pic14_emitcode(";BUG!? ","%d",__LINE__);
9460 /* this should never happen */
9461 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9462 "got unknown pointer type");
9465 //aopPut(AOP(result),l, GPTRSIZE - 1);
9469 /* just copy the pointers */
9470 size = AOP_SIZE(result);
9474 aopGet(AOP(right),offset,FALSE,FALSE),
9483 /* so we now know that the size of destination is greater
9484 than the size of the source.
9485 Now, if the next iCode is an operator then we might be
9486 able to optimize the operation without performing a cast.
9488 if(genMixedOperation(ic))
9491 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9493 /* we move to result for the size of source */
9494 size = AOP_SIZE(right);
9497 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9498 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9502 /* now depending on the sign of the destination */
9503 size = AOP_SIZE(result) - AOP_SIZE(right);
9504 /* if unsigned or not an integral type */
9505 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9507 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9509 /* we need to extend the sign :{ */
9512 /* Save one instruction of casting char to int */
9513 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9514 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9515 emitpcode(POC_DECF, popGet(AOP(result),offset));
9517 emitpcodeNULLop(POC_CLRW);
9520 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9522 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9524 emitpcode(POC_MOVLW, popGetLit(0xff));
9527 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9532 freeAsmop(right,NULL,ic,TRUE);
9533 freeAsmop(result,NULL,ic,TRUE);
9537 /*-----------------------------------------------------------------*/
9538 /* genDjnz - generate decrement & jump if not zero instrucion */
9539 /*-----------------------------------------------------------------*/
9540 static int genDjnz (iCode *ic, iCode *ifx)
9543 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9548 /* if the if condition has a false label
9549 then we cannot save */
9553 /* if the minus is not of the form
9555 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9556 !IS_OP_LITERAL(IC_RIGHT(ic)))
9559 if (operandLitValue(IC_RIGHT(ic)) != 1)
9562 /* if the size of this greater than one then no
9564 if (getSize(operandType(IC_RESULT(ic))) > 1)
9567 /* otherwise we can save BIG */
9568 lbl = newiTempLabel(NULL);
9569 lbl1= newiTempLabel(NULL);
9571 aopOp(IC_RESULT(ic),ic,FALSE);
9573 if (IS_AOP_PREG(IC_RESULT(ic))) {
9574 pic14_emitcode("dec","%s",
9575 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9576 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9577 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9581 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9582 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9584 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9585 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9588 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9589 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9590 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9591 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9594 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9599 /*-----------------------------------------------------------------*/
9600 /* genReceive - generate code for a receive iCode */
9601 /*-----------------------------------------------------------------*/
9602 static void genReceive (iCode *ic)
9604 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9606 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9607 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9608 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9610 int size = getSize(operandType(IC_RESULT(ic)));
9611 int offset = fReturnSizePic - size;
9613 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9614 fReturn[fReturnSizePic - offset - 1] : "acc"));
9617 aopOp(IC_RESULT(ic),ic,FALSE);
9618 size = AOP_SIZE(IC_RESULT(ic));
9621 pic14_emitcode ("pop","acc");
9622 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9627 aopOp(IC_RESULT(ic),ic,FALSE);
9629 assignResultValue(IC_RESULT(ic));
9632 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9635 /*-----------------------------------------------------------------*/
9636 /* genpic14Code - generate code for pic14 based controllers */
9637 /*-----------------------------------------------------------------*/
9639 * At this point, ralloc.c has gone through the iCode and attempted
9640 * to optimize in a way suitable for a PIC. Now we've got to generate
9641 * PIC instructions that correspond to the iCode.
9643 * Once the instructions are generated, we'll pass through both the
9644 * peep hole optimizer and the pCode optimizer.
9645 *-----------------------------------------------------------------*/
9647 void genpic14Code (iCode *lic)
9652 lineHead = lineCurr = NULL;
9654 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9657 /* if debug information required */
9658 if (options.debug && currFunc) {
9660 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9662 if (IS_STATIC(currFunc->etype)) {
9663 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9664 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9666 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9667 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9674 for (ic = lic ; ic ; ic = ic->next ) {
9676 DEBUGpic14_emitcode(";ic","");
9677 if ( cln != ic->lineno ) {
9678 if ( options.debug ) {
9680 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9681 FileBaseName(ic->filename),ic->lineno,
9682 ic->level,ic->block);
9685 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9686 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9687 printCLine(ic->filename, ic->lineno));
9691 /* if the result is marked as
9692 spilt and rematerializable or code for
9693 this has already been generated then
9695 if (resultRemat(ic) || ic->generated )
9698 /* depending on the operation */
9717 /* IPOP happens only when trying to restore a
9718 spilt live range, if there is an ifx statement
9719 following this pop then the if statement might
9720 be using some of the registers being popped which
9721 would destory the contents of the register so
9722 we need to check for this condition and handle it */
9724 ic->next->op == IFX &&
9725 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9726 genIfx (ic->next,ic);
9744 genEndFunction (ic);
9764 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9781 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9785 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9792 /* note these two are xlated by algebraic equivalence
9793 during parsing SDCC.y */
9794 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9795 "got '>=' or '<=' shouldn't have come here");
9799 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9811 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9815 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9819 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9846 case GET_VALUE_AT_ADDRESS:
9851 if (POINTER_SET(ic))
9878 addSet(&_G.sendSet,ic);
9887 /* now we are ready to call the
9888 peep hole optimizer */
9889 if (!options.nopeep) {
9890 peepHole (&lineHead);
9892 /* now do the actual printing */
9893 printLine (lineHead,codeOutFile);
9896 DFPRINTF((stderr,"printing pBlock\n\n"));
9897 printpBlock(stdout,pb);