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);
3715 symbol *lbl = newiTempLabel(NULL);
3717 if(AOP_TYPE(right) == AOP_LIT) {
3719 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3721 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3728 genSkipCond(&rFalseIfx,left,size-1,7);
3730 /* no need to compare to 0...*/
3731 /* NOTE: this is a de-generate compare that most certainly
3732 * creates some dead code. */
3733 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3735 if(ifx) ifx->generated = 1;
3742 //i = (lit >> (size*8)) & 0xff;
3743 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3745 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3747 i = ((0-lit) & 0xff);
3750 /* lit is 0x7f, all signed chars are less than
3751 * this except for 0x7f itself */
3752 emitpcode(POC_XORLW, popGetLit(0x7f));
3753 genSkipz2(&rFalseIfx);
3755 emitpcode(POC_ADDLW, popGetLit(0x80));
3756 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3757 genSkipc(&rFalseIfx);
3761 emitpcode(POC_ADDLW, popGetLit(i));
3762 genSkipc(&rFalseIfx);
3766 if(ifx) ifx->generated = 1;
3770 /* chars are out of the way. now do ints and longs */
3773 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3780 genSkipCond(&rFalseIfx,left,size,7);
3781 if(ifx) ifx->generated = 1;
3786 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3788 //rFalseIfx.condition ^= 1;
3789 //genSkipCond(&rFalseIfx,left,size,7);
3790 //rFalseIfx.condition ^= 1;
3792 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3793 if(rFalseIfx.condition)
3794 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3796 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3798 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3799 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3800 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3803 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3805 if(rFalseIfx.condition) {
3807 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3813 genSkipc(&rFalseIfx);
3814 emitpLabel(truelbl->key);
3815 if(ifx) ifx->generated = 1;
3822 if( (lit & 0xff) == 0) {
3823 /* lower byte is zero */
3824 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3825 i = ((lit >> 8) & 0xff) ^0x80;
3826 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3827 emitpcode(POC_ADDLW, popGetLit( 0x80));
3828 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3829 genSkipc(&rFalseIfx);
3832 if(ifx) ifx->generated = 1;
3837 /* Special cases for signed longs */
3838 if( (lit & 0xffffff) == 0) {
3839 /* lower byte is zero */
3840 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3841 i = ((lit >> 8*3) & 0xff) ^0x80;
3842 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3843 emitpcode(POC_ADDLW, popGetLit( 0x80));
3844 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3845 genSkipc(&rFalseIfx);
3848 if(ifx) ifx->generated = 1;
3856 if(lit & (0x80 << (size*8))) {
3857 /* lit is negative */
3858 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3860 //genSkipCond(&rFalseIfx,left,size,7);
3862 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3864 if(rFalseIfx.condition)
3865 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3867 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3871 /* lit is positive */
3872 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3873 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3874 if(rFalseIfx.condition)
3875 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3877 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3879 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3880 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3881 //rFalseIfx.condition ^= 1;
3882 //genSkipCond(&rFalseIfx,left,size,7);
3883 //rFalseIfx.condition ^= 1;
3887 This works, but is only good for ints.
3888 It also requires a "known zero" register.
3889 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3890 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3891 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3892 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3893 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3894 genSkipc(&rFalseIfx);
3896 emitpLabel(truelbl->key);
3897 if(ifx) ifx->generated = 1;
3901 /* There are no more special cases, so perform a general compare */
3903 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3904 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3908 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3910 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3912 //rFalseIfx.condition ^= 1;
3913 genSkipc(&rFalseIfx);
3915 emitpLabel(truelbl->key);
3917 if(ifx) ifx->generated = 1;
3924 /* sign is out of the way. So now do an unsigned compare */
3925 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3928 //genChkZeroes(left)
3930 /* General case - compare to an unsigned literal on the right.*/
3932 i = (lit >> (size*8)) & 0xff;
3933 emitpcode(POC_MOVLW, popGetLit(i));
3934 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3936 i = (lit >> (size*8)) & 0xff;
3939 emitpcode(POC_MOVLW, popGetLit(i));
3941 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3943 /* this byte of the lit is zero,
3944 *if it's not the last then OR in the variable */
3946 emitpcode(POC_IORFW, popGet(AOP(left),size));
3951 emitpLabel(lbl->key);
3952 //if(emitFinalCheck)
3953 genSkipc(&rFalseIfx);
3955 emitpLabel(truelbl->key);
3957 if(ifx) ifx->generated = 1;
3963 if(AOP_TYPE(left) == AOP_LIT) {
3964 //symbol *lbl = newiTempLabel(NULL);
3966 lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3969 DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign);
3972 if((lit == 0) && (sign == 0)){
3975 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3977 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3979 //rFalseIfx.condition ^= 1;
3980 genSkipz2(&rFalseIfx);
3981 if(ifx) ifx->generated = 1;
3988 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3989 /* degenerate compare can never be true */
3990 if(rFalseIfx.condition == 0)
3991 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3993 if(ifx) ifx->generated = 1;
3999 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4000 emitpcode(POC_ADDLW, popGetLit(0x80));
4001 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4002 rFalseIfx.condition ^= 1;
4003 genSkipc(&rFalseIfx);
4005 rFalseIfx.condition ^= 1;
4006 genSkipCond(&rFalseIfx,right,0,7);
4011 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4012 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4014 rFalseIfx.condition ^= 1;
4015 genSkipc(&rFalseIfx);
4017 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4018 genSkipz2(&rFalseIfx);
4022 if(ifx) ifx->generated = 1;
4027 /* Size is greater than 1 */
4037 /* this means lit = 0xffffffff, or -1 */
4040 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4041 rFalseIfx.condition ^= 1;
4042 genSkipCond(&rFalseIfx,right,size,7);
4043 if(ifx) ifx->generated = 1;
4050 if(rFalseIfx.condition) {
4051 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4052 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4055 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4057 emitpcode(POC_IORFW, popGet(AOP(right),size));
4061 if(rFalseIfx.condition) {
4062 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4063 emitpLabel(truelbl->key);
4065 rFalseIfx.condition ^= 1;
4066 genSkipCond(&rFalseIfx,right,s,7);
4069 if(ifx) ifx->generated = 1;
4074 if(lit & (0x80 << (size*8))) {
4075 /* Lit is less than zero */
4076 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4077 //rFalseIfx.condition ^= 1;
4078 //genSkipCond(&rFalseIfx,left,size,7);
4079 //rFalseIfx.condition ^= 1;
4080 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4081 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4083 if(rFalseIfx.condition)
4084 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4086 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4090 /* Lit is greater than or equal to zero */
4091 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4092 //rFalseIfx.condition ^= 1;
4093 //genSkipCond(&rFalseIfx,right,size,7);
4094 //rFalseIfx.condition ^= 1;
4096 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4097 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4099 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4100 if(rFalseIfx.condition)
4101 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4103 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4106 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4107 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4111 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4113 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4115 rFalseIfx.condition ^= 1;
4116 //rFalseIfx.condition = 1;
4117 genSkipc(&rFalseIfx);
4119 emitpLabel(truelbl->key);
4121 if(ifx) ifx->generated = 1;
4125 /* Unsigned compare for sizes greater than 1 */
4128 i = (lit >> (size*8)) & 0xff;
4132 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4133 emitpcode(POC_MOVLW, popGetLit(i&0xff));
4134 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4136 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4138 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4139 emitpcode(POC_MOVLW, popGetLit((i+1)&0xff));
4140 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4145 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4147 emitpLabel(lbl->key);
4149 rFalseIfx.condition ^= 1;
4150 genSkipc(&rFalseIfx);
4154 emitpLabel(truelbl->key);
4155 if(ifx) ifx->generated = 1;
4159 /* Compare two variables */
4161 DEBUGpic14_emitcode(";sign","%d",sign);
4165 /* Sigh. thus sucks... */
4167 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4168 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4169 emitpcode(POC_MOVLW, popGetLit(0x80));
4170 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4171 emitpcode(POC_XORFW, popGet(AOP(right),size));
4172 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4174 /* Signed char comparison */
4175 /* Special thanks to Nikolai Golovchenko for this snippet */
4176 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4177 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4178 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4179 emitpcode(POC_XORFW, popGet(AOP(left),0));
4180 emitpcode(POC_XORFW, popGet(AOP(right),0));
4181 emitpcode(POC_ADDLW, popGetLit(0x80));
4183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4184 genSkipc(&rFalseIfx);
4186 if(ifx) ifx->generated = 1;
4192 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4193 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4197 /* The rest of the bytes of a multi-byte compare */
4201 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4204 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4205 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4210 emitpLabel(lbl->key);
4212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4213 genSkipc(&rFalseIfx);
4214 if(ifx) ifx->generated = 1;
4221 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4222 pic14_outBitC(result);
4224 /* if the result is used in the next
4225 ifx conditional branch then generate
4226 code a little differently */
4228 genIfxJump (ifx,"c");
4230 pic14_outBitC(result);
4231 /* leave the result in acc */
4236 /*-----------------------------------------------------------------*/
4237 /* genCmpGt :- greater than comparison */
4238 /*-----------------------------------------------------------------*/
4239 static void genCmpGt (iCode *ic, iCode *ifx)
4241 operand *left, *right, *result;
4242 sym_link *letype , *retype;
4245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4247 right= IC_RIGHT(ic);
4248 result = IC_RESULT(ic);
4250 letype = getSpec(operandType(left));
4251 retype =getSpec(operandType(right));
4252 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4253 /* assign the amsops */
4254 aopOp (left,ic,FALSE);
4255 aopOp (right,ic,FALSE);
4256 aopOp (result,ic,TRUE);
4258 genCmp(right, left, result, ifx, sign);
4260 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4261 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4262 freeAsmop(result,NULL,ic,TRUE);
4265 /*-----------------------------------------------------------------*/
4266 /* genCmpLt - less than comparisons */
4267 /*-----------------------------------------------------------------*/
4268 static void genCmpLt (iCode *ic, iCode *ifx)
4270 operand *left, *right, *result;
4271 sym_link *letype , *retype;
4274 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4276 right= IC_RIGHT(ic);
4277 result = IC_RESULT(ic);
4279 letype = getSpec(operandType(left));
4280 retype =getSpec(operandType(right));
4281 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4283 /* assign the amsops */
4284 aopOp (left,ic,FALSE);
4285 aopOp (right,ic,FALSE);
4286 aopOp (result,ic,TRUE);
4288 genCmp(left, right, result, ifx, sign);
4290 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4291 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4292 freeAsmop(result,NULL,ic,TRUE);
4295 /*-----------------------------------------------------------------*/
4296 /* genc16bit2lit - compare a 16 bit value to a literal */
4297 /*-----------------------------------------------------------------*/
4298 static void genc16bit2lit(operand *op, int lit, int offset)
4302 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4303 if( (lit&0xff) == 0)
4308 switch( BYTEofLONG(lit,i)) {
4310 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4313 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4316 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4319 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4320 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4325 switch( BYTEofLONG(lit,i)) {
4327 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4331 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4335 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4338 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4340 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4346 /*-----------------------------------------------------------------*/
4347 /* gencjneshort - compare and jump if not equal */
4348 /*-----------------------------------------------------------------*/
4349 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4351 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4356 unsigned long lit = 0L;
4357 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4358 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4360 resolveIfx(&rIfx,ifx);
4361 lbl = newiTempLabel(NULL);
4364 /* if the left side is a literal or
4365 if the right is in a pointer register and left
4367 if ((AOP_TYPE(left) == AOP_LIT) ||
4368 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4373 if(AOP_TYPE(right) == AOP_LIT)
4374 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4376 /* if the right side is a literal then anything goes */
4377 if (AOP_TYPE(right) == AOP_LIT &&
4378 AOP_TYPE(left) != AOP_DIR ) {
4381 genc16bit2lit(left, lit, 0);
4383 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4388 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4389 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4391 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4395 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4403 /* if the right side is in a register or in direct space or
4404 if the left is a pointer register & right is not */
4405 else if (AOP_TYPE(right) == AOP_REG ||
4406 AOP_TYPE(right) == AOP_DIR ||
4407 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4408 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4411 genc16bit2lit(left, lit, 0);
4413 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4418 if((AOP_TYPE(left) == AOP_DIR) &&
4419 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4421 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4422 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4424 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4426 switch (lit & 0xff) {
4428 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4431 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4432 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4436 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4437 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4441 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4442 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4447 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4450 if(AOP_TYPE(result) == AOP_CRY) {
4451 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4456 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4458 /* fix me. probably need to check result size too */
4459 emitpcode(POC_CLRF,popGet(AOP(result),0));
4464 emitpcode(POC_INCF,popGet(AOP(result),0));
4474 } else if(AOP_TYPE(right) == AOP_REG &&
4475 AOP_TYPE(left) != AOP_DIR){
4478 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4479 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4480 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4485 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4490 /* right is a pointer reg need both a & b */
4492 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4494 pic14_emitcode("mov","b,%s",l);
4495 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4496 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4500 emitpLabel(lbl->key);
4507 /*-----------------------------------------------------------------*/
4508 /* gencjne - compare and jump if not equal */
4509 /*-----------------------------------------------------------------*/
4510 static void gencjne(operand *left, operand *right, iCode *ifx)
4512 symbol *tlbl = newiTempLabel(NULL);
4514 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4515 gencjneshort(left, right, lbl);
4517 pic14_emitcode("mov","a,%s",one);
4518 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4519 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4520 pic14_emitcode("clr","a");
4521 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4523 emitpLabel(lbl->key);
4524 emitpLabel(tlbl->key);
4529 /*-----------------------------------------------------------------*/
4530 /* genCmpEq - generates code for equal to */
4531 /*-----------------------------------------------------------------*/
4532 static void genCmpEq (iCode *ic, iCode *ifx)
4534 operand *left, *right, *result;
4535 unsigned long lit = 0L;
4538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4541 DEBUGpic14_emitcode ("; ifx is non-null","");
4543 DEBUGpic14_emitcode ("; ifx is null","");
4545 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4546 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4547 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4549 size = max(AOP_SIZE(left),AOP_SIZE(right));
4551 DEBUGpic14_AopType(__LINE__,left,right,result);
4553 /* if literal, literal on the right or
4554 if the right is in a pointer register and left
4556 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4557 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4558 operand *tmp = right ;
4564 if(ifx && !AOP_SIZE(result)){
4566 /* if they are both bit variables */
4567 if (AOP_TYPE(left) == AOP_CRY &&
4568 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4569 if(AOP_TYPE(right) == AOP_LIT){
4570 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4572 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4573 pic14_emitcode("cpl","c");
4574 } else if(lit == 1L) {
4575 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4577 pic14_emitcode("clr","c");
4579 /* AOP_TYPE(right) == AOP_CRY */
4581 symbol *lbl = newiTempLabel(NULL);
4582 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4583 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4584 pic14_emitcode("cpl","c");
4585 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4587 /* if true label then we jump if condition
4589 tlbl = newiTempLabel(NULL);
4590 if ( IC_TRUE(ifx) ) {
4591 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4592 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4594 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4595 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4597 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4600 /* left and right are both bit variables, result is carry */
4603 resolveIfx(&rIfx,ifx);
4605 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4606 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4607 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4608 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4613 /* They're not both bit variables. Is the right a literal? */
4614 if(AOP_TYPE(right) == AOP_LIT) {
4615 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4620 switch(lit & 0xff) {
4622 if ( IC_TRUE(ifx) ) {
4623 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4625 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4627 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4628 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4632 if ( IC_TRUE(ifx) ) {
4633 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4635 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4637 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4638 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4642 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4644 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4649 /* end of size == 1 */
4653 genc16bit2lit(left,lit,offset);
4656 /* end of size == 2 */
4661 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4662 emitpcode(POC_IORFW,popGet(AOP(left),1));
4663 emitpcode(POC_IORFW,popGet(AOP(left),2));
4664 emitpcode(POC_IORFW,popGet(AOP(left),3));
4668 /* search for patterns that can be optimized */
4670 genc16bit2lit(left,lit,0);
4673 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4675 genc16bit2lit(left,lit,2);
4677 emitpcode(POC_IORFW,popGet(AOP(left),2));
4678 emitpcode(POC_IORFW,popGet(AOP(left),3));
4691 } else if(AOP_TYPE(right) == AOP_CRY ) {
4692 /* we know the left is not a bit, but that the right is */
4693 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4694 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4695 popGet(AOP(right),offset));
4696 emitpcode(POC_XORLW,popGetLit(1));
4698 /* if the two are equal, then W will be 0 and the Z bit is set
4699 * we could test Z now, or go ahead and check the high order bytes if
4700 * the variable we're comparing is larger than a byte. */
4703 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4705 if ( IC_TRUE(ifx) ) {
4707 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4708 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4711 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4712 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4716 /* They're both variables that are larger than bits */
4719 tlbl = newiTempLabel(NULL);
4722 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4723 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4725 if ( IC_TRUE(ifx) ) {
4728 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4729 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4732 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4733 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4737 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4738 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4742 if(s>1 && IC_TRUE(ifx)) {
4743 emitpLabel(tlbl->key);
4744 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4748 /* mark the icode as generated */
4753 /* if they are both bit variables */
4754 if (AOP_TYPE(left) == AOP_CRY &&
4755 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4756 if(AOP_TYPE(right) == AOP_LIT){
4757 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4759 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4760 pic14_emitcode("cpl","c");
4761 } else if(lit == 1L) {
4762 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4764 pic14_emitcode("clr","c");
4766 /* AOP_TYPE(right) == AOP_CRY */
4768 symbol *lbl = newiTempLabel(NULL);
4769 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4770 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4771 pic14_emitcode("cpl","c");
4772 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4775 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4776 pic14_outBitC(result);
4780 genIfxJump (ifx,"c");
4783 /* if the result is used in an arithmetic operation
4784 then put the result in place */
4785 pic14_outBitC(result);
4788 gencjne(left,right,result,ifx);
4791 gencjne(left,right,newiTempLabel(NULL));
4793 if(IC_TRUE(ifx)->key)
4794 gencjne(left,right,IC_TRUE(ifx)->key);
4796 gencjne(left,right,IC_FALSE(ifx)->key);
4800 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4801 aopPut(AOP(result),"a",0);
4806 genIfxJump (ifx,"a");
4810 /* if the result is used in an arithmetic operation
4811 then put the result in place */
4813 if (AOP_TYPE(result) != AOP_CRY)
4814 pic14_outAcc(result);
4816 /* leave the result in acc */
4820 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4821 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4822 freeAsmop(result,NULL,ic,TRUE);
4825 /*-----------------------------------------------------------------*/
4826 /* ifxForOp - returns the icode containing the ifx for operand */
4827 /*-----------------------------------------------------------------*/
4828 static iCode *ifxForOp ( operand *op, iCode *ic )
4830 /* if true symbol then needs to be assigned */
4831 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4832 if (IS_TRUE_SYMOP(op))
4835 /* if this has register type condition and
4836 the next instruction is ifx with the same operand
4837 and live to of the operand is upto the ifx only then */
4839 ic->next->op == IFX &&
4840 IC_COND(ic->next)->key == op->key &&
4841 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4845 ic->next->op == IFX &&
4846 IC_COND(ic->next)->key == op->key) {
4847 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4851 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4853 ic->next->op == IFX)
4854 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4857 ic->next->op == IFX &&
4858 IC_COND(ic->next)->key == op->key) {
4859 DEBUGpic14_emitcode ("; "," key is okay");
4860 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4861 OP_SYMBOL(op)->liveTo,
4868 /*-----------------------------------------------------------------*/
4869 /* genAndOp - for && operation */
4870 /*-----------------------------------------------------------------*/
4871 static void genAndOp (iCode *ic)
4873 operand *left,*right, *result;
4876 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4877 /* note here that && operations that are in an
4878 if statement are taken away by backPatchLabels
4879 only those used in arthmetic operations remain */
4880 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4881 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4882 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4884 /* if both are bit variables */
4885 if (AOP_TYPE(left) == AOP_CRY &&
4886 AOP_TYPE(right) == AOP_CRY ) {
4887 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4888 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4889 pic14_outBitC(result);
4891 tlbl = newiTempLabel(NULL);
4892 pic14_toBoolean(left);
4893 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4894 pic14_toBoolean(right);
4895 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4896 pic14_outBitAcc(result);
4899 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4900 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4901 freeAsmop(result,NULL,ic,TRUE);
4905 /*-----------------------------------------------------------------*/
4906 /* genOrOp - for || operation */
4907 /*-----------------------------------------------------------------*/
4910 modified this code, but it doesn't appear to ever get called
4913 static void genOrOp (iCode *ic)
4915 operand *left,*right, *result;
4918 /* note here that || operations that are in an
4919 if statement are taken away by backPatchLabels
4920 only those used in arthmetic operations remain */
4921 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4922 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4923 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4924 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4926 DEBUGpic14_AopType(__LINE__,left,right,result);
4928 /* if both are bit variables */
4929 if (AOP_TYPE(left) == AOP_CRY &&
4930 AOP_TYPE(right) == AOP_CRY ) {
4931 pic14_emitcode("clrc","");
4932 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
4933 AOP(left)->aopu.aop_dir,
4934 AOP(left)->aopu.aop_dir);
4935 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
4936 AOP(right)->aopu.aop_dir,
4937 AOP(right)->aopu.aop_dir);
4938 pic14_emitcode("setc","");
4941 tlbl = newiTempLabel(NULL);
4942 pic14_toBoolean(left);
4944 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
4945 pic14_toBoolean(right);
4946 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4948 pic14_outBitAcc(result);
4951 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4952 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4953 freeAsmop(result,NULL,ic,TRUE);
4956 /*-----------------------------------------------------------------*/
4957 /* isLiteralBit - test if lit == 2^n */
4958 /*-----------------------------------------------------------------*/
4959 static int isLiteralBit(unsigned long lit)
4961 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
4962 0x100L,0x200L,0x400L,0x800L,
4963 0x1000L,0x2000L,0x4000L,0x8000L,
4964 0x10000L,0x20000L,0x40000L,0x80000L,
4965 0x100000L,0x200000L,0x400000L,0x800000L,
4966 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
4967 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
4970 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4971 for(idx = 0; idx < 32; idx++)
4977 /*-----------------------------------------------------------------*/
4978 /* continueIfTrue - */
4979 /*-----------------------------------------------------------------*/
4980 static void continueIfTrue (iCode *ic)
4982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4984 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
4988 /*-----------------------------------------------------------------*/
4990 /*-----------------------------------------------------------------*/
4991 static void jumpIfTrue (iCode *ic)
4993 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4995 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
4999 /*-----------------------------------------------------------------*/
5000 /* jmpTrueOrFalse - */
5001 /*-----------------------------------------------------------------*/
5002 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5004 // ugly but optimized by peephole
5005 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5007 symbol *nlbl = newiTempLabel(NULL);
5008 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5009 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5010 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5011 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5014 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5015 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5020 /*-----------------------------------------------------------------*/
5021 /* genAnd - code for and */
5022 /*-----------------------------------------------------------------*/
5023 static void genAnd (iCode *ic, iCode *ifx)
5025 operand *left, *right, *result;
5027 unsigned long lit = 0L;
5032 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5033 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5034 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5035 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5037 resolveIfx(&rIfx,ifx);
5039 /* if left is a literal & right is not then exchange them */
5040 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5041 AOP_NEEDSACC(left)) {
5042 operand *tmp = right ;
5047 /* if result = right then exchange them */
5048 if(pic14_sameRegs(AOP(result),AOP(right))){
5049 operand *tmp = right ;
5054 /* if right is bit then exchange them */
5055 if (AOP_TYPE(right) == AOP_CRY &&
5056 AOP_TYPE(left) != AOP_CRY){
5057 operand *tmp = right ;
5061 if(AOP_TYPE(right) == AOP_LIT)
5062 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5064 size = AOP_SIZE(result);
5066 DEBUGpic14_AopType(__LINE__,left,right,result);
5069 // result = bit & yy;
5070 if (AOP_TYPE(left) == AOP_CRY){
5071 // c = bit & literal;
5072 if(AOP_TYPE(right) == AOP_LIT){
5074 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5077 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5080 if(size && (AOP_TYPE(result) == AOP_CRY)){
5081 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5084 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5088 pic14_emitcode("clr","c");
5091 if (AOP_TYPE(right) == AOP_CRY){
5093 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5094 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5097 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5099 pic14_emitcode("rrc","a");
5100 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5106 pic14_outBitC(result);
5108 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5109 genIfxJump(ifx, "c");
5113 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5114 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5115 if((AOP_TYPE(right) == AOP_LIT) &&
5116 (AOP_TYPE(result) == AOP_CRY) &&
5117 (AOP_TYPE(left) != AOP_CRY)){
5118 int posbit = isLiteralBit(lit);
5122 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5125 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5131 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5132 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5134 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5135 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5138 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5139 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5140 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5147 symbol *tlbl = newiTempLabel(NULL);
5148 int sizel = AOP_SIZE(left);
5150 pic14_emitcode("setb","c");
5152 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5153 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5155 if((posbit = isLiteralBit(bytelit)) != 0)
5156 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5158 if(bytelit != 0x0FFL)
5159 pic14_emitcode("anl","a,%s",
5160 aopGet(AOP(right),offset,FALSE,TRUE));
5161 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5166 // bit = left & literal
5168 pic14_emitcode("clr","c");
5169 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5171 // if(left & literal)
5174 jmpTrueOrFalse(ifx, tlbl);
5178 pic14_outBitC(result);
5182 /* if left is same as result */
5183 if(pic14_sameRegs(AOP(result),AOP(left))){
5185 for(;size--; offset++,lit>>=8) {
5186 if(AOP_TYPE(right) == AOP_LIT){
5187 switch(lit & 0xff) {
5189 /* and'ing with 0 has clears the result */
5190 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5191 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5194 /* and'ing with 0xff is a nop when the result and left are the same */
5199 int p = my_powof2( (~lit) & 0xff );
5201 /* only one bit is set in the literal, so use a bcf instruction */
5202 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5203 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5206 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5207 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5208 if(know_W != (lit&0xff))
5209 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5211 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5216 if (AOP_TYPE(left) == AOP_ACC) {
5217 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5219 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5220 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5227 // left & result in different registers
5228 if(AOP_TYPE(result) == AOP_CRY){
5230 // if(size), result in bit
5231 // if(!size && ifx), conditional oper: if(left & right)
5232 symbol *tlbl = newiTempLabel(NULL);
5233 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5235 pic14_emitcode("setb","c");
5237 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5238 pic14_emitcode("anl","a,%s",
5239 aopGet(AOP(left),offset,FALSE,FALSE));
5240 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5245 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5246 pic14_outBitC(result);
5248 jmpTrueOrFalse(ifx, tlbl);
5250 for(;(size--);offset++) {
5252 // result = left & right
5253 if(AOP_TYPE(right) == AOP_LIT){
5254 int t = (lit >> (offset*8)) & 0x0FFL;
5257 pic14_emitcode("clrf","%s",
5258 aopGet(AOP(result),offset,FALSE,FALSE));
5259 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5262 pic14_emitcode("movf","%s,w",
5263 aopGet(AOP(left),offset,FALSE,FALSE));
5264 pic14_emitcode("movwf","%s",
5265 aopGet(AOP(result),offset,FALSE,FALSE));
5266 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5267 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5270 pic14_emitcode("movlw","0x%x",t);
5271 pic14_emitcode("andwf","%s,w",
5272 aopGet(AOP(left),offset,FALSE,FALSE));
5273 pic14_emitcode("movwf","%s",
5274 aopGet(AOP(result),offset,FALSE,FALSE));
5276 emitpcode(POC_MOVLW, popGetLit(t));
5277 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5278 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5283 if (AOP_TYPE(left) == AOP_ACC) {
5284 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5285 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5287 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5288 pic14_emitcode("andwf","%s,w",
5289 aopGet(AOP(left),offset,FALSE,FALSE));
5290 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5291 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5293 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5294 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5300 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5301 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5302 freeAsmop(result,NULL,ic,TRUE);
5305 /*-----------------------------------------------------------------*/
5306 /* genOr - code for or */
5307 /*-----------------------------------------------------------------*/
5308 static void genOr (iCode *ic, iCode *ifx)
5310 operand *left, *right, *result;
5312 unsigned long lit = 0L;
5314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5316 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5317 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5318 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5320 DEBUGpic14_AopType(__LINE__,left,right,result);
5322 /* if left is a literal & right is not then exchange them */
5323 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5324 AOP_NEEDSACC(left)) {
5325 operand *tmp = right ;
5330 /* if result = right then exchange them */
5331 if(pic14_sameRegs(AOP(result),AOP(right))){
5332 operand *tmp = right ;
5337 /* if right is bit then exchange them */
5338 if (AOP_TYPE(right) == AOP_CRY &&
5339 AOP_TYPE(left) != AOP_CRY){
5340 operand *tmp = right ;
5345 DEBUGpic14_AopType(__LINE__,left,right,result);
5347 if(AOP_TYPE(right) == AOP_LIT)
5348 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5350 size = AOP_SIZE(result);
5354 if (AOP_TYPE(left) == AOP_CRY){
5355 if(AOP_TYPE(right) == AOP_LIT){
5356 // c = bit & literal;
5358 // lit != 0 => result = 1
5359 if(AOP_TYPE(result) == AOP_CRY){
5361 emitpcode(POC_BSF, popGet(AOP(result),0));
5362 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5363 // AOP(result)->aopu.aop_dir,
5364 // AOP(result)->aopu.aop_dir);
5366 continueIfTrue(ifx);
5370 // lit == 0 => result = left
5371 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5373 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5376 if (AOP_TYPE(right) == AOP_CRY){
5377 if(pic14_sameRegs(AOP(result),AOP(left))){
5379 emitpcode(POC_BCF, popGet(AOP(result),0));
5380 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5381 emitpcode(POC_BSF, popGet(AOP(result),0));
5383 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5384 AOP(result)->aopu.aop_dir,
5385 AOP(result)->aopu.aop_dir);
5386 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5387 AOP(right)->aopu.aop_dir,
5388 AOP(right)->aopu.aop_dir);
5389 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5390 AOP(result)->aopu.aop_dir,
5391 AOP(result)->aopu.aop_dir);
5393 if( AOP_TYPE(result) == AOP_ACC) {
5394 emitpcode(POC_MOVLW, popGetLit(0));
5395 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5396 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5397 emitpcode(POC_MOVLW, popGetLit(1));
5401 emitpcode(POC_BCF, popGet(AOP(result),0));
5402 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5403 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5404 emitpcode(POC_BSF, popGet(AOP(result),0));
5406 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5407 AOP(result)->aopu.aop_dir,
5408 AOP(result)->aopu.aop_dir);
5409 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5410 AOP(right)->aopu.aop_dir,
5411 AOP(right)->aopu.aop_dir);
5412 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5413 AOP(left)->aopu.aop_dir,
5414 AOP(left)->aopu.aop_dir);
5415 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5416 AOP(result)->aopu.aop_dir,
5417 AOP(result)->aopu.aop_dir);
5422 symbol *tlbl = newiTempLabel(NULL);
5423 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5426 emitpcode(POC_BCF, popGet(AOP(result),0));
5427 if( AOP_TYPE(right) == AOP_ACC) {
5428 emitpcode(POC_IORLW, popGetLit(0));
5430 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5431 emitpcode(POC_BSF, popGet(AOP(result),0));
5436 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5437 pic14_emitcode(";XXX setb","c");
5438 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5439 AOP(left)->aopu.aop_dir,tlbl->key+100);
5440 pic14_toBoolean(right);
5441 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5442 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5443 jmpTrueOrFalse(ifx, tlbl);
5447 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5454 pic14_outBitC(result);
5456 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5457 genIfxJump(ifx, "c");
5461 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5462 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5463 if((AOP_TYPE(right) == AOP_LIT) &&
5464 (AOP_TYPE(result) == AOP_CRY) &&
5465 (AOP_TYPE(left) != AOP_CRY)){
5467 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5470 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5472 continueIfTrue(ifx);
5475 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5476 // lit = 0, result = boolean(left)
5478 pic14_emitcode(";XXX setb","c");
5479 pic14_toBoolean(right);
5481 symbol *tlbl = newiTempLabel(NULL);
5482 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5484 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5486 genIfxJump (ifx,"a");
5490 pic14_outBitC(result);
5494 /* if left is same as result */
5495 if(pic14_sameRegs(AOP(result),AOP(left))){
5497 for(;size--; offset++,lit>>=8) {
5498 if(AOP_TYPE(right) == AOP_LIT){
5499 if((lit & 0xff) == 0)
5500 /* or'ing with 0 has no effect */
5503 int p = my_powof2(lit & 0xff);
5505 /* only one bit is set in the literal, so use a bsf instruction */
5507 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5509 if(know_W != (lit & 0xff))
5510 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5511 know_W = lit & 0xff;
5512 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5517 if (AOP_TYPE(left) == AOP_ACC) {
5518 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5519 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5521 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5522 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5524 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5525 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5531 // left & result in different registers
5532 if(AOP_TYPE(result) == AOP_CRY){
5534 // if(size), result in bit
5535 // if(!size && ifx), conditional oper: if(left | right)
5536 symbol *tlbl = newiTempLabel(NULL);
5537 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5538 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5542 pic14_emitcode(";XXX setb","c");
5544 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5545 pic14_emitcode(";XXX orl","a,%s",
5546 aopGet(AOP(left),offset,FALSE,FALSE));
5547 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5552 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5553 pic14_outBitC(result);
5555 jmpTrueOrFalse(ifx, tlbl);
5556 } else for(;(size--);offset++){
5558 // result = left & right
5559 if(AOP_TYPE(right) == AOP_LIT){
5560 int t = (lit >> (offset*8)) & 0x0FFL;
5563 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5564 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5566 pic14_emitcode("movf","%s,w",
5567 aopGet(AOP(left),offset,FALSE,FALSE));
5568 pic14_emitcode("movwf","%s",
5569 aopGet(AOP(result),offset,FALSE,FALSE));
5572 emitpcode(POC_MOVLW, popGetLit(t));
5573 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5574 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5576 pic14_emitcode("movlw","0x%x",t);
5577 pic14_emitcode("iorwf","%s,w",
5578 aopGet(AOP(left),offset,FALSE,FALSE));
5579 pic14_emitcode("movwf","%s",
5580 aopGet(AOP(result),offset,FALSE,FALSE));
5586 // faster than result <- left, anl result,right
5587 // and better if result is SFR
5588 if (AOP_TYPE(left) == AOP_ACC) {
5589 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5590 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5592 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5593 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5595 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5596 pic14_emitcode("iorwf","%s,w",
5597 aopGet(AOP(left),offset,FALSE,FALSE));
5599 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5600 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5605 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5606 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5607 freeAsmop(result,NULL,ic,TRUE);
5610 /*-----------------------------------------------------------------*/
5611 /* genXor - code for xclusive or */
5612 /*-----------------------------------------------------------------*/
5613 static void genXor (iCode *ic, iCode *ifx)
5615 operand *left, *right, *result;
5617 unsigned long lit = 0L;
5619 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5621 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5622 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5623 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5625 /* if left is a literal & right is not ||
5626 if left needs acc & right does not */
5627 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5628 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5629 operand *tmp = right ;
5634 /* if result = right then exchange them */
5635 if(pic14_sameRegs(AOP(result),AOP(right))){
5636 operand *tmp = right ;
5641 /* if right is bit then exchange them */
5642 if (AOP_TYPE(right) == AOP_CRY &&
5643 AOP_TYPE(left) != AOP_CRY){
5644 operand *tmp = right ;
5648 if(AOP_TYPE(right) == AOP_LIT)
5649 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5651 size = AOP_SIZE(result);
5655 if (AOP_TYPE(left) == AOP_CRY){
5656 if(AOP_TYPE(right) == AOP_LIT){
5657 // c = bit & literal;
5659 // lit>>1 != 0 => result = 1
5660 if(AOP_TYPE(result) == AOP_CRY){
5662 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5663 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5665 continueIfTrue(ifx);
5668 pic14_emitcode("setb","c");
5672 // lit == 0, result = left
5673 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5675 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5677 // lit == 1, result = not(left)
5678 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5679 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5680 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5681 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5684 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5685 pic14_emitcode("cpl","c");
5692 symbol *tlbl = newiTempLabel(NULL);
5693 if (AOP_TYPE(right) == AOP_CRY){
5695 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5698 int sizer = AOP_SIZE(right);
5700 // if val>>1 != 0, result = 1
5701 pic14_emitcode("setb","c");
5703 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5705 // test the msb of the lsb
5706 pic14_emitcode("anl","a,#0xfe");
5707 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5711 pic14_emitcode("rrc","a");
5713 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5714 pic14_emitcode("cpl","c");
5715 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5720 pic14_outBitC(result);
5722 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5723 genIfxJump(ifx, "c");
5727 if(pic14_sameRegs(AOP(result),AOP(left))){
5728 /* if left is same as result */
5729 for(;size--; offset++) {
5730 if(AOP_TYPE(right) == AOP_LIT){
5731 int t = (lit >> (offset*8)) & 0x0FFL;
5735 if (IS_AOP_PREG(left)) {
5736 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5737 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5738 aopPut(AOP(result),"a",offset);
5740 emitpcode(POC_MOVLW, popGetLit(t));
5741 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5742 pic14_emitcode("xrl","%s,%s",
5743 aopGet(AOP(left),offset,FALSE,TRUE),
5744 aopGet(AOP(right),offset,FALSE,FALSE));
5747 if (AOP_TYPE(left) == AOP_ACC)
5748 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5750 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5751 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5753 if (IS_AOP_PREG(left)) {
5754 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5755 aopPut(AOP(result),"a",offset);
5757 pic14_emitcode("xrl","%s,a",
5758 aopGet(AOP(left),offset,FALSE,TRUE));
5764 // left & result in different registers
5765 if(AOP_TYPE(result) == AOP_CRY){
5767 // if(size), result in bit
5768 // if(!size && ifx), conditional oper: if(left ^ right)
5769 symbol *tlbl = newiTempLabel(NULL);
5770 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5772 pic14_emitcode("setb","c");
5774 if((AOP_TYPE(right) == AOP_LIT) &&
5775 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5776 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5778 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5779 pic14_emitcode("xrl","a,%s",
5780 aopGet(AOP(left),offset,FALSE,FALSE));
5782 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5787 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5788 pic14_outBitC(result);
5790 jmpTrueOrFalse(ifx, tlbl);
5791 } else for(;(size--);offset++){
5793 // result = left & right
5794 if(AOP_TYPE(right) == AOP_LIT){
5795 int t = (lit >> (offset*8)) & 0x0FFL;
5798 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5799 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5800 pic14_emitcode("movf","%s,w",
5801 aopGet(AOP(left),offset,FALSE,FALSE));
5802 pic14_emitcode("movwf","%s",
5803 aopGet(AOP(result),offset,FALSE,FALSE));
5806 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5807 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5808 pic14_emitcode("comf","%s,w",
5809 aopGet(AOP(left),offset,FALSE,FALSE));
5810 pic14_emitcode("movwf","%s",
5811 aopGet(AOP(result),offset,FALSE,FALSE));
5814 emitpcode(POC_MOVLW, popGetLit(t));
5815 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5816 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5817 pic14_emitcode("movlw","0x%x",t);
5818 pic14_emitcode("xorwf","%s,w",
5819 aopGet(AOP(left),offset,FALSE,FALSE));
5820 pic14_emitcode("movwf","%s",
5821 aopGet(AOP(result),offset,FALSE,FALSE));
5827 // faster than result <- left, anl result,right
5828 // and better if result is SFR
5829 if (AOP_TYPE(left) == AOP_ACC) {
5830 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5831 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5833 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5834 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5835 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5836 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5838 if ( AOP_TYPE(result) != AOP_ACC){
5839 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5840 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5846 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5847 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5848 freeAsmop(result,NULL,ic,TRUE);
5851 /*-----------------------------------------------------------------*/
5852 /* genInline - write the inline code out */
5853 /*-----------------------------------------------------------------*/
5854 static void genInline (iCode *ic)
5856 char *buffer, *bp, *bp1;
5858 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5860 _G.inLine += (!options.asmpeep);
5862 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5863 strcpy(buffer,IC_INLINE(ic));
5865 /* emit each line as a code */
5869 pic14_emitcode(bp1,"");
5876 pic14_emitcode(bp1,"");
5883 pic14_emitcode(bp1,"");
5884 /* pic14_emitcode("",buffer); */
5885 _G.inLine -= (!options.asmpeep);
5888 /*-----------------------------------------------------------------*/
5889 /* genRRC - rotate right with carry */
5890 /*-----------------------------------------------------------------*/
5891 static void genRRC (iCode *ic)
5893 operand *left , *result ;
5894 int size, offset = 0, same;
5896 /* rotate right with carry */
5898 result=IC_RESULT(ic);
5899 aopOp (left,ic,FALSE);
5900 aopOp (result,ic,FALSE);
5902 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5904 same = pic14_sameRegs(AOP(result),AOP(left));
5906 size = AOP_SIZE(result);
5908 /* get the lsb and put it into the carry */
5909 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
5916 emitpcode(POC_RRF, popGet(AOP(left),offset));
5918 emitpcode(POC_RRFW, popGet(AOP(left),offset));
5919 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5925 freeAsmop(left,NULL,ic,TRUE);
5926 freeAsmop(result,NULL,ic,TRUE);
5929 /*-----------------------------------------------------------------*/
5930 /* genRLC - generate code for rotate left with carry */
5931 /*-----------------------------------------------------------------*/
5932 static void genRLC (iCode *ic)
5934 operand *left , *result ;
5935 int size, offset = 0;
5938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5939 /* rotate right with carry */
5941 result=IC_RESULT(ic);
5942 aopOp (left,ic,FALSE);
5943 aopOp (result,ic,FALSE);
5945 DEBUGpic14_AopType(__LINE__,left,NULL,result);
5947 same = pic14_sameRegs(AOP(result),AOP(left));
5949 /* move it to the result */
5950 size = AOP_SIZE(result);
5952 /* get the msb and put it into the carry */
5953 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
5960 emitpcode(POC_RLF, popGet(AOP(left),offset));
5962 emitpcode(POC_RLFW, popGet(AOP(left),offset));
5963 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5970 freeAsmop(left,NULL,ic,TRUE);
5971 freeAsmop(result,NULL,ic,TRUE);
5974 /*-----------------------------------------------------------------*/
5975 /* genGetHbit - generates code get highest order bit */
5976 /*-----------------------------------------------------------------*/
5977 static void genGetHbit (iCode *ic)
5979 operand *left, *result;
5981 result=IC_RESULT(ic);
5982 aopOp (left,ic,FALSE);
5983 aopOp (result,ic,FALSE);
5985 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5986 /* get the highest order byte into a */
5987 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
5988 if(AOP_TYPE(result) == AOP_CRY){
5989 pic14_emitcode("rlc","a");
5990 pic14_outBitC(result);
5993 pic14_emitcode("rl","a");
5994 pic14_emitcode("anl","a,#0x01");
5995 pic14_outAcc(result);
5999 freeAsmop(left,NULL,ic,TRUE);
6000 freeAsmop(result,NULL,ic,TRUE);
6003 /*-----------------------------------------------------------------*/
6004 /* AccRol - rotate left accumulator by known count */
6005 /*-----------------------------------------------------------------*/
6006 static void AccRol (int shCount)
6008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6009 shCount &= 0x0007; // shCount : 0..7
6014 pic14_emitcode("rl","a");
6017 pic14_emitcode("rl","a");
6018 pic14_emitcode("rl","a");
6021 pic14_emitcode("swap","a");
6022 pic14_emitcode("rr","a");
6025 pic14_emitcode("swap","a");
6028 pic14_emitcode("swap","a");
6029 pic14_emitcode("rl","a");
6032 pic14_emitcode("rr","a");
6033 pic14_emitcode("rr","a");
6036 pic14_emitcode("rr","a");
6041 /*-----------------------------------------------------------------*/
6042 /* AccLsh - left shift accumulator by known count */
6043 /*-----------------------------------------------------------------*/
6044 static void AccLsh (int shCount)
6046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6049 pic14_emitcode("add","a,acc");
6052 pic14_emitcode("add","a,acc");
6053 pic14_emitcode("add","a,acc");
6055 /* rotate left accumulator */
6057 /* and kill the lower order bits */
6058 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6063 /*-----------------------------------------------------------------*/
6064 /* AccRsh - right shift accumulator by known count */
6065 /*-----------------------------------------------------------------*/
6066 static void AccRsh (int shCount)
6068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6072 pic14_emitcode("rrc","a");
6074 /* rotate right accumulator */
6075 AccRol(8 - shCount);
6076 /* and kill the higher order bits */
6077 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6083 /*-----------------------------------------------------------------*/
6084 /* AccSRsh - signed right shift accumulator by known count */
6085 /*-----------------------------------------------------------------*/
6086 static void AccSRsh (int shCount)
6089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6092 pic14_emitcode("mov","c,acc.7");
6093 pic14_emitcode("rrc","a");
6094 } else if(shCount == 2){
6095 pic14_emitcode("mov","c,acc.7");
6096 pic14_emitcode("rrc","a");
6097 pic14_emitcode("mov","c,acc.7");
6098 pic14_emitcode("rrc","a");
6100 tlbl = newiTempLabel(NULL);
6101 /* rotate right accumulator */
6102 AccRol(8 - shCount);
6103 /* and kill the higher order bits */
6104 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6105 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6106 pic14_emitcode("orl","a,#0x%02x",
6107 (unsigned char)~SRMask[shCount]);
6108 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6113 /*-----------------------------------------------------------------*/
6114 /* shiftR1Left2Result - shift right one byte from left to result */
6115 /*-----------------------------------------------------------------*/
6116 static void shiftR1Left2ResultSigned (operand *left, int offl,
6117 operand *result, int offr,
6122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6124 same = (left == result) || (AOP(left) == AOP(result));
6128 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6130 emitpcode(POC_RRF, popGet(AOP(result),offr));
6132 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6133 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6143 /*-----------------------------------------------------------------*/
6144 /* shiftR1Left2Result - shift right one byte from left to result */
6145 /*-----------------------------------------------------------------*/
6146 static void shiftR1Left2Result (operand *left, int offl,
6147 operand *result, int offr,
6148 int shCount, int sign)
6152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6154 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6156 /* Copy the msb into the carry if signed. */
6158 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6168 emitpcode(POC_RRF, popGet(AOP(result),offr));
6170 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6171 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6177 emitpcode(POC_RRF, popGet(AOP(result),offr));
6179 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6180 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6183 emitpcode(POC_RRF, popGet(AOP(result),offr));
6188 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6190 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6191 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6194 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6195 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6196 emitpcode(POC_ANDLW, popGetLit(0x1f));
6197 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6201 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6202 emitpcode(POC_ANDLW, popGetLit(0x0f));
6203 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6207 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6208 emitpcode(POC_ANDLW, popGetLit(0x0f));
6209 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6211 emitpcode(POC_RRF, popGet(AOP(result),offr));
6216 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6217 emitpcode(POC_ANDLW, popGetLit(0x80));
6218 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6219 emitpcode(POC_RLF, popGet(AOP(result),offr));
6220 emitpcode(POC_RLF, popGet(AOP(result),offr));
6225 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6226 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6227 emitpcode(POC_RLF, popGet(AOP(result),offr));
6238 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6240 /* shift right accumulator */
6245 aopPut(AOP(result),"a",offr);
6249 /*-----------------------------------------------------------------*/
6250 /* shiftL1Left2Result - shift left one byte from left to result */
6251 /*-----------------------------------------------------------------*/
6252 static void shiftL1Left2Result (operand *left, int offl,
6253 operand *result, int offr, int shCount)
6258 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6260 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6261 DEBUGpic14_emitcode ("; ***","same = %d",same);
6262 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6264 /* shift left accumulator */
6265 //AccLsh(shCount); // don't comment out just yet...
6266 // aopPut(AOP(result),"a",offr);
6270 /* Shift left 1 bit position */
6271 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6273 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6275 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6276 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6280 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6281 emitpcode(POC_ANDLW,popGetLit(0x7e));
6282 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6283 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6286 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6287 emitpcode(POC_ANDLW,popGetLit(0x3e));
6288 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6289 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6290 emitpcode(POC_RLF, popGet(AOP(result),offr));
6293 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6294 emitpcode(POC_ANDLW, popGetLit(0xf0));
6295 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6298 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6299 emitpcode(POC_ANDLW, popGetLit(0xf0));
6300 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6301 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6304 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6305 emitpcode(POC_ANDLW, popGetLit(0x30));
6306 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6307 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6308 emitpcode(POC_RLF, popGet(AOP(result),offr));
6311 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6312 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6313 emitpcode(POC_RRF, popGet(AOP(result),offr));
6317 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6322 /*-----------------------------------------------------------------*/
6323 /* movLeft2Result - move byte from left to result */
6324 /*-----------------------------------------------------------------*/
6325 static void movLeft2Result (operand *left, int offl,
6326 operand *result, int offr, int sign)
6329 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6330 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6331 l = aopGet(AOP(left),offl,FALSE,FALSE);
6333 if (*l == '@' && (IS_AOP_PREG(result))) {
6334 pic14_emitcode("mov","a,%s",l);
6335 aopPut(AOP(result),"a",offr);
6338 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6339 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6341 //aopPut(AOP(result),l,offr);
6343 /* MSB sign in acc.7 ! */
6344 if(pic14_getDataSize(left) == offl+1){
6345 pic14_emitcode("mov","a,%s",l);
6346 aopPut(AOP(result),"a",offr);
6353 /*-----------------------------------------------------------------*/
6354 /* shiftL2Left2Result - shift left two bytes from left to result */
6355 /*-----------------------------------------------------------------*/
6356 static void shiftL2Left2Result (operand *left, int offl,
6357 operand *result, int offr, int shCount)
6361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6363 if(pic14_sameRegs(AOP(result), AOP(left))) {
6371 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6372 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6373 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6377 emitpcode(POC_RLF, popGet(AOP(result),offr));
6378 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6384 emitpcode(POC_MOVLW, popGetLit(0x0f));
6385 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6386 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6387 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6388 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6389 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6390 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6392 emitpcode(POC_RLF, popGet(AOP(result),offr));
6393 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6397 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6398 emitpcode(POC_RRF, popGet(AOP(result),offr));
6399 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6400 emitpcode(POC_RRF, popGet(AOP(result),offr));
6401 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6402 emitpcode(POC_ANDLW,popGetLit(0xc0));
6403 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6404 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6405 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6406 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6409 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6410 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6411 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6412 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6413 emitpcode(POC_RRF, popGet(AOP(result),offr));
6423 /* note, use a mov/add for the shift since the mov has a
6424 chance of getting optimized out */
6425 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6426 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6427 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6428 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6429 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6433 emitpcode(POC_RLF, popGet(AOP(result),offr));
6434 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6440 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6441 emitpcode(POC_ANDLW, popGetLit(0xF0));
6442 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6443 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6444 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6445 emitpcode(POC_ANDLW, popGetLit(0xF0));
6446 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6447 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6451 emitpcode(POC_RLF, popGet(AOP(result),offr));
6452 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6456 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6457 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6458 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6459 emitpcode(POC_MOVWF, 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(left),offl+MSB16));
6472 emitpcode(POC_RRFW, popGet(AOP(left),offl));
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));
6480 /*-----------------------------------------------------------------*/
6481 /* shiftR2Left2Result - shift right two bytes from left to result */
6482 /*-----------------------------------------------------------------*/
6483 static void shiftR2Left2Result (operand *left, int offl,
6484 operand *result, int offr,
6485 int shCount, int sign)
6489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6490 same = pic14_sameRegs(AOP(result), AOP(left));
6492 if(same && ((offl + MSB16) == offr)){
6494 /* don't crash result[offr] */
6495 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6496 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6498 movLeft2Result(left,offl, result, offr, 0);
6499 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6501 /* a:x >> shCount (x = lsb(result))*/
6504 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6506 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6516 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6517 emitpcode(POC_RRF,popGet(AOP(result),offr));
6520 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6521 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6522 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6523 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6528 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6529 emitpcode(POC_RRF,popGet(AOP(result),offr));
6536 emitpcode(POC_MOVLW, popGetLit(0xf0));
6537 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6538 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6540 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6541 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6542 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6543 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6545 emitpcode(POC_SWAPF, popGet(AOP(left),offl));
6546 emitpcode(POC_ANDLW, popGetLit(0x0f));
6547 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6549 emitpcode(POC_SWAPF, popGet(AOP(left),offl+MSB16));
6550 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6551 emitpcode(POC_ANDLW, popGetLit(0xf0));
6552 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6553 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6557 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6558 emitpcode(POC_RRF, popGet(AOP(result),offr));
6566 emitpcode(POC_RLF, popGet(AOP(result),offr));
6567 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6569 emitpcode(POC_RLF, popGet(AOP(result),offr));
6570 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6571 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6572 emitpcode(POC_ANDLW,popGetLit(0x03));
6573 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6574 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6575 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6576 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6578 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6579 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6580 emitpcode(POC_RLFW, popGet(AOP(result),offl+MSB16));
6581 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6582 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6583 emitpcode(POC_RLF, popGet(AOP(result),offr));
6584 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6585 emitpcode(POC_ANDLW,popGetLit(0x03));
6586 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6591 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6592 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6593 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6594 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6595 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6600 /*-----------------------------------------------------------------*/
6601 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6602 /*-----------------------------------------------------------------*/
6603 static void shiftLLeftOrResult (operand *left, int offl,
6604 operand *result, int offr, int shCount)
6606 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6607 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6608 /* shift left accumulator */
6610 /* or with result */
6611 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6612 /* back to result */
6613 aopPut(AOP(result),"a",offr);
6616 /*-----------------------------------------------------------------*/
6617 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6618 /*-----------------------------------------------------------------*/
6619 static void shiftRLeftOrResult (operand *left, int offl,
6620 operand *result, int offr, int shCount)
6622 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6623 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6624 /* shift right accumulator */
6626 /* or with result */
6627 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6628 /* back to result */
6629 aopPut(AOP(result),"a",offr);
6632 /*-----------------------------------------------------------------*/
6633 /* genlshOne - left shift a one byte quantity by known count */
6634 /*-----------------------------------------------------------------*/
6635 static void genlshOne (operand *result, operand *left, int shCount)
6637 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6638 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6641 /*-----------------------------------------------------------------*/
6642 /* genlshTwo - left shift two bytes by known amount != 0 */
6643 /*-----------------------------------------------------------------*/
6644 static void genlshTwo (operand *result,operand *left, int shCount)
6648 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6649 size = pic14_getDataSize(result);
6651 /* if shCount >= 8 */
6657 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6659 movLeft2Result(left, LSB, result, MSB16, 0);
6661 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6664 /* 1 <= shCount <= 7 */
6667 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6669 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6673 /*-----------------------------------------------------------------*/
6674 /* shiftLLong - shift left one long from left to result */
6675 /* offl = LSB or MSB16 */
6676 /*-----------------------------------------------------------------*/
6677 static void shiftLLong (operand *left, operand *result, int offr )
6680 int size = AOP_SIZE(result);
6682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6683 if(size >= LSB+offr){
6684 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6686 pic14_emitcode("add","a,acc");
6687 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6688 size >= MSB16+offr && offr != LSB )
6689 pic14_emitcode("xch","a,%s",
6690 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6692 aopPut(AOP(result),"a",LSB+offr);
6695 if(size >= MSB16+offr){
6696 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6697 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6700 pic14_emitcode("rlc","a");
6701 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6702 size >= MSB24+offr && offr != LSB)
6703 pic14_emitcode("xch","a,%s",
6704 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6706 aopPut(AOP(result),"a",MSB16+offr);
6709 if(size >= MSB24+offr){
6710 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6711 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6714 pic14_emitcode("rlc","a");
6715 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6716 size >= MSB32+offr && offr != LSB )
6717 pic14_emitcode("xch","a,%s",
6718 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6720 aopPut(AOP(result),"a",MSB24+offr);
6723 if(size > MSB32+offr){
6724 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6725 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6728 pic14_emitcode("rlc","a");
6729 aopPut(AOP(result),"a",MSB32+offr);
6732 aopPut(AOP(result),zero,LSB);
6735 /*-----------------------------------------------------------------*/
6736 /* genlshFour - shift four byte by a known amount != 0 */
6737 /*-----------------------------------------------------------------*/
6738 static void genlshFour (operand *result, operand *left, int shCount)
6742 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6743 size = AOP_SIZE(result);
6745 /* if shifting more that 3 bytes */
6746 if (shCount >= 24 ) {
6749 /* lowest order of left goes to the highest
6750 order of the destination */
6751 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6753 movLeft2Result(left, LSB, result, MSB32, 0);
6754 aopPut(AOP(result),zero,LSB);
6755 aopPut(AOP(result),zero,MSB16);
6756 aopPut(AOP(result),zero,MSB32);
6760 /* more than two bytes */
6761 else if ( shCount >= 16 ) {
6762 /* lower order two bytes goes to higher order two bytes */
6764 /* if some more remaining */
6766 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6768 movLeft2Result(left, MSB16, result, MSB32, 0);
6769 movLeft2Result(left, LSB, result, MSB24, 0);
6771 aopPut(AOP(result),zero,MSB16);
6772 aopPut(AOP(result),zero,LSB);
6776 /* if more than 1 byte */
6777 else if ( shCount >= 8 ) {
6778 /* lower order three bytes goes to higher order three bytes */
6782 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6784 movLeft2Result(left, LSB, result, MSB16, 0);
6786 else{ /* size = 4 */
6788 movLeft2Result(left, MSB24, result, MSB32, 0);
6789 movLeft2Result(left, MSB16, result, MSB24, 0);
6790 movLeft2Result(left, LSB, result, MSB16, 0);
6791 aopPut(AOP(result),zero,LSB);
6793 else if(shCount == 1)
6794 shiftLLong(left, result, MSB16);
6796 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6797 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6798 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6799 aopPut(AOP(result),zero,LSB);
6804 /* 1 <= shCount <= 7 */
6805 else if(shCount <= 2){
6806 shiftLLong(left, result, LSB);
6808 shiftLLong(result, result, LSB);
6810 /* 3 <= shCount <= 7, optimize */
6812 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6813 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6814 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6818 /*-----------------------------------------------------------------*/
6819 /* genLeftShiftLiteral - left shifting by known count */
6820 /*-----------------------------------------------------------------*/
6821 static void genLeftShiftLiteral (operand *left,
6826 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
6829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6830 freeAsmop(right,NULL,ic,TRUE);
6832 aopOp(left,ic,FALSE);
6833 aopOp(result,ic,FALSE);
6835 size = getSize(operandType(result));
6838 pic14_emitcode("; shift left ","result %d, left %d",size,
6842 /* I suppose that the left size >= result size */
6845 movLeft2Result(left, size, result, size, 0);
6849 else if(shCount >= (size * 8))
6851 aopPut(AOP(result),zero,size);
6855 genlshOne (result,left,shCount);
6860 genlshTwo (result,left,shCount);
6864 genlshFour (result,left,shCount);
6868 freeAsmop(left,NULL,ic,TRUE);
6869 freeAsmop(result,NULL,ic,TRUE);
6872 /*-----------------------------------------------------------------*
6873 * genMultiAsm - repeat assembly instruction for size of register.
6874 * if endian == 1, then the high byte (i.e base address + size of
6875 * register) is used first else the low byte is used first;
6876 *-----------------------------------------------------------------*/
6877 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
6882 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6895 emitpcode(poc, popGet(AOP(reg),offset));
6900 /*-----------------------------------------------------------------*/
6901 /* genLeftShift - generates code for left shifting */
6902 /*-----------------------------------------------------------------*/
6903 static void genLeftShift (iCode *ic)
6905 operand *left,*right, *result;
6908 symbol *tlbl , *tlbl1;
6910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6912 right = IC_RIGHT(ic);
6914 result = IC_RESULT(ic);
6916 aopOp(right,ic,FALSE);
6918 /* if the shift count is known then do it
6919 as efficiently as possible */
6920 if (AOP_TYPE(right) == AOP_LIT) {
6921 genLeftShiftLiteral (left,right,result,ic);
6925 /* shift count is unknown then we have to form
6926 a loop get the loop count in B : Note: we take
6927 only the lower order byte since shifting
6928 more that 32 bits make no sense anyway, ( the
6929 largest size of an object can be only 32 bits ) */
6932 aopOp(left,ic,FALSE);
6933 aopOp(result,ic,FALSE);
6935 /* now move the left to the result if they are not the
6937 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
6938 AOP_SIZE(result) > 1) {
6940 size = AOP_SIZE(result);
6943 l = aopGet(AOP(left),offset,FALSE,TRUE);
6944 if (*l == '@' && (IS_AOP_PREG(result))) {
6946 pic14_emitcode("mov","a,%s",l);
6947 aopPut(AOP(result),"a",offset);
6949 aopPut(AOP(result),l,offset);
6954 size = AOP_SIZE(result);
6956 /* if it is only one byte then */
6958 if(optimized_for_speed) {
6959 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
6960 emitpcode(POC_ANDLW, popGetLit(0xf0));
6961 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
6962 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6963 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6964 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
6965 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6966 emitpcode(POC_RLFW, popGet(AOP(result),0));
6967 emitpcode(POC_ANDLW, popGetLit(0xfe));
6968 emitpcode(POC_ADDFW, popGet(AOP(result),0));
6969 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
6970 emitpcode(POC_ADDWF, popGet(AOP(result),0));
6973 tlbl = newiTempLabel(NULL);
6974 if (!pic14_sameRegs(AOP(left),AOP(result))) {
6975 emitpcode(POC_MOVFW, popGet(AOP(left),0));
6976 emitpcode(POC_MOVWF, popGet(AOP(result),0));
6979 emitpcode(POC_COMFW, popGet(AOP(right),0));
6980 emitpcode(POC_RRF, popGet(AOP(result),0));
6981 emitpLabel(tlbl->key);
6982 emitpcode(POC_RLF, popGet(AOP(result),0));
6983 emitpcode(POC_ADDLW, popGetLit(1));
6985 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
6990 if (pic14_sameRegs(AOP(left),AOP(result))) {
6992 tlbl = newiTempLabel(NULL);
6993 emitpcode(POC_COMFW, popGet(AOP(right),0));
6994 genMultiAsm(POC_RRF, result, size,1);
6995 emitpLabel(tlbl->key);
6996 genMultiAsm(POC_RLF, result, size,0);
6997 emitpcode(POC_ADDLW, popGetLit(1));
6999 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7003 tlbl = newiTempLabel(NULL);
7005 tlbl1 = newiTempLabel(NULL);
7007 reAdjustPreg(AOP(result));
7009 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7010 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7011 l = aopGet(AOP(result),offset,FALSE,FALSE);
7013 pic14_emitcode("add","a,acc");
7014 aopPut(AOP(result),"a",offset++);
7016 l = aopGet(AOP(result),offset,FALSE,FALSE);
7018 pic14_emitcode("rlc","a");
7019 aopPut(AOP(result),"a",offset++);
7021 reAdjustPreg(AOP(result));
7023 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7024 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7026 freeAsmop (right,NULL,ic,TRUE);
7027 freeAsmop(left,NULL,ic,TRUE);
7028 freeAsmop(result,NULL,ic,TRUE);
7031 /*-----------------------------------------------------------------*/
7032 /* genrshOne - right shift a one byte quantity by known count */
7033 /*-----------------------------------------------------------------*/
7034 static void genrshOne (operand *result, operand *left,
7035 int shCount, int sign)
7037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7038 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7041 /*-----------------------------------------------------------------*/
7042 /* genrshTwo - right shift two bytes by known amount != 0 */
7043 /*-----------------------------------------------------------------*/
7044 static void genrshTwo (operand *result,operand *left,
7045 int shCount, int sign)
7047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7048 /* if shCount >= 8 */
7052 shiftR1Left2Result(left, MSB16, result, LSB,
7055 movLeft2Result(left, MSB16, result, LSB, sign);
7057 addSign(result, MSB16, sign);
7059 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7063 /* 1 <= shCount <= 7 */
7065 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7068 /*-----------------------------------------------------------------*/
7069 /* shiftRLong - shift right one long from left to result */
7070 /* offl = LSB or MSB16 */
7071 /*-----------------------------------------------------------------*/
7072 static void shiftRLong (operand *left, int offl,
7073 operand *result, int sign)
7075 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7077 pic14_emitcode("clr","c");
7078 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7080 pic14_emitcode("mov","c,acc.7");
7081 pic14_emitcode("rrc","a");
7082 aopPut(AOP(result),"a",MSB32-offl);
7084 /* add sign of "a" */
7085 addSign(result, MSB32, sign);
7087 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7088 pic14_emitcode("rrc","a");
7089 aopPut(AOP(result),"a",MSB24-offl);
7091 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7092 pic14_emitcode("rrc","a");
7093 aopPut(AOP(result),"a",MSB16-offl);
7096 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7097 pic14_emitcode("rrc","a");
7098 aopPut(AOP(result),"a",LSB);
7102 /*-----------------------------------------------------------------*/
7103 /* genrshFour - shift four byte by a known amount != 0 */
7104 /*-----------------------------------------------------------------*/
7105 static void genrshFour (operand *result, operand *left,
7106 int shCount, int sign)
7108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7109 /* if shifting more that 3 bytes */
7110 if(shCount >= 24 ) {
7113 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7115 movLeft2Result(left, MSB32, result, LSB, sign);
7116 addSign(result, MSB16, sign);
7118 else if(shCount >= 16){
7121 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7123 movLeft2Result(left, MSB24, result, LSB, 0);
7124 movLeft2Result(left, MSB32, result, MSB16, sign);
7126 addSign(result, MSB24, sign);
7128 else if(shCount >= 8){
7131 shiftRLong(left, MSB16, result, sign);
7132 else if(shCount == 0){
7133 movLeft2Result(left, MSB16, result, LSB, 0);
7134 movLeft2Result(left, MSB24, result, MSB16, 0);
7135 movLeft2Result(left, MSB32, result, MSB24, sign);
7136 addSign(result, MSB32, sign);
7139 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7140 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7141 /* the last shift is signed */
7142 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7143 addSign(result, MSB32, sign);
7146 else{ /* 1 <= shCount <= 7 */
7148 shiftRLong(left, LSB, result, sign);
7150 shiftRLong(result, LSB, result, sign);
7153 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7154 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7155 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7160 /*-----------------------------------------------------------------*/
7161 /* genRightShiftLiteral - right shifting by known count */
7162 /*-----------------------------------------------------------------*/
7163 static void genRightShiftLiteral (operand *left,
7169 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7173 freeAsmop(right,NULL,ic,TRUE);
7175 aopOp(left,ic,FALSE);
7176 aopOp(result,ic,FALSE);
7179 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7183 size = pic14_getDataSize(left);
7184 /* test the LEFT size !!! */
7186 /* I suppose that the left size >= result size */
7188 size = pic14_getDataSize(result);
7190 movLeft2Result(left, size, result, size, 0);
7193 else if(shCount >= (size * 8)){
7195 /* get sign in acc.7 */
7196 MOVA(aopGet(AOP(left),size-1,FALSE,FALSE));
7197 addSign(result, LSB, sign);
7201 genrshOne (result,left,shCount,sign);
7205 genrshTwo (result,left,shCount,sign);
7209 genrshFour (result,left,shCount,sign);
7215 freeAsmop(left,NULL,ic,TRUE);
7216 freeAsmop(result,NULL,ic,TRUE);
7220 /*-----------------------------------------------------------------*/
7221 /* genSignedRightShift - right shift of signed number */
7222 /*-----------------------------------------------------------------*/
7223 static void genSignedRightShift (iCode *ic)
7225 operand *right, *left, *result;
7228 symbol *tlbl, *tlbl1 ;
7230 /* we do it the hard way put the shift count in b
7231 and loop thru preserving the sign */
7232 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7234 right = IC_RIGHT(ic);
7236 result = IC_RESULT(ic);
7238 aopOp(right,ic,FALSE);
7241 if ( AOP_TYPE(right) == AOP_LIT) {
7242 genRightShiftLiteral (left,right,result,ic,1);
7245 /* shift count is unknown then we have to form
7246 a loop get the loop count in B : Note: we take
7247 only the lower order byte since shifting
7248 more that 32 bits make no sense anyway, ( the
7249 largest size of an object can be only 32 bits ) */
7251 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7252 pic14_emitcode("inc","b");
7253 freeAsmop (right,NULL,ic,TRUE);
7254 aopOp(left,ic,FALSE);
7255 aopOp(result,ic,FALSE);
7257 /* now move the left to the result if they are not the
7259 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7260 AOP_SIZE(result) > 1) {
7262 size = AOP_SIZE(result);
7265 l = aopGet(AOP(left),offset,FALSE,TRUE);
7266 if (*l == '@' && IS_AOP_PREG(result)) {
7268 pic14_emitcode("mov","a,%s",l);
7269 aopPut(AOP(result),"a",offset);
7271 aopPut(AOP(result),l,offset);
7276 /* mov the highest order bit to OVR */
7277 tlbl = newiTempLabel(NULL);
7278 tlbl1= newiTempLabel(NULL);
7280 size = AOP_SIZE(result);
7282 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7283 pic14_emitcode("rlc","a");
7284 pic14_emitcode("mov","ov,c");
7285 /* if it is only one byte then */
7287 l = aopGet(AOP(left),0,FALSE,FALSE);
7289 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7290 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7291 pic14_emitcode("mov","c,ov");
7292 pic14_emitcode("rrc","a");
7293 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7294 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7295 aopPut(AOP(result),"a",0);
7299 reAdjustPreg(AOP(result));
7300 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7301 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7302 pic14_emitcode("mov","c,ov");
7304 l = aopGet(AOP(result),offset,FALSE,FALSE);
7306 pic14_emitcode("rrc","a");
7307 aopPut(AOP(result),"a",offset--);
7309 reAdjustPreg(AOP(result));
7310 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7311 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7314 freeAsmop(left,NULL,ic,TRUE);
7315 freeAsmop(result,NULL,ic,TRUE);
7318 /*-----------------------------------------------------------------*/
7319 /* genRightShift - generate code for right shifting */
7320 /*-----------------------------------------------------------------*/
7321 static void genRightShift (iCode *ic)
7323 operand *right, *left, *result;
7327 symbol *tlbl, *tlbl1 ;
7329 /* if signed then we do it the hard way preserve the
7330 sign bit moving it inwards */
7331 retype = getSpec(operandType(IC_RESULT(ic)));
7332 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7334 if (!SPEC_USIGN(retype)) {
7335 genSignedRightShift (ic);
7339 /* signed & unsigned types are treated the same : i.e. the
7340 signed is NOT propagated inwards : quoting from the
7341 ANSI - standard : "for E1 >> E2, is equivalent to division
7342 by 2**E2 if unsigned or if it has a non-negative value,
7343 otherwise the result is implementation defined ", MY definition
7344 is that the sign does not get propagated */
7346 right = IC_RIGHT(ic);
7348 result = IC_RESULT(ic);
7350 aopOp(right,ic,FALSE);
7352 /* if the shift count is known then do it
7353 as efficiently as possible */
7354 if (AOP_TYPE(right) == AOP_LIT) {
7355 genRightShiftLiteral (left,right,result,ic, 0);
7359 /* shift count is unknown then we have to form
7360 a loop get the loop count in B : Note: we take
7361 only the lower order byte since shifting
7362 more that 32 bits make no sense anyway, ( the
7363 largest size of an object can be only 32 bits ) */
7365 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7366 pic14_emitcode("inc","b");
7367 aopOp(left,ic,FALSE);
7368 aopOp(result,ic,FALSE);
7370 /* now move the left to the result if they are not the
7372 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7373 AOP_SIZE(result) > 1) {
7375 size = AOP_SIZE(result);
7378 l = aopGet(AOP(left),offset,FALSE,TRUE);
7379 if (*l == '@' && IS_AOP_PREG(result)) {
7381 pic14_emitcode("mov","a,%s",l);
7382 aopPut(AOP(result),"a",offset);
7384 aopPut(AOP(result),l,offset);
7389 tlbl = newiTempLabel(NULL);
7390 tlbl1= newiTempLabel(NULL);
7391 size = AOP_SIZE(result);
7394 /* if it is only one byte then */
7397 l = aopGet(AOP(left),0,FALSE,FALSE);
7399 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7400 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7402 pic14_emitcode("rrc","a");
7403 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7404 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7405 aopPut(AOP(result),"a",0);
7407 tlbl = newiTempLabel(NULL);
7408 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7409 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7410 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7413 emitpcode(POC_COMFW, popGet(AOP(right),0));
7414 emitpcode(POC_RLF, popGet(AOP(result),0));
7415 emitpLabel(tlbl->key);
7416 emitpcode(POC_RRF, popGet(AOP(result),0));
7417 emitpcode(POC_ADDLW, popGetLit(1));
7419 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7424 reAdjustPreg(AOP(result));
7425 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7426 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7429 l = aopGet(AOP(result),offset,FALSE,FALSE);
7431 pic14_emitcode("rrc","a");
7432 aopPut(AOP(result),"a",offset--);
7434 reAdjustPreg(AOP(result));
7436 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7437 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7440 freeAsmop(left,NULL,ic,TRUE);
7441 freeAsmop (right,NULL,ic,TRUE);
7442 freeAsmop(result,NULL,ic,TRUE);
7445 /*-----------------------------------------------------------------*/
7446 /* genUnpackBits - generates code for unpacking bits */
7447 /*-----------------------------------------------------------------*/
7448 static void genUnpackBits (operand *result, char *rname, int ptype)
7455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7456 etype = getSpec(operandType(result));
7458 /* read the first byte */
7463 pic14_emitcode("mov","a,@%s",rname);
7467 pic14_emitcode("movx","a,@%s",rname);
7471 pic14_emitcode("movx","a,@dptr");
7475 pic14_emitcode("clr","a");
7476 pic14_emitcode("movc","a","@a+dptr");
7480 pic14_emitcode("lcall","__gptrget");
7484 /* if we have bitdisplacement then it fits */
7485 /* into this byte completely or if length is */
7486 /* less than a byte */
7487 if ((shCnt = SPEC_BSTR(etype)) ||
7488 (SPEC_BLEN(etype) <= 8)) {
7490 /* shift right acc */
7493 pic14_emitcode("anl","a,#0x%02x",
7494 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7495 aopPut(AOP(result),"a",offset);
7499 /* bit field did not fit in a byte */
7500 rlen = SPEC_BLEN(etype) - 8;
7501 aopPut(AOP(result),"a",offset++);
7508 pic14_emitcode("inc","%s",rname);
7509 pic14_emitcode("mov","a,@%s",rname);
7513 pic14_emitcode("inc","%s",rname);
7514 pic14_emitcode("movx","a,@%s",rname);
7518 pic14_emitcode("inc","dptr");
7519 pic14_emitcode("movx","a,@dptr");
7523 pic14_emitcode("clr","a");
7524 pic14_emitcode("inc","dptr");
7525 pic14_emitcode("movc","a","@a+dptr");
7529 pic14_emitcode("inc","dptr");
7530 pic14_emitcode("lcall","__gptrget");
7535 /* if we are done */
7539 aopPut(AOP(result),"a",offset++);
7544 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7545 aopPut(AOP(result),"a",offset);
7552 /*-----------------------------------------------------------------*/
7553 /* genDataPointerGet - generates code when ptr offset is known */
7554 /*-----------------------------------------------------------------*/
7555 static void genDataPointerGet (operand *left,
7559 int size , offset = 0;
7562 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7565 /* optimization - most of the time, left and result are the same
7566 * address, but different types. for the pic code, we could omit
7570 aopOp(result,ic,TRUE);
7572 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7574 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7576 size = AOP_SIZE(result);
7579 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7583 freeAsmop(left,NULL,ic,TRUE);
7584 freeAsmop(result,NULL,ic,TRUE);
7587 /*-----------------------------------------------------------------*/
7588 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7589 /*-----------------------------------------------------------------*/
7590 static void genNearPointerGet (operand *left,
7597 sym_link *rtype, *retype;
7598 sym_link *ltype = operandType(left);
7601 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7603 rtype = operandType(result);
7604 retype= getSpec(rtype);
7606 aopOp(left,ic,FALSE);
7608 /* if left is rematerialisable and
7609 result is not bit variable type and
7610 the left is pointer to data space i.e
7611 lower 128 bytes of space */
7612 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7613 !IS_BITVAR(retype) &&
7614 DCL_TYPE(ltype) == POINTER) {
7615 //genDataPointerGet (left,result,ic);
7619 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7621 /* if the value is already in a pointer register
7622 then don't need anything more */
7623 if (!AOP_INPREG(AOP(left))) {
7624 /* otherwise get a free pointer register */
7625 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7627 preg = getFreePtr(ic,&aop,FALSE);
7628 pic14_emitcode("mov","%s,%s",
7630 aopGet(AOP(left),0,FALSE,TRUE));
7631 rname = preg->name ;
7633 rname = aopGet(AOP(left),0,FALSE,FALSE);
7635 freeAsmop(left,NULL,ic,TRUE);
7636 aopOp (result,ic,FALSE);
7638 /* if bitfield then unpack the bits */
7639 if (IS_BITVAR(retype))
7640 genUnpackBits (result,rname,POINTER);
7642 /* we have can just get the values */
7643 int size = AOP_SIZE(result);
7646 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7648 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7650 pic14_emitcode("mov","a,@%s",rname);
7651 aopPut(AOP(result),"a",offset);
7653 sprintf(buffer,"@%s",rname);
7654 aopPut(AOP(result),buffer,offset);
7658 pic14_emitcode("inc","%s",rname);
7662 /* now some housekeeping stuff */
7664 /* we had to allocate for this iCode */
7665 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7666 freeAsmop(NULL,aop,ic,TRUE);
7668 /* we did not allocate which means left
7669 already in a pointer register, then
7670 if size > 0 && this could be used again
7671 we have to point it back to where it
7673 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7674 if (AOP_SIZE(result) > 1 &&
7675 !OP_SYMBOL(left)->remat &&
7676 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7678 int size = AOP_SIZE(result) - 1;
7680 pic14_emitcode("dec","%s",rname);
7685 freeAsmop(result,NULL,ic,TRUE);
7689 /*-----------------------------------------------------------------*/
7690 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7691 /*-----------------------------------------------------------------*/
7692 static void genPagedPointerGet (operand *left,
7699 sym_link *rtype, *retype;
7701 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7703 rtype = operandType(result);
7704 retype= getSpec(rtype);
7706 aopOp(left,ic,FALSE);
7708 /* if the value is already in a pointer register
7709 then don't need anything more */
7710 if (!AOP_INPREG(AOP(left))) {
7711 /* otherwise get a free pointer register */
7713 preg = getFreePtr(ic,&aop,FALSE);
7714 pic14_emitcode("mov","%s,%s",
7716 aopGet(AOP(left),0,FALSE,TRUE));
7717 rname = preg->name ;
7719 rname = aopGet(AOP(left),0,FALSE,FALSE);
7721 freeAsmop(left,NULL,ic,TRUE);
7722 aopOp (result,ic,FALSE);
7724 /* if bitfield then unpack the bits */
7725 if (IS_BITVAR(retype))
7726 genUnpackBits (result,rname,PPOINTER);
7728 /* we have can just get the values */
7729 int size = AOP_SIZE(result);
7734 pic14_emitcode("movx","a,@%s",rname);
7735 aopPut(AOP(result),"a",offset);
7740 pic14_emitcode("inc","%s",rname);
7744 /* now some housekeeping stuff */
7746 /* we had to allocate for this iCode */
7747 freeAsmop(NULL,aop,ic,TRUE);
7749 /* we did not allocate which means left
7750 already in a pointer register, then
7751 if size > 0 && this could be used again
7752 we have to point it back to where it
7754 if (AOP_SIZE(result) > 1 &&
7755 !OP_SYMBOL(left)->remat &&
7756 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7758 int size = AOP_SIZE(result) - 1;
7760 pic14_emitcode("dec","%s",rname);
7765 freeAsmop(result,NULL,ic,TRUE);
7770 /*-----------------------------------------------------------------*/
7771 /* genFarPointerGet - gget value from far space */
7772 /*-----------------------------------------------------------------*/
7773 static void genFarPointerGet (operand *left,
7774 operand *result, iCode *ic)
7777 sym_link *retype = getSpec(operandType(result));
7779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7781 aopOp(left,ic,FALSE);
7783 /* if the operand is already in dptr
7784 then we do nothing else we move the value to dptr */
7785 if (AOP_TYPE(left) != AOP_STR) {
7786 /* if this is remateriazable */
7787 if (AOP_TYPE(left) == AOP_IMMD)
7788 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7789 else { /* we need to get it byte by byte */
7790 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7791 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7792 if (options.model == MODEL_FLAT24)
7794 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7798 /* so dptr know contains the address */
7799 freeAsmop(left,NULL,ic,TRUE);
7800 aopOp(result,ic,FALSE);
7802 /* if bit then unpack */
7803 if (IS_BITVAR(retype))
7804 genUnpackBits(result,"dptr",FPOINTER);
7806 size = AOP_SIZE(result);
7810 pic14_emitcode("movx","a,@dptr");
7811 aopPut(AOP(result),"a",offset++);
7813 pic14_emitcode("inc","dptr");
7817 freeAsmop(result,NULL,ic,TRUE);
7820 /*-----------------------------------------------------------------*/
7821 /* genCodePointerGet - get value from code space */
7822 /*-----------------------------------------------------------------*/
7823 static void genCodePointerGet (operand *left,
7824 operand *result, iCode *ic)
7827 sym_link *retype = getSpec(operandType(result));
7829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7831 aopOp(left,ic,FALSE);
7833 /* if the operand is already in dptr
7834 then we do nothing else we move the value to dptr */
7835 if (AOP_TYPE(left) != AOP_STR) {
7836 /* if this is remateriazable */
7837 if (AOP_TYPE(left) == AOP_IMMD)
7838 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7839 else { /* we need to get it byte by byte */
7840 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
7841 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
7842 if (options.model == MODEL_FLAT24)
7844 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
7848 /* so dptr know contains the address */
7849 freeAsmop(left,NULL,ic,TRUE);
7850 aopOp(result,ic,FALSE);
7852 /* if bit then unpack */
7853 if (IS_BITVAR(retype))
7854 genUnpackBits(result,"dptr",CPOINTER);
7856 size = AOP_SIZE(result);
7860 pic14_emitcode("clr","a");
7861 pic14_emitcode("movc","a,@a+dptr");
7862 aopPut(AOP(result),"a",offset++);
7864 pic14_emitcode("inc","dptr");
7868 freeAsmop(result,NULL,ic,TRUE);
7871 /*-----------------------------------------------------------------*/
7872 /* genGenPointerGet - gget value from generic pointer space */
7873 /*-----------------------------------------------------------------*/
7874 static void genGenPointerGet (operand *left,
7875 operand *result, iCode *ic)
7878 sym_link *retype = getSpec(operandType(result));
7880 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7881 aopOp(left,ic,FALSE);
7882 aopOp(result,ic,FALSE);
7885 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7887 /* if the operand is already in dptr
7888 then we do nothing else we move the value to dptr */
7889 // if (AOP_TYPE(left) != AOP_STR) {
7890 /* if this is remateriazable */
7891 if (AOP_TYPE(left) == AOP_IMMD) {
7892 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
7893 pic14_emitcode("mov","b,#%d",pointerCode(retype));
7895 else { /* we need to get it byte by byte */
7897 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7898 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7900 size = AOP_SIZE(result);
7904 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7905 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7907 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7912 /* so dptr know contains the address */
7914 /* if bit then unpack */
7915 //if (IS_BITVAR(retype))
7916 // genUnpackBits(result,"dptr",GPOINTER);
7919 freeAsmop(left,NULL,ic,TRUE);
7920 freeAsmop(result,NULL,ic,TRUE);
7924 /*-----------------------------------------------------------------*/
7925 /* genConstPointerGet - get value from const generic pointer space */
7926 /*-----------------------------------------------------------------*/
7927 static void genConstPointerGet (operand *left,
7928 operand *result, iCode *ic)
7930 //sym_link *retype = getSpec(operandType(result));
7931 symbol *albl = newiTempLabel(NULL);
7932 symbol *blbl = newiTempLabel(NULL);
7935 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7936 aopOp(left,ic,FALSE);
7937 aopOp(result,ic,FALSE);
7940 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7942 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
7944 emitpcode(POC_CALL,popGetLabel(albl->key));
7945 emitpcode(POC_GOTO,popGetLabel(blbl->key));
7946 emitpLabel(albl->key);
7948 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
7950 emitpcode(poc,popGet(AOP(left),1));
7951 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
7952 emitpcode(poc,popGet(AOP(left),0));
7953 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
7955 emitpLabel(blbl->key);
7957 emitpcode(POC_MOVWF,popGet(AOP(result),0));
7960 freeAsmop(left,NULL,ic,TRUE);
7961 freeAsmop(result,NULL,ic,TRUE);
7964 /*-----------------------------------------------------------------*/
7965 /* genPointerGet - generate code for pointer get */
7966 /*-----------------------------------------------------------------*/
7967 static void genPointerGet (iCode *ic)
7969 operand *left, *result ;
7970 sym_link *type, *etype;
7973 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7976 result = IC_RESULT(ic) ;
7978 /* depending on the type of pointer we need to
7979 move it to the correct pointer register */
7980 type = operandType(left);
7981 etype = getSpec(type);
7983 if (IS_PTR_CONST(type))
7984 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
7986 /* if left is of type of pointer then it is simple */
7987 if (IS_PTR(type) && !IS_FUNC(type->next))
7988 p_type = DCL_TYPE(type);
7990 /* we have to go by the storage class */
7991 p_type = PTR_TYPE(SPEC_OCLS(etype));
7993 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
7995 if (SPEC_OCLS(etype)->codesp ) {
7996 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
7997 //p_type = CPOINTER ;
8000 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8001 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8002 /*p_type = FPOINTER ;*/
8004 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8005 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8006 /* p_type = PPOINTER; */
8008 if (SPEC_OCLS(etype) == idata )
8009 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8010 /* p_type = IPOINTER; */
8012 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8013 /* p_type = POINTER ; */
8016 /* now that we have the pointer type we assign
8017 the pointer values */
8022 genNearPointerGet (left,result,ic);
8026 genPagedPointerGet(left,result,ic);
8030 genFarPointerGet (left,result,ic);
8034 genConstPointerGet (left,result,ic);
8035 //pic14_emitcodePointerGet (left,result,ic);
8039 if (IS_PTR_CONST(type))
8040 genConstPointerGet (left,result,ic);
8042 genGenPointerGet (left,result,ic);
8048 /*-----------------------------------------------------------------*/
8049 /* genPackBits - generates code for packed bit storage */
8050 /*-----------------------------------------------------------------*/
8051 static void genPackBits (sym_link *etype ,
8053 char *rname, int p_type)
8061 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8062 blen = SPEC_BLEN(etype);
8063 bstr = SPEC_BSTR(etype);
8065 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8068 /* if the bit lenth is less than or */
8069 /* it exactly fits a byte then */
8070 if (SPEC_BLEN(etype) <= 8 ) {
8071 shCount = SPEC_BSTR(etype) ;
8073 /* shift left acc */
8076 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8081 pic14_emitcode ("mov","b,a");
8082 pic14_emitcode("mov","a,@%s",rname);
8086 pic14_emitcode ("mov","b,a");
8087 pic14_emitcode("movx","a,@dptr");
8091 pic14_emitcode ("push","b");
8092 pic14_emitcode ("push","acc");
8093 pic14_emitcode ("lcall","__gptrget");
8094 pic14_emitcode ("pop","b");
8098 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8099 ((unsigned char)(0xFF << (blen+bstr)) |
8100 (unsigned char)(0xFF >> (8-bstr)) ) );
8101 pic14_emitcode ("orl","a,b");
8102 if (p_type == GPOINTER)
8103 pic14_emitcode("pop","b");
8109 pic14_emitcode("mov","@%s,a",rname);
8113 pic14_emitcode("movx","@dptr,a");
8117 DEBUGpic14_emitcode(";lcall","__gptrput");
8122 if ( SPEC_BLEN(etype) <= 8 )
8125 pic14_emitcode("inc","%s",rname);
8126 rLen = SPEC_BLEN(etype) ;
8128 /* now generate for lengths greater than one byte */
8131 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8141 pic14_emitcode("mov","@%s,a",rname);
8143 pic14_emitcode("mov","@%s,%s",rname,l);
8148 pic14_emitcode("movx","@dptr,a");
8153 DEBUGpic14_emitcode(";lcall","__gptrput");
8156 pic14_emitcode ("inc","%s",rname);
8161 /* last last was not complete */
8163 /* save the byte & read byte */
8166 pic14_emitcode ("mov","b,a");
8167 pic14_emitcode("mov","a,@%s",rname);
8171 pic14_emitcode ("mov","b,a");
8172 pic14_emitcode("movx","a,@dptr");
8176 pic14_emitcode ("push","b");
8177 pic14_emitcode ("push","acc");
8178 pic14_emitcode ("lcall","__gptrget");
8179 pic14_emitcode ("pop","b");
8183 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8184 pic14_emitcode ("orl","a,b");
8187 if (p_type == GPOINTER)
8188 pic14_emitcode("pop","b");
8193 pic14_emitcode("mov","@%s,a",rname);
8197 pic14_emitcode("movx","@dptr,a");
8201 DEBUGpic14_emitcode(";lcall","__gptrput");
8205 /*-----------------------------------------------------------------*/
8206 /* genDataPointerSet - remat pointer to data space */
8207 /*-----------------------------------------------------------------*/
8208 static void genDataPointerSet(operand *right,
8212 int size, offset = 0 ;
8213 char *l, buffer[256];
8215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8216 aopOp(right,ic,FALSE);
8218 l = aopGet(AOP(result),0,FALSE,TRUE);
8219 size = AOP_SIZE(right);
8220 if ( AOP_TYPE(result) == AOP_PCODE) {
8221 fprintf(stderr,"genDataPointerSet %s, %d\n",
8222 AOP(result)->aopu.pcop->name,
8223 PCOI(AOP(result)->aopu.pcop)->offset);
8226 // tsd, was l+1 - the underline `_' prefix was being stripped
8229 sprintf(buffer,"(%s + %d)",l,offset);
8230 fprintf(stderr,"oops %s\n",buffer);
8232 sprintf(buffer,"%s",l);
8234 if (AOP_TYPE(right) == AOP_LIT) {
8235 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8236 lit = lit >> (8*offset);
8238 pic14_emitcode("movlw","%d",lit);
8239 pic14_emitcode("movwf","%s",buffer);
8241 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8242 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8243 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8246 pic14_emitcode("clrf","%s",buffer);
8247 //emitpcode(POC_CLRF, popRegFromString(buffer));
8248 emitpcode(POC_CLRF, popGet(AOP(result),0));
8251 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8252 pic14_emitcode("movwf","%s",buffer);
8254 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8255 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8256 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8263 freeAsmop(right,NULL,ic,TRUE);
8264 freeAsmop(result,NULL,ic,TRUE);
8267 /*-----------------------------------------------------------------*/
8268 /* genNearPointerSet - pic14_emitcode for near pointer put */
8269 /*-----------------------------------------------------------------*/
8270 static void genNearPointerSet (operand *right,
8277 sym_link *ptype = operandType(result);
8280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8281 retype= getSpec(operandType(right));
8283 aopOp(result,ic,FALSE);
8285 /* if the result is rematerializable &
8286 in data space & not a bit variable */
8287 //if (AOP_TYPE(result) == AOP_IMMD &&
8288 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8289 DCL_TYPE(ptype) == POINTER &&
8290 !IS_BITVAR(retype)) {
8291 genDataPointerSet (right,result,ic);
8295 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8297 /* if the value is already in a pointer register
8298 then don't need anything more */
8299 if (!AOP_INPREG(AOP(result))) {
8300 /* otherwise get a free pointer register */
8301 //aop = newAsmop(0);
8302 //preg = getFreePtr(ic,&aop,FALSE);
8303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8304 //pic14_emitcode("mov","%s,%s",
8306 // aopGet(AOP(result),0,FALSE,TRUE));
8307 //rname = preg->name ;
8308 pic14_emitcode("movwf","fsr");
8310 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8312 freeAsmop(result,NULL,ic,TRUE);
8313 aopOp (right,ic,FALSE);
8314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8316 /* if bitfield then unpack the bits */
8317 if (IS_BITVAR(retype)) {
8318 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8319 "The programmer is obviously confused");
8320 //genPackBits (retype,right,rname,POINTER);
8324 /* we have can just get the values */
8325 int size = AOP_SIZE(right);
8328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8330 l = aopGet(AOP(right),offset,FALSE,TRUE);
8333 //pic14_emitcode("mov","@%s,a",rname);
8334 pic14_emitcode("movf","indf,w ;1");
8337 if (AOP_TYPE(right) == AOP_LIT) {
8338 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8340 pic14_emitcode("movlw","%s",l);
8341 pic14_emitcode("movwf","indf ;2");
8343 pic14_emitcode("clrf","indf");
8345 pic14_emitcode("movf","%s,w",l);
8346 pic14_emitcode("movwf","indf ;2");
8348 //pic14_emitcode("mov","@%s,%s",rname,l);
8351 pic14_emitcode("incf","fsr,f ;3");
8352 //pic14_emitcode("inc","%s",rname);
8357 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8358 /* now some housekeeping stuff */
8360 /* we had to allocate for this iCode */
8361 freeAsmop(NULL,aop,ic,TRUE);
8363 /* we did not allocate which means left
8364 already in a pointer register, then
8365 if size > 0 && this could be used again
8366 we have to point it back to where it
8368 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8369 if (AOP_SIZE(right) > 1 &&
8370 !OP_SYMBOL(result)->remat &&
8371 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8373 int size = AOP_SIZE(right) - 1;
8375 pic14_emitcode("decf","fsr,f");
8376 //pic14_emitcode("dec","%s",rname);
8380 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8382 freeAsmop(right,NULL,ic,TRUE);
8387 /*-----------------------------------------------------------------*/
8388 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8389 /*-----------------------------------------------------------------*/
8390 static void genPagedPointerSet (operand *right,
8399 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8401 retype= getSpec(operandType(right));
8403 aopOp(result,ic,FALSE);
8405 /* if the value is already in a pointer register
8406 then don't need anything more */
8407 if (!AOP_INPREG(AOP(result))) {
8408 /* otherwise get a free pointer register */
8410 preg = getFreePtr(ic,&aop,FALSE);
8411 pic14_emitcode("mov","%s,%s",
8413 aopGet(AOP(result),0,FALSE,TRUE));
8414 rname = preg->name ;
8416 rname = aopGet(AOP(result),0,FALSE,FALSE);
8418 freeAsmop(result,NULL,ic,TRUE);
8419 aopOp (right,ic,FALSE);
8421 /* if bitfield then unpack the bits */
8422 if (IS_BITVAR(retype))
8423 genPackBits (retype,right,rname,PPOINTER);
8425 /* we have can just get the values */
8426 int size = AOP_SIZE(right);
8430 l = aopGet(AOP(right),offset,FALSE,TRUE);
8433 pic14_emitcode("movx","@%s,a",rname);
8436 pic14_emitcode("inc","%s",rname);
8442 /* now some housekeeping stuff */
8444 /* we had to allocate for this iCode */
8445 freeAsmop(NULL,aop,ic,TRUE);
8447 /* we did not allocate which means left
8448 already in a pointer register, then
8449 if size > 0 && this could be used again
8450 we have to point it back to where it
8452 if (AOP_SIZE(right) > 1 &&
8453 !OP_SYMBOL(result)->remat &&
8454 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8456 int size = AOP_SIZE(right) - 1;
8458 pic14_emitcode("dec","%s",rname);
8463 freeAsmop(right,NULL,ic,TRUE);
8468 /*-----------------------------------------------------------------*/
8469 /* genFarPointerSet - set value from far space */
8470 /*-----------------------------------------------------------------*/
8471 static void genFarPointerSet (operand *right,
8472 operand *result, iCode *ic)
8475 sym_link *retype = getSpec(operandType(right));
8477 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8478 aopOp(result,ic,FALSE);
8480 /* if the operand is already in dptr
8481 then we do nothing else we move the value to dptr */
8482 if (AOP_TYPE(result) != AOP_STR) {
8483 /* if this is remateriazable */
8484 if (AOP_TYPE(result) == AOP_IMMD)
8485 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8486 else { /* we need to get it byte by byte */
8487 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8488 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8489 if (options.model == MODEL_FLAT24)
8491 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8495 /* so dptr know contains the address */
8496 freeAsmop(result,NULL,ic,TRUE);
8497 aopOp(right,ic,FALSE);
8499 /* if bit then unpack */
8500 if (IS_BITVAR(retype))
8501 genPackBits(retype,right,"dptr",FPOINTER);
8503 size = AOP_SIZE(right);
8507 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8509 pic14_emitcode("movx","@dptr,a");
8511 pic14_emitcode("inc","dptr");
8515 freeAsmop(right,NULL,ic,TRUE);
8518 /*-----------------------------------------------------------------*/
8519 /* genGenPointerSet - set value from generic pointer space */
8520 /*-----------------------------------------------------------------*/
8521 static void genGenPointerSet (operand *right,
8522 operand *result, iCode *ic)
8525 sym_link *retype = getSpec(operandType(right));
8527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8529 aopOp(result,ic,FALSE);
8530 aopOp(right,ic,FALSE);
8531 size = AOP_SIZE(right);
8533 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8535 /* if the operand is already in dptr
8536 then we do nothing else we move the value to dptr */
8537 if (AOP_TYPE(result) != AOP_STR) {
8538 /* if this is remateriazable */
8539 if (AOP_TYPE(result) == AOP_IMMD) {
8540 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8541 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8543 else { /* we need to get it byte by byte */
8544 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8545 size = AOP_SIZE(right);
8548 /* hack hack! see if this the FSR. If so don't load W */
8549 if(AOP_TYPE(right) != AOP_ACC) {
8551 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8552 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8555 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8557 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8558 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8562 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8563 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8566 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8573 if(aopIdx(AOP(result),0) != 4) {
8575 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8579 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8584 /* so dptr know contains the address */
8587 /* if bit then unpack */
8588 if (IS_BITVAR(retype))
8589 genPackBits(retype,right,"dptr",GPOINTER);
8591 size = AOP_SIZE(right);
8595 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8597 pic14_emitcode("incf","fsr,f");
8598 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8599 pic14_emitcode("movwf","indf");
8601 //DEBUGpic14_emitcode(";lcall","__gptrput");
8603 // pic14_emitcode("inc","dptr");
8608 freeAsmop(right,NULL,ic,TRUE);
8609 freeAsmop(result,NULL,ic,TRUE);
8612 /*-----------------------------------------------------------------*/
8613 /* genPointerSet - stores the value into a pointer location */
8614 /*-----------------------------------------------------------------*/
8615 static void genPointerSet (iCode *ic)
8617 operand *right, *result ;
8618 sym_link *type, *etype;
8621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8623 right = IC_RIGHT(ic);
8624 result = IC_RESULT(ic) ;
8626 /* depending on the type of pointer we need to
8627 move it to the correct pointer register */
8628 type = operandType(result);
8629 etype = getSpec(type);
8630 /* if left is of type of pointer then it is simple */
8631 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8632 p_type = DCL_TYPE(type);
8635 /* we have to go by the storage class */
8636 p_type = PTR_TYPE(SPEC_OCLS(etype));
8638 /* if (SPEC_OCLS(etype)->codesp ) { */
8639 /* p_type = CPOINTER ; */
8642 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8643 /* p_type = FPOINTER ; */
8645 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8646 /* p_type = PPOINTER ; */
8648 /* if (SPEC_OCLS(etype) == idata ) */
8649 /* p_type = IPOINTER ; */
8651 /* p_type = POINTER ; */
8654 /* now that we have the pointer type we assign
8655 the pointer values */
8660 genNearPointerSet (right,result,ic);
8664 genPagedPointerSet (right,result,ic);
8668 genFarPointerSet (right,result,ic);
8672 genGenPointerSet (right,result,ic);
8676 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8677 "genPointerSet: illegal pointer type");
8681 /*-----------------------------------------------------------------*/
8682 /* genIfx - generate code for Ifx statement */
8683 /*-----------------------------------------------------------------*/
8684 static void genIfx (iCode *ic, iCode *popIc)
8686 operand *cond = IC_COND(ic);
8689 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8691 aopOp(cond,ic,FALSE);
8693 /* get the value into acc */
8694 if (AOP_TYPE(cond) != AOP_CRY)
8695 pic14_toBoolean(cond);
8698 /* the result is now in the accumulator */
8699 freeAsmop(cond,NULL,ic,TRUE);
8701 /* if there was something to be popped then do it */
8705 /* if the condition is a bit variable */
8706 if (isbit && IS_ITEMP(cond) &&
8708 genIfxJump(ic,SPIL_LOC(cond)->rname);
8709 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
8712 if (isbit && !IS_ITEMP(cond))
8713 genIfxJump(ic,OP_SYMBOL(cond)->rname);
8721 /*-----------------------------------------------------------------*/
8722 /* genAddrOf - generates code for address of */
8723 /*-----------------------------------------------------------------*/
8724 static void genAddrOf (iCode *ic)
8726 operand *right, *result, *left;
8729 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8732 //aopOp(IC_RESULT(ic),ic,FALSE);
8734 aopOp((left=IC_LEFT(ic)),ic,FALSE);
8735 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
8736 aopOp((result=IC_RESULT(ic)),ic,TRUE);
8738 DEBUGpic14_AopType(__LINE__,left,right,result);
8740 size = AOP_SIZE(IC_RESULT(ic));
8744 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
8745 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8749 freeAsmop(left,NULL,ic,FALSE);
8750 freeAsmop(result,NULL,ic,TRUE);
8755 /*-----------------------------------------------------------------*/
8756 /* genFarFarAssign - assignment when both are in far space */
8757 /*-----------------------------------------------------------------*/
8758 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
8760 int size = AOP_SIZE(right);
8763 /* first push the right side on to the stack */
8765 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8767 pic14_emitcode ("push","acc");
8770 freeAsmop(right,NULL,ic,FALSE);
8771 /* now assign DPTR to result */
8772 aopOp(result,ic,FALSE);
8773 size = AOP_SIZE(result);
8775 pic14_emitcode ("pop","acc");
8776 aopPut(AOP(result),"a",--offset);
8778 freeAsmop(result,NULL,ic,FALSE);
8783 /*-----------------------------------------------------------------*/
8784 /* genAssign - generate code for assignment */
8785 /*-----------------------------------------------------------------*/
8786 static void genAssign (iCode *ic)
8788 operand *result, *right;
8789 int size, offset,know_W;
8790 unsigned long lit = 0L;
8792 result = IC_RESULT(ic);
8793 right = IC_RIGHT(ic) ;
8795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8797 /* if they are the same */
8798 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
8801 aopOp(right,ic,FALSE);
8802 aopOp(result,ic,TRUE);
8804 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8806 /* if they are the same registers */
8807 if (pic14_sameRegs(AOP(right),AOP(result)))
8810 /* if the result is a bit */
8811 if (AOP_TYPE(result) == AOP_CRY) {
8813 /* if the right size is a literal then
8814 we know what the value is */
8815 if (AOP_TYPE(right) == AOP_LIT) {
8817 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
8818 popGet(AOP(result),0));
8820 if (((int) operandLitValue(right)))
8821 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8822 AOP(result)->aopu.aop_dir,
8823 AOP(result)->aopu.aop_dir);
8825 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8826 AOP(result)->aopu.aop_dir,
8827 AOP(result)->aopu.aop_dir);
8831 /* the right is also a bit variable */
8832 if (AOP_TYPE(right) == AOP_CRY) {
8833 emitpcode(POC_BCF, popGet(AOP(result),0));
8834 emitpcode(POC_BTFSC, popGet(AOP(right),0));
8835 emitpcode(POC_BSF, popGet(AOP(result),0));
8837 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
8838 AOP(result)->aopu.aop_dir,
8839 AOP(result)->aopu.aop_dir);
8840 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
8841 AOP(right)->aopu.aop_dir,
8842 AOP(right)->aopu.aop_dir);
8843 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
8844 AOP(result)->aopu.aop_dir,
8845 AOP(result)->aopu.aop_dir);
8850 emitpcode(POC_BCF, popGet(AOP(result),0));
8851 pic14_toBoolean(right);
8853 emitpcode(POC_BSF, popGet(AOP(result),0));
8854 //aopPut(AOP(result),"a",0);
8858 /* bit variables done */
8860 size = AOP_SIZE(result);
8862 if(AOP_TYPE(right) == AOP_LIT)
8863 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
8865 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
8866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8867 if(aopIdx(AOP(result),0) == 4) {
8868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8869 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8870 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8873 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
8878 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8879 if(AOP_TYPE(right) == AOP_LIT) {
8881 if(know_W != (lit&0xff))
8882 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
8884 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8886 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8890 } else if (AOP_TYPE(right) == AOP_CRY) {
8891 emitpcode(POC_CLRF, popGet(AOP(result),offset));
8893 emitpcode(POC_BTFSS, popGet(AOP(right),0));
8894 emitpcode(POC_INCF, popGet(AOP(result),0));
8897 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8898 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8899 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8907 freeAsmop (right,NULL,ic,FALSE);
8908 freeAsmop (result,NULL,ic,TRUE);
8911 /*-----------------------------------------------------------------*/
8912 /* genJumpTab - genrates code for jump table */
8913 /*-----------------------------------------------------------------*/
8914 static void genJumpTab (iCode *ic)
8919 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8921 aopOp(IC_JTCOND(ic),ic,FALSE);
8922 /* get the condition into accumulator */
8923 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
8925 /* multiply by three */
8926 pic14_emitcode("add","a,acc");
8927 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
8929 jtab = newiTempLabel(NULL);
8930 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
8931 pic14_emitcode("jmp","@a+dptr");
8932 pic14_emitcode("","%05d_DS_:",jtab->key+100);
8934 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
8935 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
8937 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
8938 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
8939 emitpLabel(jtab->key);
8941 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
8943 /* now generate the jump labels */
8944 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
8945 jtab = setNextItem(IC_JTLABELS(ic))) {
8946 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
8947 emitpcode(POC_GOTO,popGetLabel(jtab->key));
8953 /*-----------------------------------------------------------------*/
8954 /* genMixedOperation - gen code for operators between mixed types */
8955 /*-----------------------------------------------------------------*/
8957 TSD - Written for the PIC port - but this unfortunately is buggy.
8958 This routine is good in that it is able to efficiently promote
8959 types to different (larger) sizes. Unfortunately, the temporary
8960 variables that are optimized out by this routine are sometimes
8961 used in other places. So until I know how to really parse the
8962 iCode tree, I'm going to not be using this routine :(.
8964 static int genMixedOperation (iCode *ic)
8967 operand *result = IC_RESULT(ic);
8968 sym_link *ctype = operandType(IC_LEFT(ic));
8969 operand *right = IC_RIGHT(ic);
8975 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
8977 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
8983 nextright = IC_RIGHT(nextic);
8984 nextleft = IC_LEFT(nextic);
8985 nextresult = IC_RESULT(nextic);
8987 aopOp(right,ic,FALSE);
8988 aopOp(result,ic,FALSE);
8989 aopOp(nextright, nextic, FALSE);
8990 aopOp(nextleft, nextic, FALSE);
8991 aopOp(nextresult, nextic, FALSE);
8993 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
8999 pic14_emitcode(";remove right +","");
9001 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9007 pic14_emitcode(";remove left +","");
9011 big = AOP_SIZE(nextleft);
9012 small = AOP_SIZE(nextright);
9014 switch(nextic->op) {
9017 pic14_emitcode(";optimize a +","");
9018 /* if unsigned or not an integral type */
9019 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9020 pic14_emitcode(";add a bit to something","");
9023 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9025 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9026 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9027 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9029 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9037 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9038 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9039 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9042 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9044 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9045 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9046 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9047 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9048 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9051 pic14_emitcode("rlf","known_zero,w");
9058 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9059 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9060 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9062 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9072 freeAsmop(right,NULL,ic,TRUE);
9073 freeAsmop(result,NULL,ic,TRUE);
9074 freeAsmop(nextright,NULL,ic,TRUE);
9075 freeAsmop(nextleft,NULL,ic,TRUE);
9077 nextic->generated = 1;
9084 /*-----------------------------------------------------------------*/
9085 /* genCast - gen code for casting */
9086 /*-----------------------------------------------------------------*/
9087 static void genCast (iCode *ic)
9089 operand *result = IC_RESULT(ic);
9090 sym_link *ctype = operandType(IC_LEFT(ic));
9091 sym_link *rtype = operandType(IC_RIGHT(ic));
9092 operand *right = IC_RIGHT(ic);
9095 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9096 /* if they are equivalent then do nothing */
9097 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9100 aopOp(right,ic,FALSE) ;
9101 aopOp(result,ic,FALSE);
9103 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9105 /* if the result is a bit */
9106 if (AOP_TYPE(result) == AOP_CRY) {
9107 /* if the right size is a literal then
9108 we know what the value is */
9109 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9110 if (AOP_TYPE(right) == AOP_LIT) {
9112 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9113 popGet(AOP(result),0));
9115 if (((int) operandLitValue(right)))
9116 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9117 AOP(result)->aopu.aop_dir,
9118 AOP(result)->aopu.aop_dir);
9120 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9121 AOP(result)->aopu.aop_dir,
9122 AOP(result)->aopu.aop_dir);
9127 /* the right is also a bit variable */
9128 if (AOP_TYPE(right) == AOP_CRY) {
9131 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9133 pic14_emitcode("clrc","");
9134 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9135 AOP(right)->aopu.aop_dir,
9136 AOP(right)->aopu.aop_dir);
9137 aopPut(AOP(result),"c",0);
9142 if (AOP_TYPE(right) == AOP_REG) {
9143 emitpcode(POC_BCF, popGet(AOP(result),0));
9144 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9145 emitpcode(POC_BSF, popGet(AOP(result),0));
9147 pic14_toBoolean(right);
9148 aopPut(AOP(result),"a",0);
9152 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9154 size = AOP_SIZE(result);
9156 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9158 emitpcode(POC_CLRF, popGet(AOP(result),0));
9159 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9160 emitpcode(POC_INCF, popGet(AOP(result),0));
9163 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9168 /* if they are the same size : or less */
9169 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9171 /* if they are in the same place */
9172 if (pic14_sameRegs(AOP(right),AOP(result)))
9175 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9176 if (IS_PTR_CONST(rtype))
9177 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9178 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9179 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9181 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9182 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9183 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9184 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9185 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9186 if(AOP_SIZE(result) <2)
9187 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9191 /* if they in different places then copy */
9192 size = AOP_SIZE(result);
9195 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9196 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9198 //aopPut(AOP(result),
9199 // aopGet(AOP(right),offset,FALSE,FALSE),
9209 /* if the result is of type pointer */
9210 if (IS_PTR(ctype)) {
9213 sym_link *type = operandType(right);
9214 sym_link *etype = getSpec(type);
9215 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9217 /* pointer to generic pointer */
9218 if (IS_GENPTR(ctype)) {
9222 p_type = DCL_TYPE(type);
9224 /* we have to go by the storage class */
9225 p_type = PTR_TYPE(SPEC_OCLS(etype));
9227 /* if (SPEC_OCLS(etype)->codesp ) */
9228 /* p_type = CPOINTER ; */
9230 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9231 /* p_type = FPOINTER ; */
9233 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9234 /* p_type = PPOINTER; */
9236 /* if (SPEC_OCLS(etype) == idata ) */
9237 /* p_type = IPOINTER ; */
9239 /* p_type = POINTER ; */
9242 /* the first two bytes are known */
9243 size = GPTRSIZE - 1;
9246 if(offset < AOP_SIZE(right))
9248 aopGet(AOP(right),offset,FALSE,FALSE),
9251 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9254 /* the last byte depending on type */
9258 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9261 pic14_emitcode(";BUG!? ","%d",__LINE__);
9265 pic14_emitcode(";BUG!? ","%d",__LINE__);
9269 pic14_emitcode(";BUG!? ","%d",__LINE__);
9274 /* this should never happen */
9275 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9276 "got unknown pointer type");
9279 //aopPut(AOP(result),l, GPTRSIZE - 1);
9283 /* just copy the pointers */
9284 size = AOP_SIZE(result);
9288 aopGet(AOP(right),offset,FALSE,FALSE),
9297 /* so we now know that the size of destination is greater
9298 than the size of the source.
9299 Now, if the next iCode is an operator then we might be
9300 able to optimize the operation without performing a cast.
9302 if(genMixedOperation(ic))
9305 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9307 /* we move to result for the size of source */
9308 size = AOP_SIZE(right);
9311 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9312 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9316 /* now depending on the sign of the destination */
9317 size = AOP_SIZE(result) - AOP_SIZE(right);
9318 /* if unsigned or not an integral type */
9319 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9321 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9323 /* we need to extend the sign :{ */
9326 /* Save one instruction of casting char to int */
9327 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9328 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9329 emitpcode(POC_DECF, popGet(AOP(result),offset));
9331 emitpcodeNULLop(POC_CLRW);
9334 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9336 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9338 emitpcode(POC_MOVLW, popGetLit(0xff));
9341 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9346 freeAsmop(right,NULL,ic,TRUE);
9347 freeAsmop(result,NULL,ic,TRUE);
9351 /*-----------------------------------------------------------------*/
9352 /* genDjnz - generate decrement & jump if not zero instrucion */
9353 /*-----------------------------------------------------------------*/
9354 static int genDjnz (iCode *ic, iCode *ifx)
9357 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9362 /* if the if condition has a false label
9363 then we cannot save */
9367 /* if the minus is not of the form
9369 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9370 !IS_OP_LITERAL(IC_RIGHT(ic)))
9373 if (operandLitValue(IC_RIGHT(ic)) != 1)
9376 /* if the size of this greater than one then no
9378 if (getSize(operandType(IC_RESULT(ic))) > 1)
9381 /* otherwise we can save BIG */
9382 lbl = newiTempLabel(NULL);
9383 lbl1= newiTempLabel(NULL);
9385 aopOp(IC_RESULT(ic),ic,FALSE);
9387 if (IS_AOP_PREG(IC_RESULT(ic))) {
9388 pic14_emitcode("dec","%s",
9389 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9390 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9391 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9395 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9396 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9398 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9399 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9402 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9403 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9404 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9405 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9408 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9413 /*-----------------------------------------------------------------*/
9414 /* genReceive - generate code for a receive iCode */
9415 /*-----------------------------------------------------------------*/
9416 static void genReceive (iCode *ic)
9418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9420 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9421 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9422 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9424 int size = getSize(operandType(IC_RESULT(ic)));
9425 int offset = fReturnSizePic - size;
9427 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9428 fReturn[fReturnSizePic - offset - 1] : "acc"));
9431 aopOp(IC_RESULT(ic),ic,FALSE);
9432 size = AOP_SIZE(IC_RESULT(ic));
9435 pic14_emitcode ("pop","acc");
9436 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9441 aopOp(IC_RESULT(ic),ic,FALSE);
9443 assignResultValue(IC_RESULT(ic));
9446 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9449 /*-----------------------------------------------------------------*/
9450 /* genpic14Code - generate code for pic14 based controllers */
9451 /*-----------------------------------------------------------------*/
9453 * At this point, ralloc.c has gone through the iCode and attempted
9454 * to optimize in a way suitable for a PIC. Now we've got to generate
9455 * PIC instructions that correspond to the iCode.
9457 * Once the instructions are generated, we'll pass through both the
9458 * peep hole optimizer and the pCode optimizer.
9459 *-----------------------------------------------------------------*/
9461 void genpic14Code (iCode *lic)
9466 lineHead = lineCurr = NULL;
9468 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9471 /* if debug information required */
9472 if (options.debug && currFunc) {
9474 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9476 if (IS_STATIC(currFunc->etype)) {
9477 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9478 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9480 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9481 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9488 for (ic = lic ; ic ; ic = ic->next ) {
9490 DEBUGpic14_emitcode(";ic","");
9491 if ( cln != ic->lineno ) {
9492 if ( options.debug ) {
9494 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9495 FileBaseName(ic->filename),ic->lineno,
9496 ic->level,ic->block);
9499 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9500 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9501 printCLine(ic->filename, ic->lineno));
9505 /* if the result is marked as
9506 spilt and rematerializable or code for
9507 this has already been generated then
9509 if (resultRemat(ic) || ic->generated )
9512 /* depending on the operation */
9531 /* IPOP happens only when trying to restore a
9532 spilt live range, if there is an ifx statement
9533 following this pop then the if statement might
9534 be using some of the registers being popped which
9535 would destory the contents of the register so
9536 we need to check for this condition and handle it */
9538 ic->next->op == IFX &&
9539 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9540 genIfx (ic->next,ic);
9558 genEndFunction (ic);
9578 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9595 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9599 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9606 /* note these two are xlated by algebraic equivalence
9607 during parsing SDCC.y */
9608 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9609 "got '>=' or '<=' shouldn't have come here");
9613 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9625 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9629 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9633 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9660 case GET_VALUE_AT_ADDRESS:
9665 if (POINTER_SET(ic))
9692 addSet(&_G.sendSet,ic);
9701 /* now we are ready to call the
9702 peep hole optimizer */
9703 if (!options.nopeep) {
9704 peepHole (&lineHead);
9706 /* now do the actual printing */
9707 printLine (lineHead,codeOutFile);
9710 DFPRINTF((stderr,"printing pBlock\n\n"));
9711 printpBlock(stdout,pb);