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