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__);
591 if(IS_OP_POINTER(op)) {
592 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
596 val += (int) operandLitValue(IC_RIGHT(ic));
597 } else if (ic->op == '-') {
598 val -= (int) operandLitValue(IC_RIGHT(ic));
602 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
605 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
606 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
607 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
608 PCOI(aop->aopu.pcop)->index = val;
610 DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d",
611 OP_SYMBOL(IC_LEFT(ic))->rname,
612 val, IS_PTR_CONST(operandType(op)));
614 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
616 allocDirReg (IC_LEFT(ic));
621 int aopIdx (asmop *aop, int offset)
626 if(aop->type != AOP_REG)
629 return aop->aopu.aop_reg[offset]->rIdx;
632 /*-----------------------------------------------------------------*/
633 /* regsInCommon - two operands have some registers in common */
634 /*-----------------------------------------------------------------*/
635 static bool regsInCommon (operand *op1, operand *op2)
640 /* if they have registers in common */
641 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
644 sym1 = OP_SYMBOL(op1);
645 sym2 = OP_SYMBOL(op2);
647 if (sym1->nRegs == 0 || sym2->nRegs == 0)
650 for (i = 0 ; i < sym1->nRegs ; i++) {
655 for (j = 0 ; j < sym2->nRegs ;j++ ) {
659 if (sym2->regs[j] == sym1->regs[i])
667 /*-----------------------------------------------------------------*/
668 /* operandsEqu - equivalent */
669 /*-----------------------------------------------------------------*/
670 static bool operandsEqu ( operand *op1, operand *op2)
674 /* if they not symbols */
675 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
678 sym1 = OP_SYMBOL(op1);
679 sym2 = OP_SYMBOL(op2);
681 /* if both are itemps & one is spilt
682 and the other is not then false */
683 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
684 sym1->isspilt != sym2->isspilt )
687 /* if they are the same */
691 if (strcmp(sym1->rname,sym2->rname) == 0)
695 /* if left is a tmp & right is not */
699 (sym1->usl.spillLoc == sym2))
706 (sym2->usl.spillLoc == sym1))
712 /*-----------------------------------------------------------------*/
713 /* pic14_sameRegs - two asmops have the same registers */
714 /*-----------------------------------------------------------------*/
715 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
722 if (aop1->type != AOP_REG ||
723 aop2->type != AOP_REG )
726 if (aop1->size != aop2->size )
729 for (i = 0 ; i < aop1->size ; i++ )
730 if (aop1->aopu.aop_reg[i] !=
731 aop2->aopu.aop_reg[i] )
737 /*-----------------------------------------------------------------*/
738 /* aopOp - allocates an asmop for an operand : */
739 /*-----------------------------------------------------------------*/
740 void aopOp (operand *op, iCode *ic, bool result)
749 // DEBUGpic14_emitcode(";","%d",__LINE__);
750 /* if this a literal */
751 if (IS_OP_LITERAL(op)) {
752 op->aop = aop = newAsmop(AOP_LIT);
753 aop->aopu.aop_lit = op->operand.valOperand;
754 aop->size = getSize(operandType(op));
759 sym_link *type = operandType(op);
760 if(IS_PTR_CONST(type))
761 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
764 /* if already has a asmop then continue */
768 /* if the underlying symbol has a aop */
769 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
770 DEBUGpic14_emitcode(";","%d",__LINE__);
771 op->aop = OP_SYMBOL(op)->aop;
775 /* if this is a true symbol */
776 if (IS_TRUE_SYMOP(op)) {
777 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
778 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
782 /* this is a temporary : this has
788 e) can be a return use only */
793 /* if the type is a conditional */
794 if (sym->regType == REG_CND) {
795 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
800 /* if it is spilt then two situations
802 b) has a spill location */
803 if (sym->isspilt || sym->nRegs == 0) {
805 DEBUGpic14_emitcode(";","%d",__LINE__);
806 /* rematerialize it NOW */
809 sym->aop = op->aop = aop =
811 aop->size = getSize(sym->type);
812 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
818 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
819 aop->size = getSize(sym->type);
820 for ( i = 0 ; i < 2 ; i++ )
821 aop->aopu.aop_str[i] = accUse[i];
822 DEBUGpic14_emitcode(";","%d",__LINE__);
828 aop = op->aop = sym->aop = newAsmop(AOP_STR);
829 aop->size = getSize(sym->type);
830 for ( i = 0 ; i < fReturnSizePic ; i++ )
831 aop->aopu.aop_str[i] = fReturn[i];
832 DEBUGpic14_emitcode(";","%d",__LINE__);
836 /* else spill location */
837 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
838 /* force a new aop if sizes differ */
839 sym->usl.spillLoc->aop = NULL;
841 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
842 __FUNCTION__,__LINE__,
843 sym->usl.spillLoc->rname,
844 sym->rname, sym->usl.spillLoc->offset);
845 // X sym->aop = op->aop = aop = aopForSym(ic,sym->usl.spillLoc,result);
846 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
847 aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
848 //allocDirReg (IC_LEFT(ic));
849 aop->size = getSize(sym->type);
855 sym_link *type = operandType(op);
856 if(IS_PTR_CONST(type))
857 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
860 /* must be in a register */
861 sym->aop = op->aop = aop = newAsmop(AOP_REG);
862 aop->size = sym->nRegs;
863 for ( i = 0 ; i < sym->nRegs ;i++)
864 aop->aopu.aop_reg[i] = sym->regs[i];
867 /*-----------------------------------------------------------------*/
868 /* freeAsmop - free up the asmop given to an operand */
869 /*----------------------------------------------------------------*/
870 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
887 /* depending on the asmop type only three cases need work AOP_RO
888 , AOP_R1 && AOP_STK */
894 pic14_emitcode ("pop","ar0");
898 bitVectUnSetBit(ic->rUsed,R0_IDX);
904 pic14_emitcode ("pop","ar1");
908 bitVectUnSetBit(ic->rUsed,R1_IDX);
914 int stk = aop->aopu.aop_stk + aop->size;
915 bitVectUnSetBit(ic->rUsed,R0_IDX);
916 bitVectUnSetBit(ic->rUsed,R1_IDX);
918 getFreePtr(ic,&aop,FALSE);
920 if (options.stack10bit)
922 /* I'm not sure what to do here yet... */
925 "*** Warning: probably generating bad code for "
926 "10 bit stack mode.\n");
930 pic14_emitcode ("mov","a,_bp");
931 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
932 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
934 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
938 pic14_emitcode("pop","acc");
939 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
941 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
944 freeAsmop(op,NULL,ic,TRUE);
946 pic14_emitcode("pop","ar0");
951 pic14_emitcode("pop","ar1");
959 /* all other cases just dealloc */
963 OP_SYMBOL(op)->aop = NULL;
964 /* if the symbol has a spill */
966 SPIL_LOC(op)->aop = NULL;
971 /*-----------------------------------------------------------------*/
972 /* aopGet - for fetching value of the aop */
973 /*-----------------------------------------------------------------*/
974 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
979 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
980 /* offset is greater than
982 if (offset > (aop->size - 1) &&
983 aop->type != AOP_LIT)
986 /* depending on type */
991 DEBUGpic14_emitcode(";","%d",__LINE__);
992 /* if we need to increment it */
993 while (offset > aop->coff) {
994 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
998 while (offset < aop->coff) {
999 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1003 aop->coff = offset ;
1005 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1006 return (dname ? "acc" : "a");
1008 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1009 rs = Safe_calloc(1,strlen(s)+1);
1015 DEBUGpic14_emitcode(";","%d",__LINE__);
1016 if (aop->type == AOP_DPTR2)
1021 while (offset > aop->coff) {
1022 pic14_emitcode ("inc","dptr");
1026 while (offset < aop->coff) {
1027 pic14_emitcode("lcall","__decdptr");
1033 pic14_emitcode("clr","a");
1034 pic14_emitcode("movc","a,@a+dptr");
1037 pic14_emitcode("movx","a,@dptr");
1040 if (aop->type == AOP_DPTR2)
1045 return (dname ? "acc" : "a");
1050 sprintf (s,"%s",aop->aopu.aop_immd);
1053 sprintf(s,"(%s >> %d)",
1058 aop->aopu.aop_immd);
1059 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1060 rs = Safe_calloc(1,strlen(s)+1);
1066 sprintf(s,"(%s + %d)",
1069 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1071 sprintf(s,"%s",aop->aopu.aop_dir);
1072 rs = Safe_calloc(1,strlen(s)+1);
1078 // return aop->aopu.aop_reg[offset]->dname;
1080 return aop->aopu.aop_reg[offset]->name;
1083 //pic14_emitcode(";","%d",__LINE__);
1084 return aop->aopu.aop_dir;
1087 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1088 return "AOP_accumulator_bug";
1091 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1092 rs = Safe_calloc(1,strlen(s)+1);
1097 DEBUGpic14_emitcode(";","%d",__LINE__);
1098 aop->coff = offset ;
1099 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1103 return aop->aopu.aop_str[offset];
1107 pCodeOp *pcop = aop->aopu.pcop;
1108 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE",__LINE__);
1110 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1111 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1112 sprintf(s,"%s", pcop->name);
1114 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1117 rs = Safe_calloc(1,strlen(s)+1);
1123 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1124 "aopget got unsupported aop->type");
1129 /*-----------------------------------------------------------------*/
1130 /* popGetTempReg - create a new temporary pCodeOp */
1131 /*-----------------------------------------------------------------*/
1132 pCodeOp *popGetTempReg(void)
1137 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1138 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1139 PCOR(pcop)->r->wasUsed=1;
1140 PCOR(pcop)->r->isFree=0;
1146 /*-----------------------------------------------------------------*/
1147 /* popGetTempReg - create a new temporary pCodeOp */
1148 /*-----------------------------------------------------------------*/
1149 void popReleaseTempReg(pCodeOp *pcop)
1152 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1153 PCOR(pcop)->r->isFree = 1;
1156 /*-----------------------------------------------------------------*/
1157 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1158 /*-----------------------------------------------------------------*/
1159 pCodeOp *popGetLabel(unsigned int key)
1162 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1167 return newpCodeOpLabel(NULL,key+100+labelOffset);
1170 /*-----------------------------------------------------------------*/
1171 /* popCopyReg - copy a pcode operator */
1172 /*-----------------------------------------------------------------*/
1173 pCodeOp *popCopyReg(pCodeOpReg *pc)
1177 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1178 pcor->pcop.type = pc->pcop.type;
1180 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1181 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1183 pcor->pcop.name = NULL;
1186 pcor->rIdx = pc->rIdx;
1189 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1193 /*-----------------------------------------------------------------*/
1194 /* popGet - asm operator to pcode operator conversion */
1195 /*-----------------------------------------------------------------*/
1196 pCodeOp *popGetLit(unsigned int lit)
1199 return newpCodeOpLit(lit);
1203 /*-----------------------------------------------------------------*/
1204 /* popGetImmd - asm operator to pcode immediate conversion */
1205 /*-----------------------------------------------------------------*/
1206 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1209 return newpCodeOpImmd(name, offset,index, 0);
1213 /*-----------------------------------------------------------------*/
1214 /* popGet - asm operator to pcode operator conversion */
1215 /*-----------------------------------------------------------------*/
1216 pCodeOp *popGetWithString(char *str)
1222 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1226 pcop = newpCodeOp(str,PO_STR);
1231 pCodeOp *popRegFromString(char *str)
1234 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOp) );
1235 pcop->type = PO_DIR;
1237 DEBUGpic14_emitcode(";","%d",__LINE__);
1238 pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1243 pCodeOp *popRegFromIdx(int rIdx)
1247 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1248 __FUNCTION__,__LINE__,rIdx);
1250 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1252 PCOR(pcop)->rIdx = rIdx;
1253 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1254 PCOR(pcop)->r->isFree = 0;
1255 PCOR(pcop)->r->wasUsed = 1;
1257 pcop->type = PCOR(pcop)->r->pc_type;
1262 /*-----------------------------------------------------------------*/
1263 /* popGet - asm operator to pcode operator conversion */
1264 /*-----------------------------------------------------------------*/
1265 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1267 //char *s = buffer ;
1272 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1273 /* offset is greater than
1276 if (offset > (aop->size - 1) &&
1277 aop->type != AOP_LIT)
1278 return NULL; //zero;
1280 /* depending on type */
1281 switch (aop->type) {
1288 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1292 DEBUGpic14_emitcode(";","%d",__LINE__);
1293 return popGetImmd(aop->aopu.aop_immd,offset,0);
1296 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1297 pcop->type = PO_DIR;
1301 sprintf(s,"(%s + %d)",
1305 sprintf(s,"%s",aop->aopu.aop_dir);
1306 pcop->name = Safe_calloc(1,strlen(s)+1);
1307 strcpy(pcop->name,s);
1309 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1310 strcpy(pcop->name,aop->aopu.aop_dir);
1311 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1312 if(PCOR(pcop)->r == NULL) {
1313 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1314 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1317 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1318 PCOR(pcop)->instance = offset;
1324 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1326 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1327 PCOR(pcop)->rIdx = rIdx;
1328 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1329 PCOR(pcop)->instance = offset;
1330 pcop->type = PCOR(pcop)->r->pc_type;
1331 //rs = aop->aopu.aop_reg[offset]->name;
1332 //DEBUGpic14_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs);
1337 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1338 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1339 //if(PCOR(pcop)->r == NULL)
1340 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1344 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1347 DEBUGpic14_emitcode(";","%d",__LINE__);
1348 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1350 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1351 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1352 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1353 pcop->type = PCOR(pcop)->r->pc_type;
1354 pcop->name = PCOR(pcop)->r->name;
1360 DEBUGpic14_emitcode(";","popGet AOP_PCODE%d",__LINE__);
1361 pcop = pCodeOpCopy(aop->aopu.pcop);
1362 PCOI(pcop)->offset = offset;
1366 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1367 "popGet got unsupported aop->type");
1370 /*-----------------------------------------------------------------*/
1371 /* aopPut - puts a string for a aop */
1372 /*-----------------------------------------------------------------*/
1373 void aopPut (asmop *aop, char *s, int offset)
1378 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1380 if (aop->size && offset > ( aop->size - 1)) {
1381 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1382 "aopPut got offset > aop->size");
1386 /* will assign value to value */
1387 /* depending on where it is ofcourse */
1388 switch (aop->type) {
1391 sprintf(d,"(%s + %d)",
1392 aop->aopu.aop_dir,offset);
1393 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1396 sprintf(d,"%s",aop->aopu.aop_dir);
1399 DEBUGpic14_emitcode(";","%d",__LINE__);
1401 pic14_emitcode("movf","%s,w",s);
1402 pic14_emitcode("movwf","%s",d);
1405 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1406 if(offset >= aop->size) {
1407 emitpcode(POC_CLRF,popGet(aop,offset));
1410 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1413 emitpcode(POC_MOVWF,popGet(aop,offset));
1420 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1421 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1424 strcmp(s,"r0") == 0 ||
1425 strcmp(s,"r1") == 0 ||
1426 strcmp(s,"r2") == 0 ||
1427 strcmp(s,"r3") == 0 ||
1428 strcmp(s,"r4") == 0 ||
1429 strcmp(s,"r5") == 0 ||
1430 strcmp(s,"r6") == 0 ||
1431 strcmp(s,"r7") == 0 )
1432 pic14_emitcode("mov","%s,%s ; %d",
1433 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1437 if(strcmp(s,"W")==0 )
1438 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1440 pic14_emitcode("movwf","%s",
1441 aop->aopu.aop_reg[offset]->name);
1443 if(strcmp(s,zero)==0) {
1444 emitpcode(POC_CLRF,popGet(aop,offset));
1446 } else if(strcmp(s,"W")==0) {
1447 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1448 pcop->type = PO_GPR_REGISTER;
1450 PCOR(pcop)->rIdx = -1;
1451 PCOR(pcop)->r = NULL;
1453 DEBUGpic14_emitcode(";","%d",__LINE__);
1454 pcop->name = Safe_strdup(s);
1455 emitpcode(POC_MOVFW,pcop);
1456 emitpcode(POC_MOVWF,popGet(aop,offset));
1457 } else if(strcmp(s,one)==0) {
1458 emitpcode(POC_CLRF,popGet(aop,offset));
1459 emitpcode(POC_INCF,popGet(aop,offset));
1461 emitpcode(POC_MOVWF,popGet(aop,offset));
1469 if (aop->type == AOP_DPTR2)
1475 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1476 "aopPut writting to code space");
1480 while (offset > aop->coff) {
1482 pic14_emitcode ("inc","dptr");
1485 while (offset < aop->coff) {
1487 pic14_emitcode("lcall","__decdptr");
1492 /* if not in accumulater */
1495 pic14_emitcode ("movx","@dptr,a");
1497 if (aop->type == AOP_DPTR2)
1505 while (offset > aop->coff) {
1507 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1509 while (offset < aop->coff) {
1511 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1517 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1522 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1524 if (strcmp(s,"r0") == 0 ||
1525 strcmp(s,"r1") == 0 ||
1526 strcmp(s,"r2") == 0 ||
1527 strcmp(s,"r3") == 0 ||
1528 strcmp(s,"r4") == 0 ||
1529 strcmp(s,"r5") == 0 ||
1530 strcmp(s,"r6") == 0 ||
1531 strcmp(s,"r7") == 0 ) {
1533 sprintf(buffer,"a%s",s);
1534 pic14_emitcode("mov","@%s,%s",
1535 aop->aopu.aop_ptr->name,buffer);
1537 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1542 if (strcmp(s,"a") == 0)
1543 pic14_emitcode("push","acc");
1545 pic14_emitcode("push","%s",s);
1550 /* if bit variable */
1551 if (!aop->aopu.aop_dir) {
1552 pic14_emitcode("clr","a");
1553 pic14_emitcode("rlc","a");
1556 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1559 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1562 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1564 lbl = newiTempLabel(NULL);
1566 if (strcmp(s,"a")) {
1569 pic14_emitcode("clr","c");
1570 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1571 pic14_emitcode("cpl","c");
1572 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1573 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1580 if (strcmp(aop->aopu.aop_str[offset],s))
1581 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1586 if (!offset && (strcmp(s,"acc") == 0))
1589 if (strcmp(aop->aopu.aop_str[offset],s))
1590 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1594 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1595 "aopPut got unsupported aop->type");
1601 /*-----------------------------------------------------------------*/
1602 /* reAdjustPreg - points a register back to where it should */
1603 /*-----------------------------------------------------------------*/
1604 static void reAdjustPreg (asmop *aop)
1608 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1610 if ((size = aop->size) <= 1)
1613 switch (aop->type) {
1617 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1621 if (aop->type == AOP_DPTR2)
1627 pic14_emitcode("lcall","__decdptr");
1630 if (aop->type == AOP_DPTR2)
1640 /*-----------------------------------------------------------------*/
1641 /* genNotFloat - generates not for float operations */
1642 /*-----------------------------------------------------------------*/
1643 static void genNotFloat (operand *op, operand *res)
1649 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1650 /* we will put 127 in the first byte of
1652 aopPut(AOP(res),"#127",0);
1653 size = AOP_SIZE(op) - 1;
1656 l = aopGet(op->aop,offset++,FALSE,FALSE);
1660 pic14_emitcode("orl","a,%s",
1662 offset++,FALSE,FALSE));
1664 tlbl = newiTempLabel(NULL);
1666 tlbl = newiTempLabel(NULL);
1667 aopPut(res->aop,one,1);
1668 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1669 aopPut(res->aop,zero,1);
1670 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1672 size = res->aop->size - 2;
1674 /* put zeros in the rest */
1676 aopPut(res->aop,zero,offset++);
1680 /*-----------------------------------------------------------------*/
1681 /* opIsGptr: returns non-zero if the passed operand is */
1682 /* a generic pointer type. */
1683 /*-----------------------------------------------------------------*/
1684 static int opIsGptr(operand *op)
1686 sym_link *type = operandType(op);
1688 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1689 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1697 /*-----------------------------------------------------------------*/
1698 /* pic14_getDataSize - get the operand data size */
1699 /*-----------------------------------------------------------------*/
1700 int pic14_getDataSize(operand *op)
1702 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1705 return AOP_SIZE(op);
1707 // tsd- in the pic port, the genptr size is 1, so this code here
1708 // fails. ( in the 8051 port, the size was 4).
1711 size = AOP_SIZE(op);
1712 if (size == GPTRSIZE)
1714 sym_link *type = operandType(op);
1715 if (IS_GENPTR(type))
1717 /* generic pointer; arithmetic operations
1718 * should ignore the high byte (pointer type).
1721 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1728 /*-----------------------------------------------------------------*/
1729 /* pic14_outAcc - output Acc */
1730 /*-----------------------------------------------------------------*/
1731 void pic14_outAcc(operand *result)
1734 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1735 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1738 size = pic14_getDataSize(result);
1740 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1743 /* unsigned or positive */
1745 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1750 /*-----------------------------------------------------------------*/
1751 /* pic14_outBitC - output a bit C */
1752 /*-----------------------------------------------------------------*/
1753 void pic14_outBitC(operand *result)
1756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1757 /* if the result is bit */
1758 if (AOP_TYPE(result) == AOP_CRY)
1759 aopPut(AOP(result),"c",0);
1761 pic14_emitcode("clr","a ; %d", __LINE__);
1762 pic14_emitcode("rlc","a");
1763 pic14_outAcc(result);
1767 /*-----------------------------------------------------------------*/
1768 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1769 /*-----------------------------------------------------------------*/
1770 void pic14_toBoolean(operand *oper)
1772 int size = AOP_SIZE(oper) - 1;
1775 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1777 if ( AOP_TYPE(oper) != AOP_ACC) {
1778 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1781 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1786 /*-----------------------------------------------------------------*/
1787 /* genNot - generate code for ! operation */
1788 /*-----------------------------------------------------------------*/
1789 static void genNot (iCode *ic)
1792 sym_link *optype = operandType(IC_LEFT(ic));
1795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1796 /* assign asmOps to operand & result */
1797 aopOp (IC_LEFT(ic),ic,FALSE);
1798 aopOp (IC_RESULT(ic),ic,TRUE);
1800 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1801 /* if in bit space then a special case */
1802 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1803 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1804 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1805 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1807 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1808 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1809 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1814 /* if type float then do float */
1815 if (IS_FLOAT(optype)) {
1816 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1820 size = AOP_SIZE(IC_RESULT(ic));
1822 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1823 emitpcode(POC_ANDLW,popGetLit(1));
1824 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1827 pic14_toBoolean(IC_LEFT(ic));
1829 tlbl = newiTempLabel(NULL);
1830 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1831 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1832 pic14_outBitC(IC_RESULT(ic));
1835 /* release the aops */
1836 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1837 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1841 /*-----------------------------------------------------------------*/
1842 /* genCpl - generate code for complement */
1843 /*-----------------------------------------------------------------*/
1844 static void genCpl (iCode *ic)
1850 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1851 /* assign asmOps to operand & result */
1852 aopOp (IC_LEFT(ic),ic,FALSE);
1853 aopOp (IC_RESULT(ic),ic,TRUE);
1855 /* if both are in bit space then
1857 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1858 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1860 pic14_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
1861 pic14_emitcode("cpl","c");
1862 pic14_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
1866 size = AOP_SIZE(IC_RESULT(ic));
1868 char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
1870 pic14_emitcode("cpl","a");
1871 aopPut(AOP(IC_RESULT(ic)),"a",offset++);
1876 /* release the aops */
1877 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1878 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1881 /*-----------------------------------------------------------------*/
1882 /* genUminusFloat - unary minus for floating points */
1883 /*-----------------------------------------------------------------*/
1884 static void genUminusFloat(operand *op,operand *result)
1886 int size ,offset =0 ;
1889 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1890 /* for this we just need to flip the
1891 first it then copy the rest in place */
1892 size = AOP_SIZE(op) - 1;
1893 l = aopGet(AOP(op),3,FALSE,FALSE);
1897 pic14_emitcode("cpl","acc.7");
1898 aopPut(AOP(result),"a",3);
1902 aopGet(AOP(op),offset,FALSE,FALSE),
1908 /*-----------------------------------------------------------------*/
1909 /* genUminus - unary minus code generation */
1910 /*-----------------------------------------------------------------*/
1911 static void genUminus (iCode *ic)
1914 sym_link *optype, *rtype;
1917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1919 aopOp(IC_LEFT(ic),ic,FALSE);
1920 aopOp(IC_RESULT(ic),ic,TRUE);
1922 /* if both in bit space then special
1924 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1925 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1927 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1928 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1929 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1934 optype = operandType(IC_LEFT(ic));
1935 rtype = operandType(IC_RESULT(ic));
1937 /* if float then do float stuff */
1938 if (IS_FLOAT(optype)) {
1939 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1943 /* otherwise subtract from zero by taking the 2's complement */
1944 size = AOP_SIZE(IC_LEFT(ic));
1946 for(i=0; i<size; i++) {
1947 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1948 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1950 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1951 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1955 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1956 for(i=1; i<size; i++) {
1958 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1962 /* release the aops */
1963 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1964 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1967 /*-----------------------------------------------------------------*/
1968 /* saveRegisters - will look for a call and save the registers */
1969 /*-----------------------------------------------------------------*/
1970 static void saveRegisters(iCode *lic)
1977 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1979 for (ic = lic ; ic ; ic = ic->next)
1980 if (ic->op == CALL || ic->op == PCALL)
1984 fprintf(stderr,"found parameter push with no function call\n");
1988 /* if the registers have been saved already then
1990 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
1993 /* find the registers in use at this time
1994 and push them away to safety */
1995 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
1999 if (options.useXstack) {
2000 if (bitVectBitValue(rsave,R0_IDX))
2001 pic14_emitcode("mov","b,r0");
2002 pic14_emitcode("mov","r0,%s",spname);
2003 for (i = 0 ; i < pic14_nRegs ; i++) {
2004 if (bitVectBitValue(rsave,i)) {
2006 pic14_emitcode("mov","a,b");
2008 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2009 pic14_emitcode("movx","@r0,a");
2010 pic14_emitcode("inc","r0");
2013 pic14_emitcode("mov","%s,r0",spname);
2014 if (bitVectBitValue(rsave,R0_IDX))
2015 pic14_emitcode("mov","r0,b");
2017 //for (i = 0 ; i < pic14_nRegs ; i++) {
2018 // if (bitVectBitValue(rsave,i))
2019 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2022 dtype = operandType(IC_LEFT(ic));
2023 if (currFunc && dtype &&
2024 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2025 IFFUNC_ISISR(currFunc->type) &&
2028 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2031 /*-----------------------------------------------------------------*/
2032 /* unsaveRegisters - pop the pushed registers */
2033 /*-----------------------------------------------------------------*/
2034 static void unsaveRegisters (iCode *ic)
2039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2040 /* find the registers in use at this time
2041 and push them away to safety */
2042 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2045 if (options.useXstack) {
2046 pic14_emitcode("mov","r0,%s",spname);
2047 for (i = pic14_nRegs ; i >= 0 ; i--) {
2048 if (bitVectBitValue(rsave,i)) {
2049 pic14_emitcode("dec","r0");
2050 pic14_emitcode("movx","a,@r0");
2052 pic14_emitcode("mov","b,a");
2054 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2058 pic14_emitcode("mov","%s,r0",spname);
2059 if (bitVectBitValue(rsave,R0_IDX))
2060 pic14_emitcode("mov","r0,b");
2062 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2063 // if (bitVectBitValue(rsave,i))
2064 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2070 /*-----------------------------------------------------------------*/
2072 /*-----------------------------------------------------------------*/
2073 static void pushSide(operand * oper, int size)
2077 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2079 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2080 if (AOP_TYPE(oper) != AOP_REG &&
2081 AOP_TYPE(oper) != AOP_DIR &&
2083 pic14_emitcode("mov","a,%s",l);
2084 pic14_emitcode("push","acc");
2086 pic14_emitcode("push","%s",l);
2091 /*-----------------------------------------------------------------*/
2092 /* assignResultValue - */
2093 /*-----------------------------------------------------------------*/
2094 static void assignResultValue(operand * oper)
2096 int size = AOP_SIZE(oper);
2098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2100 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2102 if(!GpsuedoStkPtr) {
2103 /* The last byte in the assignment is in W */
2105 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2110 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2112 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2117 /*-----------------------------------------------------------------*/
2118 /* genIpush - genrate code for pushing this gets a little complex */
2119 /*-----------------------------------------------------------------*/
2120 static void genIpush (iCode *ic)
2123 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2125 int size, offset = 0 ;
2129 /* if this is not a parm push : ie. it is spill push
2130 and spill push is always done on the local stack */
2131 if (!ic->parmPush) {
2133 /* and the item is spilt then do nothing */
2134 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2137 aopOp(IC_LEFT(ic),ic,FALSE);
2138 size = AOP_SIZE(IC_LEFT(ic));
2139 /* push it on the stack */
2141 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2146 pic14_emitcode("push","%s",l);
2151 /* this is a paramter push: in this case we call
2152 the routine to find the call and save those
2153 registers that need to be saved */
2156 /* then do the push */
2157 aopOp(IC_LEFT(ic),ic,FALSE);
2160 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2161 size = AOP_SIZE(IC_LEFT(ic));
2164 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2165 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2166 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2168 pic14_emitcode("mov","a,%s",l);
2169 pic14_emitcode("push","acc");
2171 pic14_emitcode("push","%s",l);
2174 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2178 /*-----------------------------------------------------------------*/
2179 /* genIpop - recover the registers: can happen only for spilling */
2180 /*-----------------------------------------------------------------*/
2181 static void genIpop (iCode *ic)
2183 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2188 /* if the temp was not pushed then */
2189 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2192 aopOp(IC_LEFT(ic),ic,FALSE);
2193 size = AOP_SIZE(IC_LEFT(ic));
2196 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2199 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2203 /*-----------------------------------------------------------------*/
2204 /* unsaverbank - restores the resgister bank from stack */
2205 /*-----------------------------------------------------------------*/
2206 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2208 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2214 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2216 if (options.useXstack) {
2218 r = getFreePtr(ic,&aop,FALSE);
2221 pic14_emitcode("mov","%s,_spx",r->name);
2222 pic14_emitcode("movx","a,@%s",r->name);
2223 pic14_emitcode("mov","psw,a");
2224 pic14_emitcode("dec","%s",r->name);
2227 pic14_emitcode ("pop","psw");
2230 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2231 if (options.useXstack) {
2232 pic14_emitcode("movx","a,@%s",r->name);
2233 //pic14_emitcode("mov","(%s+%d),a",
2234 // regspic14[i].base,8*bank+regspic14[i].offset);
2235 pic14_emitcode("dec","%s",r->name);
2238 pic14_emitcode("pop",""); //"(%s+%d)",
2239 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2242 if (options.useXstack) {
2244 pic14_emitcode("mov","_spx,%s",r->name);
2245 freeAsmop(NULL,aop,ic,TRUE);
2251 /*-----------------------------------------------------------------*/
2252 /* saverbank - saves an entire register bank on the stack */
2253 /*-----------------------------------------------------------------*/
2254 static void saverbank (int bank, iCode *ic, bool pushPsw)
2256 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2262 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2263 if (options.useXstack) {
2266 r = getFreePtr(ic,&aop,FALSE);
2267 pic14_emitcode("mov","%s,_spx",r->name);
2271 for (i = 0 ; i < pic14_nRegs ;i++) {
2272 if (options.useXstack) {
2273 pic14_emitcode("inc","%s",r->name);
2274 //pic14_emitcode("mov","a,(%s+%d)",
2275 // regspic14[i].base,8*bank+regspic14[i].offset);
2276 pic14_emitcode("movx","@%s,a",r->name);
2278 pic14_emitcode("push","");// "(%s+%d)",
2279 //regspic14[i].base,8*bank+regspic14[i].offset);
2283 if (options.useXstack) {
2284 pic14_emitcode("mov","a,psw");
2285 pic14_emitcode("movx","@%s,a",r->name);
2286 pic14_emitcode("inc","%s",r->name);
2287 pic14_emitcode("mov","_spx,%s",r->name);
2288 freeAsmop (NULL,aop,ic,TRUE);
2291 pic14_emitcode("push","psw");
2293 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2299 /*-----------------------------------------------------------------*/
2300 /* genCall - generates a call statement */
2301 /*-----------------------------------------------------------------*/
2302 static void genCall (iCode *ic)
2306 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2308 /* if caller saves & we have not saved then */
2312 /* if we are calling a function that is not using
2313 the same register bank then we need to save the
2314 destination registers on the stack */
2315 dtype = operandType(IC_LEFT(ic));
2316 if (currFunc && dtype &&
2317 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2318 IFFUNC_ISISR(currFunc->type) &&
2321 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2323 /* if send set is not empty the assign */
2326 /* For the Pic port, there is no data stack.
2327 * So parameters passed to functions are stored
2328 * in registers. (The pCode optimizer will get
2329 * rid of most of these :).
2331 int psuedoStkPtr=-1;
2332 int firstTimeThruLoop = 1;
2334 _G.sendSet = reverseSet(_G.sendSet);
2336 /* First figure how many parameters are getting passed */
2337 for (sic = setFirstItem(_G.sendSet) ; sic ;
2338 sic = setNextItem(_G.sendSet)) {
2340 aopOp(IC_LEFT(sic),sic,FALSE);
2341 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2342 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2345 for (sic = setFirstItem(_G.sendSet) ; sic ;
2346 sic = setNextItem(_G.sendSet)) {
2347 int size, offset = 0;
2349 aopOp(IC_LEFT(sic),sic,FALSE);
2350 size = AOP_SIZE(IC_LEFT(sic));
2353 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2354 AopType(AOP_TYPE(IC_LEFT(sic))));
2356 if(!firstTimeThruLoop) {
2357 /* If this is not the first time we've been through the loop
2358 * then we need to save the parameter in a temporary
2359 * register. The last byte of the last parameter is
2361 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2364 firstTimeThruLoop=0;
2366 //if (strcmp(l,fReturn[offset])) {
2368 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2369 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2370 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2372 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2377 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2382 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2383 OP_SYMBOL(IC_LEFT(ic))->rname :
2384 OP_SYMBOL(IC_LEFT(ic))->name));
2387 /* if we need assign a result value */
2388 if ((IS_ITEMP(IC_RESULT(ic)) &&
2389 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2390 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2391 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2394 aopOp(IC_RESULT(ic),ic,FALSE);
2397 assignResultValue(IC_RESULT(ic));
2399 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2400 AopType(AOP_TYPE(IC_RESULT(ic))));
2402 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2405 /* adjust the stack for parameters if
2407 if (ic->parmBytes) {
2409 if (ic->parmBytes > 3) {
2410 pic14_emitcode("mov","a,%s",spname);
2411 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2412 pic14_emitcode("mov","%s,a",spname);
2414 for ( i = 0 ; i < ic->parmBytes ;i++)
2415 pic14_emitcode("dec","%s",spname);
2419 /* if register bank was saved then pop them */
2421 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2423 /* if we hade saved some registers then unsave them */
2424 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2425 unsaveRegisters (ic);
2430 /*-----------------------------------------------------------------*/
2431 /* genPcall - generates a call by pointer statement */
2432 /*-----------------------------------------------------------------*/
2433 static void genPcall (iCode *ic)
2436 symbol *rlbl = newiTempLabel(NULL);
2439 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2440 /* if caller saves & we have not saved then */
2444 /* if we are calling a function that is not using
2445 the same register bank then we need to save the
2446 destination registers on the stack */
2447 dtype = operandType(IC_LEFT(ic));
2448 if (currFunc && dtype &&
2449 IFFUNC_ISISR(currFunc->type) &&
2450 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2451 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2454 /* push the return address on to the stack */
2455 pic14_emitcode("mov","a,#%05d_DS_",(rlbl->key+100));
2456 pic14_emitcode("push","acc");
2457 pic14_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100));
2458 pic14_emitcode("push","acc");
2460 if (options.model == MODEL_FLAT24)
2462 pic14_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100));
2463 pic14_emitcode("push","acc");
2466 /* now push the calling address */
2467 aopOp(IC_LEFT(ic),ic,FALSE);
2469 pushSide(IC_LEFT(ic), FPTRSIZE);
2471 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2473 /* if send set is not empty the assign */
2477 for (sic = setFirstItem(_G.sendSet) ; sic ;
2478 sic = setNextItem(_G.sendSet)) {
2479 int size, offset = 0;
2480 aopOp(IC_LEFT(sic),sic,FALSE);
2481 size = AOP_SIZE(IC_LEFT(sic));
2483 char *l = aopGet(AOP(IC_LEFT(sic)),offset,
2485 if (strcmp(l,fReturn[offset]))
2486 pic14_emitcode("mov","%s,%s",
2491 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2496 pic14_emitcode("ret","");
2497 pic14_emitcode("","%05d_DS_:",(rlbl->key+100));
2500 /* if we need assign a result value */
2501 if ((IS_ITEMP(IC_RESULT(ic)) &&
2502 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2503 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2504 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2507 aopOp(IC_RESULT(ic),ic,FALSE);
2510 assignResultValue(IC_RESULT(ic));
2512 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2515 /* adjust the stack for parameters if
2517 if (ic->parmBytes) {
2519 if (ic->parmBytes > 3) {
2520 pic14_emitcode("mov","a,%s",spname);
2521 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2522 pic14_emitcode("mov","%s,a",spname);
2524 for ( i = 0 ; i < ic->parmBytes ;i++)
2525 pic14_emitcode("dec","%s",spname);
2529 /* if register bank was saved then unsave them */
2530 if (currFunc && dtype &&
2531 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2532 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2534 /* if we hade saved some registers then
2537 unsaveRegisters (ic);
2541 /*-----------------------------------------------------------------*/
2542 /* resultRemat - result is rematerializable */
2543 /*-----------------------------------------------------------------*/
2544 static int resultRemat (iCode *ic)
2546 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2547 if (SKIP_IC(ic) || ic->op == IFX)
2550 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2551 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2552 if (sym->remat && !POINTER_SET(ic))
2559 #if defined(__BORLANDC__) || defined(_MSC_VER)
2560 #define STRCASECMP stricmp
2562 #define STRCASECMP strcasecmp
2566 /*-----------------------------------------------------------------*/
2567 /* inExcludeList - return 1 if the string is in exclude Reg list */
2568 /*-----------------------------------------------------------------*/
2569 static bool inExcludeList(char *s)
2571 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2574 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2575 if (options.excludeRegs[i] &&
2576 STRCASECMP(options.excludeRegs[i],"none") == 0)
2579 for ( i = 0 ; options.excludeRegs[i]; i++) {
2580 if (options.excludeRegs[i] &&
2581 STRCASECMP(s,options.excludeRegs[i]) == 0)
2588 /*-----------------------------------------------------------------*/
2589 /* genFunction - generated code for function entry */
2590 /*-----------------------------------------------------------------*/
2591 static void genFunction (iCode *ic)
2596 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2598 labelOffset += (max_key+4);
2602 /* create the function header */
2603 pic14_emitcode(";","-----------------------------------------");
2604 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2605 pic14_emitcode(";","-----------------------------------------");
2607 pic14_emitcode("","%s:",sym->rname);
2608 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2610 ftype = operandType(IC_LEFT(ic));
2612 /* if critical function then turn interrupts off */
2613 if (IFFUNC_ISCRITICAL(ftype))
2614 pic14_emitcode("clr","ea");
2616 /* here we need to generate the equates for the
2617 register bank if required */
2619 if (FUNC_REGBANK(ftype) != rbank) {
2622 rbank = FUNC_REGBANK(ftype);
2623 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2624 if (strcmp(regspic14[i].base,"0") == 0)
2625 pic14_emitcode("","%s = 0x%02x",
2627 8*rbank+regspic14[i].offset);
2629 pic14_emitcode ("","%s = %s + 0x%02x",
2632 8*rbank+regspic14[i].offset);
2637 /* if this is an interrupt service routine then
2638 save acc, b, dpl, dph */
2639 if (IFFUNC_ISISR(sym->type)) {
2640 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2641 emitpcodeNULLop(POC_NOP);
2642 emitpcodeNULLop(POC_NOP);
2643 emitpcodeNULLop(POC_NOP);
2644 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2645 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2646 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2647 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2649 pBlockConvert2ISR(pb);
2651 if (!inExcludeList("acc"))
2652 pic14_emitcode ("push","acc");
2653 if (!inExcludeList("b"))
2654 pic14_emitcode ("push","b");
2655 if (!inExcludeList("dpl"))
2656 pic14_emitcode ("push","dpl");
2657 if (!inExcludeList("dph"))
2658 pic14_emitcode ("push","dph");
2659 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2661 pic14_emitcode ("push", "dpx");
2662 /* Make sure we're using standard DPTR */
2663 pic14_emitcode ("push", "dps");
2664 pic14_emitcode ("mov", "dps, #0x00");
2665 if (options.stack10bit)
2667 /* This ISR could conceivably use DPTR2. Better save it. */
2668 pic14_emitcode ("push", "dpl1");
2669 pic14_emitcode ("push", "dph1");
2670 pic14_emitcode ("push", "dpx1");
2673 /* if this isr has no bank i.e. is going to
2674 run with bank 0 , then we need to save more
2676 if (!FUNC_REGBANK(sym->type)) {
2678 /* if this function does not call any other
2679 function then we can be economical and
2680 save only those registers that are used */
2681 if (! IFFUNC_HASFCALL(sym->type)) {
2684 /* if any registers used */
2685 if (sym->regsUsed) {
2686 /* save the registers used */
2687 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2688 if (bitVectBitValue(sym->regsUsed,i) ||
2689 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2690 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2695 /* this function has a function call cannot
2696 determines register usage so we will have the
2698 saverbank(0,ic,FALSE);
2703 /* if callee-save to be used for this function
2704 then save the registers being used in this function */
2705 if (IFFUNC_CALLEESAVES(sym->type)) {
2708 /* if any registers used */
2709 if (sym->regsUsed) {
2710 /* save the registers used */
2711 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2712 if (bitVectBitValue(sym->regsUsed,i) ||
2713 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2714 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2722 /* set the register bank to the desired value */
2723 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2724 pic14_emitcode("push","psw");
2725 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2728 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2730 if (options.useXstack) {
2731 pic14_emitcode("mov","r0,%s",spname);
2732 pic14_emitcode("mov","a,_bp");
2733 pic14_emitcode("movx","@r0,a");
2734 pic14_emitcode("inc","%s",spname);
2738 /* set up the stack */
2739 pic14_emitcode ("push","_bp"); /* save the callers stack */
2741 pic14_emitcode ("mov","_bp,%s",spname);
2744 /* adjust the stack for the function */
2749 werror(W_STACK_OVERFLOW,sym->name);
2751 if (i > 3 && sym->recvSize < 4) {
2753 pic14_emitcode ("mov","a,sp");
2754 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2755 pic14_emitcode ("mov","sp,a");
2760 pic14_emitcode("inc","sp");
2765 pic14_emitcode ("mov","a,_spx");
2766 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2767 pic14_emitcode ("mov","_spx,a");
2772 /*-----------------------------------------------------------------*/
2773 /* genEndFunction - generates epilogue for functions */
2774 /*-----------------------------------------------------------------*/
2775 static void genEndFunction (iCode *ic)
2777 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2781 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2783 pic14_emitcode ("mov","%s,_bp",spname);
2786 /* if use external stack but some variables were
2787 added to the local stack then decrement the
2789 if (options.useXstack && sym->stack) {
2790 pic14_emitcode("mov","a,sp");
2791 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2792 pic14_emitcode("mov","sp,a");
2796 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2797 if (options.useXstack) {
2798 pic14_emitcode("mov","r0,%s",spname);
2799 pic14_emitcode("movx","a,@r0");
2800 pic14_emitcode("mov","_bp,a");
2801 pic14_emitcode("dec","%s",spname);
2805 pic14_emitcode ("pop","_bp");
2809 /* restore the register bank */
2810 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2811 pic14_emitcode ("pop","psw");
2813 if (IFFUNC_ISISR(sym->type)) {
2815 /* now we need to restore the registers */
2816 /* if this isr has no bank i.e. is going to
2817 run with bank 0 , then we need to save more
2819 if (!FUNC_REGBANK(sym->type)) {
2821 /* if this function does not call any other
2822 function then we can be economical and
2823 save only those registers that are used */
2824 if (! IFFUNC_HASFCALL(sym->type)) {
2827 /* if any registers used */
2828 if (sym->regsUsed) {
2829 /* save the registers used */
2830 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2831 if (bitVectBitValue(sym->regsUsed,i) ||
2832 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2833 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2838 /* this function has a function call cannot
2839 determines register usage so we will have the
2841 unsaverbank(0,ic,FALSE);
2845 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2847 if (options.stack10bit)
2849 pic14_emitcode ("pop", "dpx1");
2850 pic14_emitcode ("pop", "dph1");
2851 pic14_emitcode ("pop", "dpl1");
2853 pic14_emitcode ("pop", "dps");
2854 pic14_emitcode ("pop", "dpx");
2856 if (!inExcludeList("dph"))
2857 pic14_emitcode ("pop","dph");
2858 if (!inExcludeList("dpl"))
2859 pic14_emitcode ("pop","dpl");
2860 if (!inExcludeList("b"))
2861 pic14_emitcode ("pop","b");
2862 if (!inExcludeList("acc"))
2863 pic14_emitcode ("pop","acc");
2865 if (IFFUNC_ISCRITICAL(sym->type))
2866 pic14_emitcode("setb","ea");
2869 /* if debug then send end of function */
2870 /* if (options.debug && currFunc) { */
2873 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2874 FileBaseName(ic->filename),currFunc->lastLine,
2875 ic->level,ic->block);
2876 if (IS_STATIC(currFunc->etype))
2877 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2879 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2883 pic14_emitcode ("reti","");
2885 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2886 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2887 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2888 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2889 emitpcode(POC_MOVFW, popCopyReg(&pc_wsave));
2890 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2892 emitpcodeNULLop(POC_RETFIE);
2896 if (IFFUNC_ISCRITICAL(sym->type))
2897 pic14_emitcode("setb","ea");
2899 if (IFFUNC_CALLEESAVES(sym->type)) {
2902 /* if any registers used */
2903 if (sym->regsUsed) {
2904 /* save the registers used */
2905 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2906 if (bitVectBitValue(sym->regsUsed,i) ||
2907 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2908 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2914 /* if debug then send end of function */
2917 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2918 FileBaseName(ic->filename),currFunc->lastLine,
2919 ic->level,ic->block);
2920 if (IS_STATIC(currFunc->etype))
2921 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2923 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2927 pic14_emitcode ("return","");
2928 emitpcodeNULLop(POC_RETURN);
2930 /* Mark the end of a function */
2931 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2936 /*-----------------------------------------------------------------*/
2937 /* genRet - generate code for return statement */
2938 /*-----------------------------------------------------------------*/
2939 static void genRet (iCode *ic)
2941 int size,offset = 0 , pushed = 0;
2943 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2944 /* if we have no return value then
2945 just generate the "ret" */
2949 /* we have something to return then
2950 move the return value into place */
2951 aopOp(IC_LEFT(ic),ic,FALSE);
2952 size = AOP_SIZE(IC_LEFT(ic));
2956 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2958 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2960 pic14_emitcode("push","%s",l);
2963 l = aopGet(AOP(IC_LEFT(ic)),offset,
2965 if (strcmp(fReturn[offset],l)) {
2966 if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2967 ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2968 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2970 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2973 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
2974 pic14_emitcode("movwf","%s",fReturn[offset]);
2984 if (strcmp(fReturn[pushed],"a"))
2985 pic14_emitcode("pop",fReturn[pushed]);
2987 pic14_emitcode("pop","acc");
2990 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2993 /* generate a jump to the return label
2994 if the next is not the return statement */
2995 if (!(ic->next && ic->next->op == LABEL &&
2996 IC_LABEL(ic->next) == returnLabel)) {
2998 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2999 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3004 /*-----------------------------------------------------------------*/
3005 /* genLabel - generates a label */
3006 /*-----------------------------------------------------------------*/
3007 static void genLabel (iCode *ic)
3009 /* special case never generate */
3010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3011 if (IC_LABEL(ic) == entryLabel)
3014 emitpLabel(IC_LABEL(ic)->key);
3015 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3018 /*-----------------------------------------------------------------*/
3019 /* genGoto - generates a goto */
3020 /*-----------------------------------------------------------------*/
3022 static void genGoto (iCode *ic)
3024 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3025 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3029 /*-----------------------------------------------------------------*/
3030 /* genMultbits :- multiplication of bits */
3031 /*-----------------------------------------------------------------*/
3032 static void genMultbits (operand *left,
3036 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3038 if(!pic14_sameRegs(AOP(result),AOP(right)))
3039 emitpcode(POC_BSF, popGet(AOP(result),0));
3041 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3042 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3043 emitpcode(POC_BCF, popGet(AOP(result),0));
3048 /*-----------------------------------------------------------------*/
3049 /* genMultOneByte : 8 bit multiplication & division */
3050 /*-----------------------------------------------------------------*/
3051 static void genMultOneByte (operand *left,
3055 sym_link *opetype = operandType(result);
3060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3061 DEBUGpic14_AopType(__LINE__,left,right,result);
3062 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3064 /* (if two literals, the value is computed before) */
3065 /* if one literal, literal on the right */
3066 if (AOP_TYPE(left) == AOP_LIT){
3072 size = AOP_SIZE(result);
3075 if (AOP_TYPE(right) == AOP_LIT){
3076 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3077 aopGet(AOP(right),0,FALSE,FALSE),
3078 aopGet(AOP(left),0,FALSE,FALSE),
3079 aopGet(AOP(result),0,FALSE,FALSE));
3080 pic14_emitcode("call","genMultLit");
3082 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3083 aopGet(AOP(right),0,FALSE,FALSE),
3084 aopGet(AOP(left),0,FALSE,FALSE),
3085 aopGet(AOP(result),0,FALSE,FALSE));
3086 pic14_emitcode("call","genMult8X8_8");
3089 genMult8X8_8 (left, right,result);
3092 /* signed or unsigned */
3093 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3094 //l = aopGet(AOP(left),0,FALSE,FALSE);
3096 //pic14_emitcode("mul","ab");
3097 /* if result size = 1, mul signed = mul unsigned */
3098 //aopPut(AOP(result),"a",0);
3100 } else { // (size > 1)
3102 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3103 aopGet(AOP(right),0,FALSE,FALSE),
3104 aopGet(AOP(left),0,FALSE,FALSE),
3105 aopGet(AOP(result),0,FALSE,FALSE));
3107 if (SPEC_USIGN(opetype)){
3108 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3109 genUMult8X8_16 (left, right, result, NULL);
3112 /* for filling the MSBs */
3113 emitpcode(POC_CLRF, popGet(AOP(result),2));
3114 emitpcode(POC_CLRF, popGet(AOP(result),3));
3118 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3120 pic14_emitcode("mov","a,b");
3122 /* adjust the MSB if left or right neg */
3124 /* if one literal */
3125 if (AOP_TYPE(right) == AOP_LIT){
3126 pic14_emitcode("multiply ","right is a lit");
3127 /* AND literal negative */
3128 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3129 /* adjust MSB (c==0 after mul) */
3130 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3134 genSMult8X8_16 (left, right, result, NULL);
3138 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3140 pic14_emitcode("rlc","a");
3141 pic14_emitcode("subb","a,acc");
3149 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3150 //aopPut(AOP(result),"a",offset++);
3154 /*-----------------------------------------------------------------*/
3155 /* genMult - generates code for multiplication */
3156 /*-----------------------------------------------------------------*/
3157 static void genMult (iCode *ic)
3159 operand *left = IC_LEFT(ic);
3160 operand *right = IC_RIGHT(ic);
3161 operand *result= IC_RESULT(ic);
3163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3164 /* assign the amsops */
3165 aopOp (left,ic,FALSE);
3166 aopOp (right,ic,FALSE);
3167 aopOp (result,ic,TRUE);
3169 DEBUGpic14_AopType(__LINE__,left,right,result);
3171 /* special cases first */
3173 if (AOP_TYPE(left) == AOP_CRY &&
3174 AOP_TYPE(right)== AOP_CRY) {
3175 genMultbits(left,right,result);
3179 /* if both are of size == 1 */
3180 if (AOP_SIZE(left) == 1 &&
3181 AOP_SIZE(right) == 1 ) {
3182 genMultOneByte(left,right,result);
3186 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3188 /* should have been converted to function call */
3192 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3193 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3194 freeAsmop(result,NULL,ic,TRUE);
3197 /*-----------------------------------------------------------------*/
3198 /* genDivbits :- division of bits */
3199 /*-----------------------------------------------------------------*/
3200 static void genDivbits (operand *left,
3207 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3208 /* the result must be bit */
3209 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3210 l = aopGet(AOP(left),0,FALSE,FALSE);
3214 pic14_emitcode("div","ab");
3215 pic14_emitcode("rrc","a");
3216 aopPut(AOP(result),"c",0);
3219 /*-----------------------------------------------------------------*/
3220 /* genDivOneByte : 8 bit division */
3221 /*-----------------------------------------------------------------*/
3222 static void genDivOneByte (operand *left,
3226 sym_link *opetype = operandType(result);
3231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3232 size = AOP_SIZE(result) - 1;
3234 /* signed or unsigned */
3235 if (SPEC_USIGN(opetype)) {
3236 /* unsigned is easy */
3237 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3238 l = aopGet(AOP(left),0,FALSE,FALSE);
3240 pic14_emitcode("div","ab");
3241 aopPut(AOP(result),"a",0);
3243 aopPut(AOP(result),zero,offset++);
3247 /* signed is a little bit more difficult */
3249 /* save the signs of the operands */
3250 l = aopGet(AOP(left),0,FALSE,FALSE);
3252 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3253 pic14_emitcode("push","acc"); /* save it on the stack */
3255 /* now sign adjust for both left & right */
3256 l = aopGet(AOP(right),0,FALSE,FALSE);
3258 lbl = newiTempLabel(NULL);
3259 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3260 pic14_emitcode("cpl","a");
3261 pic14_emitcode("inc","a");
3262 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3263 pic14_emitcode("mov","b,a");
3265 /* sign adjust left side */
3266 l = aopGet(AOP(left),0,FALSE,FALSE);
3269 lbl = newiTempLabel(NULL);
3270 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3271 pic14_emitcode("cpl","a");
3272 pic14_emitcode("inc","a");
3273 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3275 /* now the division */
3276 pic14_emitcode("div","ab");
3277 /* we are interested in the lower order
3279 pic14_emitcode("mov","b,a");
3280 lbl = newiTempLabel(NULL);
3281 pic14_emitcode("pop","acc");
3282 /* if there was an over flow we don't
3283 adjust the sign of the result */
3284 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3285 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3287 pic14_emitcode("clr","a");
3288 pic14_emitcode("subb","a,b");
3289 pic14_emitcode("mov","b,a");
3290 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3292 /* now we are done */
3293 aopPut(AOP(result),"b",0);
3295 pic14_emitcode("mov","c,b.7");
3296 pic14_emitcode("subb","a,acc");
3299 aopPut(AOP(result),"a",offset++);
3303 /*-----------------------------------------------------------------*/
3304 /* genDiv - generates code for division */
3305 /*-----------------------------------------------------------------*/
3306 static void genDiv (iCode *ic)
3308 operand *left = IC_LEFT(ic);
3309 operand *right = IC_RIGHT(ic);
3310 operand *result= IC_RESULT(ic);
3312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3313 /* assign the amsops */
3314 aopOp (left,ic,FALSE);
3315 aopOp (right,ic,FALSE);
3316 aopOp (result,ic,TRUE);
3318 /* special cases first */
3320 if (AOP_TYPE(left) == AOP_CRY &&
3321 AOP_TYPE(right)== AOP_CRY) {
3322 genDivbits(left,right,result);
3326 /* if both are of size == 1 */
3327 if (AOP_SIZE(left) == 1 &&
3328 AOP_SIZE(right) == 1 ) {
3329 genDivOneByte(left,right,result);
3333 /* should have been converted to function call */
3336 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3337 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3338 freeAsmop(result,NULL,ic,TRUE);
3341 /*-----------------------------------------------------------------*/
3342 /* genModbits :- modulus of bits */
3343 /*-----------------------------------------------------------------*/
3344 static void genModbits (operand *left,
3351 /* the result must be bit */
3352 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3353 l = aopGet(AOP(left),0,FALSE,FALSE);
3357 pic14_emitcode("div","ab");
3358 pic14_emitcode("mov","a,b");
3359 pic14_emitcode("rrc","a");
3360 aopPut(AOP(result),"c",0);
3363 /*-----------------------------------------------------------------*/
3364 /* genModOneByte : 8 bit modulus */
3365 /*-----------------------------------------------------------------*/
3366 static void genModOneByte (operand *left,
3370 sym_link *opetype = operandType(result);
3374 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3375 /* signed or unsigned */
3376 if (SPEC_USIGN(opetype)) {
3377 /* unsigned is easy */
3378 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3379 l = aopGet(AOP(left),0,FALSE,FALSE);
3381 pic14_emitcode("div","ab");
3382 aopPut(AOP(result),"b",0);
3386 /* signed is a little bit more difficult */
3388 /* save the signs of the operands */
3389 l = aopGet(AOP(left),0,FALSE,FALSE);
3392 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3393 pic14_emitcode("push","acc"); /* save it on the stack */
3395 /* now sign adjust for both left & right */
3396 l = aopGet(AOP(right),0,FALSE,FALSE);
3399 lbl = newiTempLabel(NULL);
3400 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3401 pic14_emitcode("cpl","a");
3402 pic14_emitcode("inc","a");
3403 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3404 pic14_emitcode("mov","b,a");
3406 /* sign adjust left side */
3407 l = aopGet(AOP(left),0,FALSE,FALSE);
3410 lbl = newiTempLabel(NULL);
3411 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3412 pic14_emitcode("cpl","a");
3413 pic14_emitcode("inc","a");
3414 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3416 /* now the multiplication */
3417 pic14_emitcode("div","ab");
3418 /* we are interested in the lower order
3420 lbl = newiTempLabel(NULL);
3421 pic14_emitcode("pop","acc");
3422 /* if there was an over flow we don't
3423 adjust the sign of the result */
3424 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3425 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3427 pic14_emitcode("clr","a");
3428 pic14_emitcode("subb","a,b");
3429 pic14_emitcode("mov","b,a");
3430 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3432 /* now we are done */
3433 aopPut(AOP(result),"b",0);
3437 /*-----------------------------------------------------------------*/
3438 /* genMod - generates code for division */
3439 /*-----------------------------------------------------------------*/
3440 static void genMod (iCode *ic)
3442 operand *left = IC_LEFT(ic);
3443 operand *right = IC_RIGHT(ic);
3444 operand *result= IC_RESULT(ic);
3446 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3447 /* assign the amsops */
3448 aopOp (left,ic,FALSE);
3449 aopOp (right,ic,FALSE);
3450 aopOp (result,ic,TRUE);
3452 /* special cases first */
3454 if (AOP_TYPE(left) == AOP_CRY &&
3455 AOP_TYPE(right)== AOP_CRY) {
3456 genModbits(left,right,result);
3460 /* if both are of size == 1 */
3461 if (AOP_SIZE(left) == 1 &&
3462 AOP_SIZE(right) == 1 ) {
3463 genModOneByte(left,right,result);
3467 /* should have been converted to function call */
3471 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3472 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3473 freeAsmop(result,NULL,ic,TRUE);
3476 /*-----------------------------------------------------------------*/
3477 /* genIfxJump :- will create a jump depending on the ifx */
3478 /*-----------------------------------------------------------------*/
3480 note: May need to add parameter to indicate when a variable is in bit space.
3482 static void genIfxJump (iCode *ic, char *jval)
3485 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3486 /* if true label then we jump if condition
3488 if ( IC_TRUE(ic) ) {
3490 if(strcmp(jval,"a") == 0)
3492 else if (strcmp(jval,"c") == 0)
3495 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3496 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3499 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3500 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3504 /* false label is present */
3505 if(strcmp(jval,"a") == 0)
3507 else if (strcmp(jval,"c") == 0)
3510 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3511 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3514 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3515 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3520 /* mark the icode as generated */
3524 /*-----------------------------------------------------------------*/
3526 /*-----------------------------------------------------------------*/
3527 static void genSkip(iCode *ifx,int status_bit)
3532 if ( IC_TRUE(ifx) ) {
3533 switch(status_bit) {
3548 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3549 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3553 switch(status_bit) {
3567 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3568 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3574 /*-----------------------------------------------------------------*/
3576 /*-----------------------------------------------------------------*/
3577 static void genSkipc(resolvedIfx *rifx)
3587 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3588 rifx->generated = 1;
3591 /*-----------------------------------------------------------------*/
3593 /*-----------------------------------------------------------------*/
3594 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3599 if( (rifx->condition ^ invert_condition) & 1)
3604 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3605 rifx->generated = 1;
3608 /*-----------------------------------------------------------------*/
3610 /*-----------------------------------------------------------------*/
3611 static void genSkipz(iCode *ifx, int condition)
3622 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3624 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3627 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3629 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3632 /*-----------------------------------------------------------------*/
3634 /*-----------------------------------------------------------------*/
3635 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3641 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3643 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3646 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3647 rifx->generated = 1;
3651 /*-----------------------------------------------------------------*/
3652 /* genChkZeroes :- greater or less than comparison */
3653 /* For each byte in a literal that is zero, inclusive or the */
3654 /* the corresponding byte in the operand with W */
3655 /* returns true if any of the bytes are zero */
3656 /*-----------------------------------------------------------------*/
3657 static int genChkZeroes(operand *op, int lit, int size)
3664 i = (lit >> (size*8)) & 0xff;
3668 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3670 emitpcode(POC_IORFW, popGet(AOP(op),size));
3679 /*-----------------------------------------------------------------*/
3680 /* genCmp :- greater or less than comparison */
3681 /*-----------------------------------------------------------------*/
3682 static void genCmp (operand *left,operand *right,
3683 operand *result, iCode *ifx, int sign)
3685 int size; //, offset = 0 ;
3686 unsigned long lit = 0L,i = 0;
3687 resolvedIfx rFalseIfx;
3688 // resolvedIfx rTrueIfx;
3690 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3692 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3693 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3697 resolveIfx(&rFalseIfx,ifx);
3698 truelbl = newiTempLabel(NULL);
3699 size = max(AOP_SIZE(left),AOP_SIZE(right));
3703 /* if literal is on the right then swap with left */
3704 if ((AOP_TYPE(right) == AOP_LIT)) {
3705 operand *tmp = right ;
3706 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3707 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3709 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit);
3710 lit = (lit - 1) & mask;
3711 DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask);
3715 rFalseIfx.condition ^= 1;
3718 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3719 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3723 //if(IC_TRUE(ifx) == NULL)
3724 /* if left & right are bit variables */
3725 if (AOP_TYPE(left) == AOP_CRY &&
3726 AOP_TYPE(right) == AOP_CRY ) {
3727 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3728 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3730 /* subtract right from left if at the
3731 end the carry flag is set then we know that
3732 left is greater than right */
3736 symbol *lbl = newiTempLabel(NULL);
3739 if(AOP_TYPE(right) == AOP_LIT) {
3741 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3743 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3750 genSkipCond(&rFalseIfx,left,size-1,7);
3752 /* no need to compare to 0...*/
3753 /* NOTE: this is a de-generate compare that most certainly
3754 * creates some dead code. */
3755 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3757 if(ifx) ifx->generated = 1;
3764 //i = (lit >> (size*8)) & 0xff;
3765 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3767 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3769 i = ((0-lit) & 0xff);
3772 /* lit is 0x7f, all signed chars are less than
3773 * this except for 0x7f itself */
3774 emitpcode(POC_XORLW, popGetLit(0x7f));
3775 genSkipz2(&rFalseIfx,0);
3777 emitpcode(POC_ADDLW, popGetLit(0x80));
3778 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3779 genSkipc(&rFalseIfx);
3784 genSkipz2(&rFalseIfx,1);
3786 emitpcode(POC_ADDLW, popGetLit(i));
3787 genSkipc(&rFalseIfx);
3791 if(ifx) ifx->generated = 1;
3795 /* chars are out of the way. now do ints and longs */
3798 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3805 genSkipCond(&rFalseIfx,left,size,7);
3806 if(ifx) ifx->generated = 1;
3811 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3813 //rFalseIfx.condition ^= 1;
3814 //genSkipCond(&rFalseIfx,left,size,7);
3815 //rFalseIfx.condition ^= 1;
3817 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3818 if(rFalseIfx.condition)
3819 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3821 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3823 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3824 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3825 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3828 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3830 if(rFalseIfx.condition) {
3832 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3838 genSkipc(&rFalseIfx);
3839 emitpLabel(truelbl->key);
3840 if(ifx) ifx->generated = 1;
3847 if( (lit & 0xff) == 0) {
3848 /* lower byte is zero */
3849 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3850 i = ((lit >> 8) & 0xff) ^0x80;
3851 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3852 emitpcode(POC_ADDLW, popGetLit( 0x80));
3853 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3854 genSkipc(&rFalseIfx);
3857 if(ifx) ifx->generated = 1;
3862 /* Special cases for signed longs */
3863 if( (lit & 0xffffff) == 0) {
3864 /* lower byte is zero */
3865 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3866 i = ((lit >> 8*3) & 0xff) ^0x80;
3867 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3868 emitpcode(POC_ADDLW, popGetLit( 0x80));
3869 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3870 genSkipc(&rFalseIfx);
3873 if(ifx) ifx->generated = 1;
3881 if(lit & (0x80 << (size*8))) {
3882 /* lit is negative */
3883 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3885 //genSkipCond(&rFalseIfx,left,size,7);
3887 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3889 if(rFalseIfx.condition)
3890 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3892 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3896 /* lit is positive */
3897 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3898 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3899 if(rFalseIfx.condition)
3900 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3902 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3907 This works, but is only good for ints.
3908 It also requires a "known zero" register.
3909 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3910 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3911 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3912 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3913 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3914 genSkipc(&rFalseIfx);
3916 emitpLabel(truelbl->key);
3917 if(ifx) ifx->generated = 1;
3921 /* There are no more special cases, so perform a general compare */
3923 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3924 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3928 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3930 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3932 //rFalseIfx.condition ^= 1;
3933 genSkipc(&rFalseIfx);
3935 emitpLabel(truelbl->key);
3937 if(ifx) ifx->generated = 1;
3944 /* sign is out of the way. So now do an unsigned compare */
3945 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3948 /* General case - compare to an unsigned literal on the right.*/
3950 i = (lit >> (size*8)) & 0xff;
3951 emitpcode(POC_MOVLW, popGetLit(i));
3952 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3954 i = (lit >> (size*8)) & 0xff;
3957 emitpcode(POC_MOVLW, popGetLit(i));
3959 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3961 /* this byte of the lit is zero,
3962 *if it's not the last then OR in the variable */
3964 emitpcode(POC_IORFW, popGet(AOP(left),size));
3969 emitpLabel(lbl->key);
3970 //if(emitFinalCheck)
3971 genSkipc(&rFalseIfx);
3973 emitpLabel(truelbl->key);
3975 if(ifx) ifx->generated = 1;
3981 if(AOP_TYPE(left) == AOP_LIT) {
3982 //symbol *lbl = newiTempLabel(NULL);
3984 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3987 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3990 if((lit == 0) && (sign == 0)){
3993 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3995 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3997 genSkipz2(&rFalseIfx,0);
3998 if(ifx) ifx->generated = 1;
4005 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4006 /* degenerate compare can never be true */
4007 if(rFalseIfx.condition == 0)
4008 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4010 if(ifx) ifx->generated = 1;
4015 /* signed comparisons to a literal byte */
4017 int lp1 = (lit+1) & 0xff;
4019 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4022 rFalseIfx.condition ^= 1;
4023 genSkipCond(&rFalseIfx,right,0,7);
4026 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4027 emitpcode(POC_XORLW, popGetLit(0x7f));
4028 genSkipz2(&rFalseIfx,1);
4031 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4032 emitpcode(POC_ADDLW, popGetLit(0x80));
4033 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4034 rFalseIfx.condition ^= 1;
4035 genSkipc(&rFalseIfx);
4039 /* unsigned comparisons to a literal byte */
4041 switch(lit & 0xff ) {
4043 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4044 genSkipz2(&rFalseIfx,0);
4047 rFalseIfx.condition ^= 1;
4048 genSkipCond(&rFalseIfx,right,0,7);
4052 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4053 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4055 rFalseIfx.condition ^= 1;
4056 genSkipc(&rFalseIfx);
4061 if(ifx) ifx->generated = 1;
4066 /* Size is greater than 1 */
4074 /* this means lit = 0xffffffff, or -1 */
4077 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4078 rFalseIfx.condition ^= 1;
4079 genSkipCond(&rFalseIfx,right,size,7);
4080 if(ifx) ifx->generated = 1;
4087 if(rFalseIfx.condition) {
4088 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4089 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4092 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4094 emitpcode(POC_IORFW, popGet(AOP(right),size));
4098 if(rFalseIfx.condition) {
4099 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4100 emitpLabel(truelbl->key);
4102 rFalseIfx.condition ^= 1;
4103 genSkipCond(&rFalseIfx,right,s,7);
4106 if(ifx) ifx->generated = 1;
4110 if((size == 1) && (0 == (lp1&0xff))) {
4111 /* lower byte of signed word is zero */
4112 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4113 i = ((lp1 >> 8) & 0xff) ^0x80;
4114 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4115 emitpcode(POC_ADDLW, popGetLit( 0x80));
4116 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4117 rFalseIfx.condition ^= 1;
4118 genSkipc(&rFalseIfx);
4121 if(ifx) ifx->generated = 1;
4125 if(lit & (0x80 << (size*8))) {
4126 /* Lit is less than zero */
4127 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4128 //rFalseIfx.condition ^= 1;
4129 //genSkipCond(&rFalseIfx,left,size,7);
4130 //rFalseIfx.condition ^= 1;
4131 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4132 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4134 if(rFalseIfx.condition)
4135 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4137 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4141 /* Lit is greater than or equal to zero */
4142 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4143 //rFalseIfx.condition ^= 1;
4144 //genSkipCond(&rFalseIfx,right,size,7);
4145 //rFalseIfx.condition ^= 1;
4147 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4148 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4150 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4151 if(rFalseIfx.condition)
4152 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4154 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4159 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4160 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4164 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4166 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4168 rFalseIfx.condition ^= 1;
4169 //rFalseIfx.condition = 1;
4170 genSkipc(&rFalseIfx);
4172 emitpLabel(truelbl->key);
4174 if(ifx) ifx->generated = 1;
4179 /* compare word or long to an unsigned literal on the right.*/
4184 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4187 break; /* handled above */
4190 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4192 emitpcode(POC_IORFW, popGet(AOP(right),size));
4193 genSkipz2(&rFalseIfx,0);
4197 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4199 emitpcode(POC_IORFW, popGet(AOP(right),size));
4202 if(rFalseIfx.condition)
4203 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4205 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4208 emitpcode(POC_MOVLW, popGetLit(lit+1));
4209 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4211 rFalseIfx.condition ^= 1;
4212 genSkipc(&rFalseIfx);
4215 emitpLabel(truelbl->key);
4217 if(ifx) ifx->generated = 1;
4223 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4224 i = (lit >> (size*8)) & 0xff;
4226 emitpcode(POC_MOVLW, popGetLit(i));
4227 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4230 i = (lit >> (size*8)) & 0xff;
4233 emitpcode(POC_MOVLW, popGetLit(i));
4235 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4237 /* this byte of the lit is zero,
4238 *if it's not the last then OR in the variable */
4240 emitpcode(POC_IORFW, popGet(AOP(right),size));
4245 emitpLabel(lbl->key);
4247 rFalseIfx.condition ^= 1;
4248 genSkipc(&rFalseIfx);
4252 emitpLabel(truelbl->key);
4253 if(ifx) ifx->generated = 1;
4257 /* Compare two variables */
4259 DEBUGpic14_emitcode(";sign","%d",sign);
4263 /* Sigh. thus sucks... */
4265 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4266 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4267 emitpcode(POC_MOVLW, popGetLit(0x80));
4268 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4269 emitpcode(POC_XORFW, popGet(AOP(right),size));
4270 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4272 /* Signed char comparison */
4273 /* Special thanks to Nikolai Golovchenko for this snippet */
4274 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4275 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4276 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4277 emitpcode(POC_XORFW, popGet(AOP(left),0));
4278 emitpcode(POC_XORFW, popGet(AOP(right),0));
4279 emitpcode(POC_ADDLW, popGetLit(0x80));
4281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4282 genSkipc(&rFalseIfx);
4284 if(ifx) ifx->generated = 1;
4290 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4291 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4295 /* The rest of the bytes of a multi-byte compare */
4299 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4302 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4303 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4308 emitpLabel(lbl->key);
4310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4311 genSkipc(&rFalseIfx);
4312 if(ifx) ifx->generated = 1;
4317 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4318 pic14_outBitC(result);
4320 /* if the result is used in the next
4321 ifx conditional branch then generate
4322 code a little differently */
4324 genIfxJump (ifx,"c");
4326 pic14_outBitC(result);
4327 /* leave the result in acc */
4332 /*-----------------------------------------------------------------*/
4333 /* genCmpGt :- greater than comparison */
4334 /*-----------------------------------------------------------------*/
4335 static void genCmpGt (iCode *ic, iCode *ifx)
4337 operand *left, *right, *result;
4338 sym_link *letype , *retype;
4341 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4343 right= IC_RIGHT(ic);
4344 result = IC_RESULT(ic);
4346 letype = getSpec(operandType(left));
4347 retype =getSpec(operandType(right));
4348 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4349 /* assign the amsops */
4350 aopOp (left,ic,FALSE);
4351 aopOp (right,ic,FALSE);
4352 aopOp (result,ic,TRUE);
4354 genCmp(right, left, result, ifx, sign);
4356 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4357 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4358 freeAsmop(result,NULL,ic,TRUE);
4361 /*-----------------------------------------------------------------*/
4362 /* genCmpLt - less than comparisons */
4363 /*-----------------------------------------------------------------*/
4364 static void genCmpLt (iCode *ic, iCode *ifx)
4366 operand *left, *right, *result;
4367 sym_link *letype , *retype;
4370 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4372 right= IC_RIGHT(ic);
4373 result = IC_RESULT(ic);
4375 letype = getSpec(operandType(left));
4376 retype =getSpec(operandType(right));
4377 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4379 /* assign the amsops */
4380 aopOp (left,ic,FALSE);
4381 aopOp (right,ic,FALSE);
4382 aopOp (result,ic,TRUE);
4384 genCmp(left, right, result, ifx, sign);
4386 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4387 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4388 freeAsmop(result,NULL,ic,TRUE);
4391 /*-----------------------------------------------------------------*/
4392 /* genc16bit2lit - compare a 16 bit value to a literal */
4393 /*-----------------------------------------------------------------*/
4394 static void genc16bit2lit(operand *op, int lit, int offset)
4398 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4399 if( (lit&0xff) == 0)
4404 switch( BYTEofLONG(lit,i)) {
4406 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4409 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4412 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4415 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4416 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4421 switch( BYTEofLONG(lit,i)) {
4423 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4427 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4431 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4434 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4436 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4442 /*-----------------------------------------------------------------*/
4443 /* gencjneshort - compare and jump if not equal */
4444 /*-----------------------------------------------------------------*/
4445 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4447 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4452 unsigned long lit = 0L;
4453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4454 DEBUGpic14_AopType(__LINE__,left,right,NULL);
4456 resolveIfx(&rIfx,ifx);
4457 lbl = newiTempLabel(NULL);
4460 /* if the left side is a literal or
4461 if the right is in a pointer register and left
4463 if ((AOP_TYPE(left) == AOP_LIT) ||
4464 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4469 if(AOP_TYPE(right) == AOP_LIT)
4470 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4472 /* if the right side is a literal then anything goes */
4473 if (AOP_TYPE(right) == AOP_LIT &&
4474 AOP_TYPE(left) != AOP_DIR ) {
4477 genc16bit2lit(left, lit, 0);
4479 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4484 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4485 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4487 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4491 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4499 /* if the right side is in a register or in direct space or
4500 if the left is a pointer register & right is not */
4501 else if (AOP_TYPE(right) == AOP_REG ||
4502 AOP_TYPE(right) == AOP_DIR ||
4503 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4504 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4507 genc16bit2lit(left, lit, 0);
4509 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4514 if((AOP_TYPE(left) == AOP_DIR) &&
4515 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4517 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4518 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4520 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4522 switch (lit & 0xff) {
4524 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4527 emitpcode(POC_DECFSZ,popGet(AOP(left),offset));
4528 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4532 emitpcode(POC_INCFSZ,popGet(AOP(left),offset));
4533 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4537 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4538 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4543 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4546 if(AOP_TYPE(result) == AOP_CRY) {
4547 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4552 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4554 /* fix me. probably need to check result size too */
4555 emitpcode(POC_CLRF,popGet(AOP(result),0));
4560 emitpcode(POC_INCF,popGet(AOP(result),0));
4570 } else if(AOP_TYPE(right) == AOP_REG &&
4571 AOP_TYPE(left) != AOP_DIR){
4574 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4575 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4576 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4581 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4586 /* right is a pointer reg need both a & b */
4588 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4590 pic14_emitcode("mov","b,%s",l);
4591 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4592 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4596 emitpLabel(lbl->key);
4603 /*-----------------------------------------------------------------*/
4604 /* gencjne - compare and jump if not equal */
4605 /*-----------------------------------------------------------------*/
4606 static void gencjne(operand *left, operand *right, iCode *ifx)
4608 symbol *tlbl = newiTempLabel(NULL);
4610 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4611 gencjneshort(left, right, lbl);
4613 pic14_emitcode("mov","a,%s",one);
4614 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4615 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4616 pic14_emitcode("clr","a");
4617 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4619 emitpLabel(lbl->key);
4620 emitpLabel(tlbl->key);
4625 /*-----------------------------------------------------------------*/
4626 /* genCmpEq - generates code for equal to */
4627 /*-----------------------------------------------------------------*/
4628 static void genCmpEq (iCode *ic, iCode *ifx)
4630 operand *left, *right, *result;
4631 unsigned long lit = 0L;
4634 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4637 DEBUGpic14_emitcode ("; ifx is non-null","");
4639 DEBUGpic14_emitcode ("; ifx is null","");
4641 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4642 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4643 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4645 size = max(AOP_SIZE(left),AOP_SIZE(right));
4647 DEBUGpic14_AopType(__LINE__,left,right,result);
4649 /* if literal, literal on the right or
4650 if the right is in a pointer register and left
4652 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4653 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4654 operand *tmp = right ;
4660 if(ifx && !AOP_SIZE(result)){
4662 /* if they are both bit variables */
4663 if (AOP_TYPE(left) == AOP_CRY &&
4664 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4665 if(AOP_TYPE(right) == AOP_LIT){
4666 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4668 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4669 pic14_emitcode("cpl","c");
4670 } else if(lit == 1L) {
4671 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4673 pic14_emitcode("clr","c");
4675 /* AOP_TYPE(right) == AOP_CRY */
4677 symbol *lbl = newiTempLabel(NULL);
4678 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4679 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4680 pic14_emitcode("cpl","c");
4681 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4683 /* if true label then we jump if condition
4685 tlbl = newiTempLabel(NULL);
4686 if ( IC_TRUE(ifx) ) {
4687 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4688 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4690 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4691 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4693 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4696 /* left and right are both bit variables, result is carry */
4699 resolveIfx(&rIfx,ifx);
4701 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4702 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4703 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4704 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4709 /* They're not both bit variables. Is the right a literal? */
4710 if(AOP_TYPE(right) == AOP_LIT) {
4711 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4716 switch(lit & 0xff) {
4718 if ( IC_TRUE(ifx) ) {
4719 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4721 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4723 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4724 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4728 if ( IC_TRUE(ifx) ) {
4729 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4731 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4733 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4734 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4738 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4740 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4745 /* end of size == 1 */
4749 genc16bit2lit(left,lit,offset);
4752 /* end of size == 2 */
4757 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4758 emitpcode(POC_IORFW,popGet(AOP(left),1));
4759 emitpcode(POC_IORFW,popGet(AOP(left),2));
4760 emitpcode(POC_IORFW,popGet(AOP(left),3));
4764 /* search for patterns that can be optimized */
4766 genc16bit2lit(left,lit,0);
4769 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4771 genc16bit2lit(left,lit,2);
4773 emitpcode(POC_IORFW,popGet(AOP(left),2));
4774 emitpcode(POC_IORFW,popGet(AOP(left),3));
4787 } else if(AOP_TYPE(right) == AOP_CRY ) {
4788 /* we know the left is not a bit, but that the right is */
4789 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4790 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4791 popGet(AOP(right),offset));
4792 emitpcode(POC_XORLW,popGetLit(1));
4794 /* if the two are equal, then W will be 0 and the Z bit is set
4795 * we could test Z now, or go ahead and check the high order bytes if
4796 * the variable we're comparing is larger than a byte. */
4799 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4801 if ( IC_TRUE(ifx) ) {
4803 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4804 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4807 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4808 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4812 /* They're both variables that are larger than bits */
4815 tlbl = newiTempLabel(NULL);
4818 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4819 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4821 if ( IC_TRUE(ifx) ) {
4824 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4825 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4828 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4829 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4833 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4834 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4838 if(s>1 && IC_TRUE(ifx)) {
4839 emitpLabel(tlbl->key);
4840 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4844 /* mark the icode as generated */
4849 /* if they are both bit variables */
4850 if (AOP_TYPE(left) == AOP_CRY &&
4851 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4852 if(AOP_TYPE(right) == AOP_LIT){
4853 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4855 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4856 pic14_emitcode("cpl","c");
4857 } else if(lit == 1L) {
4858 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4860 pic14_emitcode("clr","c");
4862 /* AOP_TYPE(right) == AOP_CRY */
4864 symbol *lbl = newiTempLabel(NULL);
4865 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4866 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4867 pic14_emitcode("cpl","c");
4868 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4871 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4872 pic14_outBitC(result);
4876 genIfxJump (ifx,"c");
4879 /* if the result is used in an arithmetic operation
4880 then put the result in place */
4881 pic14_outBitC(result);
4884 gencjne(left,right,result,ifx);
4887 gencjne(left,right,newiTempLabel(NULL));
4889 if(IC_TRUE(ifx)->key)
4890 gencjne(left,right,IC_TRUE(ifx)->key);
4892 gencjne(left,right,IC_FALSE(ifx)->key);
4896 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4897 aopPut(AOP(result),"a",0);
4902 genIfxJump (ifx,"a");
4906 /* if the result is used in an arithmetic operation
4907 then put the result in place */
4909 if (AOP_TYPE(result) != AOP_CRY)
4910 pic14_outAcc(result);
4912 /* leave the result in acc */
4916 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4917 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4918 freeAsmop(result,NULL,ic,TRUE);
4921 /*-----------------------------------------------------------------*/
4922 /* ifxForOp - returns the icode containing the ifx for operand */
4923 /*-----------------------------------------------------------------*/
4924 static iCode *ifxForOp ( operand *op, iCode *ic )
4926 /* if true symbol then needs to be assigned */
4927 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4928 if (IS_TRUE_SYMOP(op))
4931 /* if this has register type condition and
4932 the next instruction is ifx with the same operand
4933 and live to of the operand is upto the ifx only then */
4935 ic->next->op == IFX &&
4936 IC_COND(ic->next)->key == op->key &&
4937 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4941 ic->next->op == IFX &&
4942 IC_COND(ic->next)->key == op->key) {
4943 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4947 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4949 ic->next->op == IFX)
4950 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4953 ic->next->op == IFX &&
4954 IC_COND(ic->next)->key == op->key) {
4955 DEBUGpic14_emitcode ("; "," key is okay");
4956 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4957 OP_SYMBOL(op)->liveTo,
4964 /*-----------------------------------------------------------------*/
4965 /* genAndOp - for && operation */
4966 /*-----------------------------------------------------------------*/
4967 static void genAndOp (iCode *ic)
4969 operand *left,*right, *result;
4972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4973 /* note here that && operations that are in an
4974 if statement are taken away by backPatchLabels
4975 only those used in arthmetic operations remain */
4976 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4977 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4978 aopOp((result=IC_RESULT(ic)),ic,FALSE);
4980 /* if both are bit variables */
4981 if (AOP_TYPE(left) == AOP_CRY &&
4982 AOP_TYPE(right) == AOP_CRY ) {
4983 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4984 pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir);
4985 pic14_outBitC(result);
4987 tlbl = newiTempLabel(NULL);
4988 pic14_toBoolean(left);
4989 pic14_emitcode("jz","%05d_DS_",tlbl->key+100);
4990 pic14_toBoolean(right);
4991 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4992 pic14_outBitAcc(result);
4995 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4996 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4997 freeAsmop(result,NULL,ic,TRUE);
5001 /*-----------------------------------------------------------------*/
5002 /* genOrOp - for || operation */
5003 /*-----------------------------------------------------------------*/
5006 modified this code, but it doesn't appear to ever get called
5009 static void genOrOp (iCode *ic)
5011 operand *left,*right, *result;
5014 /* note here that || operations that are in an
5015 if statement are taken away by backPatchLabels
5016 only those used in arthmetic operations remain */
5017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5018 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5019 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5020 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5022 DEBUGpic14_AopType(__LINE__,left,right,result);
5024 /* if both are bit variables */
5025 if (AOP_TYPE(left) == AOP_CRY &&
5026 AOP_TYPE(right) == AOP_CRY ) {
5027 pic14_emitcode("clrc","");
5028 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5029 AOP(left)->aopu.aop_dir,
5030 AOP(left)->aopu.aop_dir);
5031 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5032 AOP(right)->aopu.aop_dir,
5033 AOP(right)->aopu.aop_dir);
5034 pic14_emitcode("setc","");
5037 tlbl = newiTempLabel(NULL);
5038 pic14_toBoolean(left);
5040 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5041 pic14_toBoolean(right);
5042 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5044 pic14_outBitAcc(result);
5047 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5048 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5049 freeAsmop(result,NULL,ic,TRUE);
5052 /*-----------------------------------------------------------------*/
5053 /* isLiteralBit - test if lit == 2^n */
5054 /*-----------------------------------------------------------------*/
5055 static int isLiteralBit(unsigned long lit)
5057 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5058 0x100L,0x200L,0x400L,0x800L,
5059 0x1000L,0x2000L,0x4000L,0x8000L,
5060 0x10000L,0x20000L,0x40000L,0x80000L,
5061 0x100000L,0x200000L,0x400000L,0x800000L,
5062 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5063 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5067 for(idx = 0; idx < 32; idx++)
5073 /*-----------------------------------------------------------------*/
5074 /* continueIfTrue - */
5075 /*-----------------------------------------------------------------*/
5076 static void continueIfTrue (iCode *ic)
5078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5080 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5084 /*-----------------------------------------------------------------*/
5086 /*-----------------------------------------------------------------*/
5087 static void jumpIfTrue (iCode *ic)
5089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5091 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5095 /*-----------------------------------------------------------------*/
5096 /* jmpTrueOrFalse - */
5097 /*-----------------------------------------------------------------*/
5098 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5100 // ugly but optimized by peephole
5101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5103 symbol *nlbl = newiTempLabel(NULL);
5104 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5105 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5106 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5107 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5110 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5111 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5116 /*-----------------------------------------------------------------*/
5117 /* genAnd - code for and */
5118 /*-----------------------------------------------------------------*/
5119 static void genAnd (iCode *ic, iCode *ifx)
5121 operand *left, *right, *result;
5123 unsigned long lit = 0L;
5128 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5129 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5130 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5131 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5133 resolveIfx(&rIfx,ifx);
5135 /* if left is a literal & right is not then exchange them */
5136 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5137 AOP_NEEDSACC(left)) {
5138 operand *tmp = right ;
5143 /* if result = right then exchange them */
5144 if(pic14_sameRegs(AOP(result),AOP(right))){
5145 operand *tmp = right ;
5150 /* if right is bit then exchange them */
5151 if (AOP_TYPE(right) == AOP_CRY &&
5152 AOP_TYPE(left) != AOP_CRY){
5153 operand *tmp = right ;
5157 if(AOP_TYPE(right) == AOP_LIT)
5158 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5160 size = AOP_SIZE(result);
5162 DEBUGpic14_AopType(__LINE__,left,right,result);
5165 // result = bit & yy;
5166 if (AOP_TYPE(left) == AOP_CRY){
5167 // c = bit & literal;
5168 if(AOP_TYPE(right) == AOP_LIT){
5170 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5173 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5176 if(size && (AOP_TYPE(result) == AOP_CRY)){
5177 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5180 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5184 pic14_emitcode("clr","c");
5187 if (AOP_TYPE(right) == AOP_CRY){
5189 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5190 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5193 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5195 pic14_emitcode("rrc","a");
5196 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5202 pic14_outBitC(result);
5204 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5205 genIfxJump(ifx, "c");
5209 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5210 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5211 if((AOP_TYPE(right) == AOP_LIT) &&
5212 (AOP_TYPE(result) == AOP_CRY) &&
5213 (AOP_TYPE(left) != AOP_CRY)){
5214 int posbit = isLiteralBit(lit);
5218 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5221 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5227 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5228 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5230 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5231 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5234 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5235 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5236 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5243 symbol *tlbl = newiTempLabel(NULL);
5244 int sizel = AOP_SIZE(left);
5246 pic14_emitcode("setb","c");
5248 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5249 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5251 if((posbit = isLiteralBit(bytelit)) != 0)
5252 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5254 if(bytelit != 0x0FFL)
5255 pic14_emitcode("anl","a,%s",
5256 aopGet(AOP(right),offset,FALSE,TRUE));
5257 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5262 // bit = left & literal
5264 pic14_emitcode("clr","c");
5265 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5267 // if(left & literal)
5270 jmpTrueOrFalse(ifx, tlbl);
5274 pic14_outBitC(result);
5278 /* if left is same as result */
5279 if(pic14_sameRegs(AOP(result),AOP(left))){
5281 for(;size--; offset++,lit>>=8) {
5282 if(AOP_TYPE(right) == AOP_LIT){
5283 switch(lit & 0xff) {
5285 /* and'ing with 0 has clears the result */
5286 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5287 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5290 /* and'ing with 0xff is a nop when the result and left are the same */
5295 int p = my_powof2( (~lit) & 0xff );
5297 /* only one bit is set in the literal, so use a bcf instruction */
5298 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5299 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5302 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5303 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5304 if(know_W != (lit&0xff))
5305 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5307 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5312 if (AOP_TYPE(left) == AOP_ACC) {
5313 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5315 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5316 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5323 // left & result in different registers
5324 if(AOP_TYPE(result) == AOP_CRY){
5326 // if(size), result in bit
5327 // if(!size && ifx), conditional oper: if(left & right)
5328 symbol *tlbl = newiTempLabel(NULL);
5329 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5331 pic14_emitcode("setb","c");
5333 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5334 pic14_emitcode("anl","a,%s",
5335 aopGet(AOP(left),offset,FALSE,FALSE));
5336 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5341 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5342 pic14_outBitC(result);
5344 jmpTrueOrFalse(ifx, tlbl);
5346 for(;(size--);offset++) {
5348 // result = left & right
5349 if(AOP_TYPE(right) == AOP_LIT){
5350 int t = (lit >> (offset*8)) & 0x0FFL;
5353 pic14_emitcode("clrf","%s",
5354 aopGet(AOP(result),offset,FALSE,FALSE));
5355 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5358 pic14_emitcode("movf","%s,w",
5359 aopGet(AOP(left),offset,FALSE,FALSE));
5360 pic14_emitcode("movwf","%s",
5361 aopGet(AOP(result),offset,FALSE,FALSE));
5362 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5363 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5366 pic14_emitcode("movlw","0x%x",t);
5367 pic14_emitcode("andwf","%s,w",
5368 aopGet(AOP(left),offset,FALSE,FALSE));
5369 pic14_emitcode("movwf","%s",
5370 aopGet(AOP(result),offset,FALSE,FALSE));
5372 emitpcode(POC_MOVLW, popGetLit(t));
5373 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5374 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5379 if (AOP_TYPE(left) == AOP_ACC) {
5380 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5381 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5383 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5384 pic14_emitcode("andwf","%s,w",
5385 aopGet(AOP(left),offset,FALSE,FALSE));
5386 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5387 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5389 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5390 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5396 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5397 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5398 freeAsmop(result,NULL,ic,TRUE);
5401 /*-----------------------------------------------------------------*/
5402 /* genOr - code for or */
5403 /*-----------------------------------------------------------------*/
5404 static void genOr (iCode *ic, iCode *ifx)
5406 operand *left, *right, *result;
5408 unsigned long lit = 0L;
5410 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5412 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5413 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5414 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5416 DEBUGpic14_AopType(__LINE__,left,right,result);
5418 /* if left is a literal & right is not then exchange them */
5419 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5420 AOP_NEEDSACC(left)) {
5421 operand *tmp = right ;
5426 /* if result = right then exchange them */
5427 if(pic14_sameRegs(AOP(result),AOP(right))){
5428 operand *tmp = right ;
5433 /* if right is bit then exchange them */
5434 if (AOP_TYPE(right) == AOP_CRY &&
5435 AOP_TYPE(left) != AOP_CRY){
5436 operand *tmp = right ;
5441 DEBUGpic14_AopType(__LINE__,left,right,result);
5443 if(AOP_TYPE(right) == AOP_LIT)
5444 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5446 size = AOP_SIZE(result);
5450 if (AOP_TYPE(left) == AOP_CRY){
5451 if(AOP_TYPE(right) == AOP_LIT){
5452 // c = bit & literal;
5454 // lit != 0 => result = 1
5455 if(AOP_TYPE(result) == AOP_CRY){
5457 emitpcode(POC_BSF, popGet(AOP(result),0));
5458 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5459 // AOP(result)->aopu.aop_dir,
5460 // AOP(result)->aopu.aop_dir);
5462 continueIfTrue(ifx);
5466 // lit == 0 => result = left
5467 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5469 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5472 if (AOP_TYPE(right) == AOP_CRY){
5473 if(pic14_sameRegs(AOP(result),AOP(left))){
5475 emitpcode(POC_BCF, popGet(AOP(result),0));
5476 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5477 emitpcode(POC_BSF, popGet(AOP(result),0));
5479 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5480 AOP(result)->aopu.aop_dir,
5481 AOP(result)->aopu.aop_dir);
5482 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5483 AOP(right)->aopu.aop_dir,
5484 AOP(right)->aopu.aop_dir);
5485 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5486 AOP(result)->aopu.aop_dir,
5487 AOP(result)->aopu.aop_dir);
5489 if( AOP_TYPE(result) == AOP_ACC) {
5490 emitpcode(POC_MOVLW, popGetLit(0));
5491 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5492 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5493 emitpcode(POC_MOVLW, popGetLit(1));
5497 emitpcode(POC_BCF, popGet(AOP(result),0));
5498 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5499 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5500 emitpcode(POC_BSF, popGet(AOP(result),0));
5502 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5503 AOP(result)->aopu.aop_dir,
5504 AOP(result)->aopu.aop_dir);
5505 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5506 AOP(right)->aopu.aop_dir,
5507 AOP(right)->aopu.aop_dir);
5508 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5509 AOP(left)->aopu.aop_dir,
5510 AOP(left)->aopu.aop_dir);
5511 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5512 AOP(result)->aopu.aop_dir,
5513 AOP(result)->aopu.aop_dir);
5518 symbol *tlbl = newiTempLabel(NULL);
5519 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5522 emitpcode(POC_BCF, popGet(AOP(result),0));
5523 if( AOP_TYPE(right) == AOP_ACC) {
5524 emitpcode(POC_IORLW, popGetLit(0));
5526 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5527 emitpcode(POC_BSF, popGet(AOP(result),0));
5532 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5533 pic14_emitcode(";XXX setb","c");
5534 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5535 AOP(left)->aopu.aop_dir,tlbl->key+100);
5536 pic14_toBoolean(right);
5537 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5538 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5539 jmpTrueOrFalse(ifx, tlbl);
5543 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5550 pic14_outBitC(result);
5552 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5553 genIfxJump(ifx, "c");
5557 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5558 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5559 if((AOP_TYPE(right) == AOP_LIT) &&
5560 (AOP_TYPE(result) == AOP_CRY) &&
5561 (AOP_TYPE(left) != AOP_CRY)){
5563 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5566 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5568 continueIfTrue(ifx);
5571 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5572 // lit = 0, result = boolean(left)
5574 pic14_emitcode(";XXX setb","c");
5575 pic14_toBoolean(right);
5577 symbol *tlbl = newiTempLabel(NULL);
5578 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5580 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5582 genIfxJump (ifx,"a");
5586 pic14_outBitC(result);
5590 /* if left is same as result */
5591 if(pic14_sameRegs(AOP(result),AOP(left))){
5593 for(;size--; offset++,lit>>=8) {
5594 if(AOP_TYPE(right) == AOP_LIT){
5595 if((lit & 0xff) == 0)
5596 /* or'ing with 0 has no effect */
5599 int p = my_powof2(lit & 0xff);
5601 /* only one bit is set in the literal, so use a bsf instruction */
5603 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5605 if(know_W != (lit & 0xff))
5606 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5607 know_W = lit & 0xff;
5608 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5613 if (AOP_TYPE(left) == AOP_ACC) {
5614 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5615 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5617 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5618 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5620 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5621 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5627 // left & result in different registers
5628 if(AOP_TYPE(result) == AOP_CRY){
5630 // if(size), result in bit
5631 // if(!size && ifx), conditional oper: if(left | right)
5632 symbol *tlbl = newiTempLabel(NULL);
5633 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5634 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5638 pic14_emitcode(";XXX setb","c");
5640 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5641 pic14_emitcode(";XXX orl","a,%s",
5642 aopGet(AOP(left),offset,FALSE,FALSE));
5643 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5648 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5649 pic14_outBitC(result);
5651 jmpTrueOrFalse(ifx, tlbl);
5652 } else for(;(size--);offset++){
5654 // result = left & right
5655 if(AOP_TYPE(right) == AOP_LIT){
5656 int t = (lit >> (offset*8)) & 0x0FFL;
5659 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5660 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5662 pic14_emitcode("movf","%s,w",
5663 aopGet(AOP(left),offset,FALSE,FALSE));
5664 pic14_emitcode("movwf","%s",
5665 aopGet(AOP(result),offset,FALSE,FALSE));
5668 emitpcode(POC_MOVLW, popGetLit(t));
5669 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5670 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5672 pic14_emitcode("movlw","0x%x",t);
5673 pic14_emitcode("iorwf","%s,w",
5674 aopGet(AOP(left),offset,FALSE,FALSE));
5675 pic14_emitcode("movwf","%s",
5676 aopGet(AOP(result),offset,FALSE,FALSE));
5682 // faster than result <- left, anl result,right
5683 // and better if result is SFR
5684 if (AOP_TYPE(left) == AOP_ACC) {
5685 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5686 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5688 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5689 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5691 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5692 pic14_emitcode("iorwf","%s,w",
5693 aopGet(AOP(left),offset,FALSE,FALSE));
5695 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5696 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5701 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5702 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5703 freeAsmop(result,NULL,ic,TRUE);
5706 /*-----------------------------------------------------------------*/
5707 /* genXor - code for xclusive or */
5708 /*-----------------------------------------------------------------*/
5709 static void genXor (iCode *ic, iCode *ifx)
5711 operand *left, *right, *result;
5713 unsigned long lit = 0L;
5715 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5717 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5718 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5719 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5721 /* if left is a literal & right is not ||
5722 if left needs acc & right does not */
5723 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5724 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5725 operand *tmp = right ;
5730 /* if result = right then exchange them */
5731 if(pic14_sameRegs(AOP(result),AOP(right))){
5732 operand *tmp = right ;
5737 /* if right is bit then exchange them */
5738 if (AOP_TYPE(right) == AOP_CRY &&
5739 AOP_TYPE(left) != AOP_CRY){
5740 operand *tmp = right ;
5744 if(AOP_TYPE(right) == AOP_LIT)
5745 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5747 size = AOP_SIZE(result);
5751 if (AOP_TYPE(left) == AOP_CRY){
5752 if(AOP_TYPE(right) == AOP_LIT){
5753 // c = bit & literal;
5755 // lit>>1 != 0 => result = 1
5756 if(AOP_TYPE(result) == AOP_CRY){
5758 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5759 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5761 continueIfTrue(ifx);
5764 pic14_emitcode("setb","c");
5768 // lit == 0, result = left
5769 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5771 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5773 // lit == 1, result = not(left)
5774 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5775 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5776 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5777 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5780 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5781 pic14_emitcode("cpl","c");
5788 symbol *tlbl = newiTempLabel(NULL);
5789 if (AOP_TYPE(right) == AOP_CRY){
5791 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5794 int sizer = AOP_SIZE(right);
5796 // if val>>1 != 0, result = 1
5797 pic14_emitcode("setb","c");
5799 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5801 // test the msb of the lsb
5802 pic14_emitcode("anl","a,#0xfe");
5803 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5807 pic14_emitcode("rrc","a");
5809 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5810 pic14_emitcode("cpl","c");
5811 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5816 pic14_outBitC(result);
5818 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5819 genIfxJump(ifx, "c");
5823 if(pic14_sameRegs(AOP(result),AOP(left))){
5824 /* if left is same as result */
5825 for(;size--; offset++) {
5826 if(AOP_TYPE(right) == AOP_LIT){
5827 int t = (lit >> (offset*8)) & 0x0FFL;
5831 if (IS_AOP_PREG(left)) {
5832 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5833 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5834 aopPut(AOP(result),"a",offset);
5836 emitpcode(POC_MOVLW, popGetLit(t));
5837 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5838 pic14_emitcode("xrl","%s,%s",
5839 aopGet(AOP(left),offset,FALSE,TRUE),
5840 aopGet(AOP(right),offset,FALSE,FALSE));
5843 if (AOP_TYPE(left) == AOP_ACC)
5844 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5846 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5847 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5849 if (IS_AOP_PREG(left)) {
5850 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5851 aopPut(AOP(result),"a",offset);
5853 pic14_emitcode("xrl","%s,a",
5854 aopGet(AOP(left),offset,FALSE,TRUE));
5860 // left & result in different registers
5861 if(AOP_TYPE(result) == AOP_CRY){
5863 // if(size), result in bit
5864 // if(!size && ifx), conditional oper: if(left ^ right)
5865 symbol *tlbl = newiTempLabel(NULL);
5866 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5868 pic14_emitcode("setb","c");
5870 if((AOP_TYPE(right) == AOP_LIT) &&
5871 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5872 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5874 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5875 pic14_emitcode("xrl","a,%s",
5876 aopGet(AOP(left),offset,FALSE,FALSE));
5878 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5883 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5884 pic14_outBitC(result);
5886 jmpTrueOrFalse(ifx, tlbl);
5887 } else for(;(size--);offset++){
5889 // result = left & right
5890 if(AOP_TYPE(right) == AOP_LIT){
5891 int t = (lit >> (offset*8)) & 0x0FFL;
5894 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5895 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5896 pic14_emitcode("movf","%s,w",
5897 aopGet(AOP(left),offset,FALSE,FALSE));
5898 pic14_emitcode("movwf","%s",
5899 aopGet(AOP(result),offset,FALSE,FALSE));
5902 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5903 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5904 pic14_emitcode("comf","%s,w",
5905 aopGet(AOP(left),offset,FALSE,FALSE));
5906 pic14_emitcode("movwf","%s",
5907 aopGet(AOP(result),offset,FALSE,FALSE));
5910 emitpcode(POC_MOVLW, popGetLit(t));
5911 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5912 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5913 pic14_emitcode("movlw","0x%x",t);
5914 pic14_emitcode("xorwf","%s,w",
5915 aopGet(AOP(left),offset,FALSE,FALSE));
5916 pic14_emitcode("movwf","%s",
5917 aopGet(AOP(result),offset,FALSE,FALSE));
5923 // faster than result <- left, anl result,right
5924 // and better if result is SFR
5925 if (AOP_TYPE(left) == AOP_ACC) {
5926 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5927 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5929 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5930 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5931 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5932 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5934 if ( AOP_TYPE(result) != AOP_ACC){
5935 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5936 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5942 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5943 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5944 freeAsmop(result,NULL,ic,TRUE);
5947 /*-----------------------------------------------------------------*/
5948 /* genInline - write the inline code out */
5949 /*-----------------------------------------------------------------*/
5950 static void genInline (iCode *ic)
5952 char *buffer, *bp, *bp1;
5954 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5956 _G.inLine += (!options.asmpeep);
5958 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5959 strcpy(buffer,IC_INLINE(ic));
5961 /* emit each line as a code */
5965 pic14_emitcode(bp1,"");
5966 addpCode2pBlock(pb,newpCodeInlineP(bp1));
5973 pic14_emitcode(bp1,"");
5980 pic14_emitcode(bp1,"");
5981 addpCode2pBlock(pb,newpCodeInlineP(bp1));
5983 /* pic14_emitcode("",buffer); */
5984 _G.inLine -= (!options.asmpeep);
5987 /*-----------------------------------------------------------------*/
5988 /* genRRC - rotate right with carry */
5989 /*-----------------------------------------------------------------*/
5990 static void genRRC (iCode *ic)
5992 operand *left , *result ;
5993 int size, offset = 0, same;
5995 /* rotate right with carry */
5997 result=IC_RESULT(ic);
5998 aopOp (left,ic,FALSE);
5999 aopOp (result,ic,FALSE);
6001 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6003 same = pic14_sameRegs(AOP(result),AOP(left));
6005 size = AOP_SIZE(result);
6007 /* get the lsb and put it into the carry */
6008 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6015 emitpcode(POC_RRF, popGet(AOP(left),offset));
6017 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6018 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6024 freeAsmop(left,NULL,ic,TRUE);
6025 freeAsmop(result,NULL,ic,TRUE);
6028 /*-----------------------------------------------------------------*/
6029 /* genRLC - generate code for rotate left with carry */
6030 /*-----------------------------------------------------------------*/
6031 static void genRLC (iCode *ic)
6033 operand *left , *result ;
6034 int size, offset = 0;
6037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6038 /* rotate right with carry */
6040 result=IC_RESULT(ic);
6041 aopOp (left,ic,FALSE);
6042 aopOp (result,ic,FALSE);
6044 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6046 same = pic14_sameRegs(AOP(result),AOP(left));
6048 /* move it to the result */
6049 size = AOP_SIZE(result);
6051 /* get the msb and put it into the carry */
6052 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6059 emitpcode(POC_RLF, popGet(AOP(left),offset));
6061 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6062 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6069 freeAsmop(left,NULL,ic,TRUE);
6070 freeAsmop(result,NULL,ic,TRUE);
6073 /*-----------------------------------------------------------------*/
6074 /* genGetHbit - generates code get highest order bit */
6075 /*-----------------------------------------------------------------*/
6076 static void genGetHbit (iCode *ic)
6078 operand *left, *result;
6080 result=IC_RESULT(ic);
6081 aopOp (left,ic,FALSE);
6082 aopOp (result,ic,FALSE);
6084 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6085 /* get the highest order byte into a */
6086 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6087 if(AOP_TYPE(result) == AOP_CRY){
6088 pic14_emitcode("rlc","a");
6089 pic14_outBitC(result);
6092 pic14_emitcode("rl","a");
6093 pic14_emitcode("anl","a,#0x01");
6094 pic14_outAcc(result);
6098 freeAsmop(left,NULL,ic,TRUE);
6099 freeAsmop(result,NULL,ic,TRUE);
6102 /*-----------------------------------------------------------------*/
6103 /* AccRol - rotate left accumulator by known count */
6104 /*-----------------------------------------------------------------*/
6105 static void AccRol (int shCount)
6107 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6108 shCount &= 0x0007; // shCount : 0..7
6113 pic14_emitcode("rl","a");
6116 pic14_emitcode("rl","a");
6117 pic14_emitcode("rl","a");
6120 pic14_emitcode("swap","a");
6121 pic14_emitcode("rr","a");
6124 pic14_emitcode("swap","a");
6127 pic14_emitcode("swap","a");
6128 pic14_emitcode("rl","a");
6131 pic14_emitcode("rr","a");
6132 pic14_emitcode("rr","a");
6135 pic14_emitcode("rr","a");
6140 /*-----------------------------------------------------------------*/
6141 /* AccLsh - left shift accumulator by known count */
6142 /*-----------------------------------------------------------------*/
6143 static void AccLsh (int shCount)
6145 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6148 pic14_emitcode("add","a,acc");
6151 pic14_emitcode("add","a,acc");
6152 pic14_emitcode("add","a,acc");
6154 /* rotate left accumulator */
6156 /* and kill the lower order bits */
6157 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6162 /*-----------------------------------------------------------------*/
6163 /* AccRsh - right shift accumulator by known count */
6164 /*-----------------------------------------------------------------*/
6165 static void AccRsh (int shCount)
6167 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6171 pic14_emitcode("rrc","a");
6173 /* rotate right accumulator */
6174 AccRol(8 - shCount);
6175 /* and kill the higher order bits */
6176 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6182 /*-----------------------------------------------------------------*/
6183 /* AccSRsh - signed right shift accumulator by known count */
6184 /*-----------------------------------------------------------------*/
6185 static void AccSRsh (int shCount)
6188 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6191 pic14_emitcode("mov","c,acc.7");
6192 pic14_emitcode("rrc","a");
6193 } else if(shCount == 2){
6194 pic14_emitcode("mov","c,acc.7");
6195 pic14_emitcode("rrc","a");
6196 pic14_emitcode("mov","c,acc.7");
6197 pic14_emitcode("rrc","a");
6199 tlbl = newiTempLabel(NULL);
6200 /* rotate right accumulator */
6201 AccRol(8 - shCount);
6202 /* and kill the higher order bits */
6203 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6204 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6205 pic14_emitcode("orl","a,#0x%02x",
6206 (unsigned char)~SRMask[shCount]);
6207 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6212 /*-----------------------------------------------------------------*/
6213 /* shiftR1Left2Result - shift right one byte from left to result */
6214 /*-----------------------------------------------------------------*/
6215 static void shiftR1Left2ResultSigned (operand *left, int offl,
6216 operand *result, int offr,
6221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6223 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6227 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6229 emitpcode(POC_RRF, popGet(AOP(result),offr));
6231 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6232 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6238 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6240 emitpcode(POC_RRF, popGet(AOP(result),offr));
6242 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6243 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6245 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6246 emitpcode(POC_RRF, popGet(AOP(result),offr));
6252 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6254 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6255 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6258 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6259 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6260 emitpcode(POC_ANDLW, popGetLit(0x1f));
6262 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6263 emitpcode(POC_IORLW, popGetLit(0xe0));
6265 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6269 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6270 emitpcode(POC_ANDLW, popGetLit(0x0f));
6271 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6272 emitpcode(POC_IORLW, popGetLit(0xf0));
6273 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6277 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6279 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6280 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6282 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6283 emitpcode(POC_ANDLW, popGetLit(0x07));
6284 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6285 emitpcode(POC_IORLW, popGetLit(0xf8));
6286 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6291 emitpcode(POC_MOVLW, popGetLit(0x00));
6292 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6293 emitpcode(POC_MOVLW, popGetLit(0xfe));
6294 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6295 emitpcode(POC_IORLW, popGetLit(0x01));
6296 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6298 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6299 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6300 emitpcode(POC_DECF, popGet(AOP(result),offr));
6301 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6302 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6308 emitpcode(POC_MOVLW, popGetLit(0x00));
6309 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6310 emitpcode(POC_MOVLW, popGetLit(0xff));
6311 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6313 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6314 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6315 emitpcode(POC_DECF, popGet(AOP(result),offr));
6323 /*-----------------------------------------------------------------*/
6324 /* shiftR1Left2Result - shift right one byte from left to result */
6325 /*-----------------------------------------------------------------*/
6326 static void shiftR1Left2Result (operand *left, int offl,
6327 operand *result, int offr,
6328 int shCount, int sign)
6332 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6334 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6336 /* Copy the msb into the carry if signed. */
6338 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6348 emitpcode(POC_RRF, popGet(AOP(result),offr));
6350 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6351 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6357 emitpcode(POC_RRF, popGet(AOP(result),offr));
6359 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6360 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6363 emitpcode(POC_RRF, popGet(AOP(result),offr));
6368 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6370 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6371 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6374 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6375 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6376 emitpcode(POC_ANDLW, popGetLit(0x1f));
6377 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6381 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6382 emitpcode(POC_ANDLW, popGetLit(0x0f));
6383 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6387 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6388 emitpcode(POC_ANDLW, popGetLit(0x0f));
6389 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6391 emitpcode(POC_RRF, popGet(AOP(result),offr));
6396 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6397 emitpcode(POC_ANDLW, popGetLit(0x80));
6398 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6399 emitpcode(POC_RLF, popGet(AOP(result),offr));
6400 emitpcode(POC_RLF, popGet(AOP(result),offr));
6405 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6406 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6407 emitpcode(POC_RLF, popGet(AOP(result),offr));
6416 /*-----------------------------------------------------------------*/
6417 /* shiftL1Left2Result - shift left one byte from left to result */
6418 /*-----------------------------------------------------------------*/
6419 static void shiftL1Left2Result (operand *left, int offl,
6420 operand *result, int offr, int shCount)
6425 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6427 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6428 DEBUGpic14_emitcode ("; ***","same = %d",same);
6429 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6431 /* shift left accumulator */
6432 //AccLsh(shCount); // don't comment out just yet...
6433 // aopPut(AOP(result),"a",offr);
6437 /* Shift left 1 bit position */
6438 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6440 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6442 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6443 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6447 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6448 emitpcode(POC_ANDLW,popGetLit(0x7e));
6449 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6450 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6453 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6454 emitpcode(POC_ANDLW,popGetLit(0x3e));
6455 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6456 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6457 emitpcode(POC_RLF, popGet(AOP(result),offr));
6460 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6461 emitpcode(POC_ANDLW, popGetLit(0xf0));
6462 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6465 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6466 emitpcode(POC_ANDLW, popGetLit(0xf0));
6467 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6468 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6471 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6472 emitpcode(POC_ANDLW, popGetLit(0x30));
6473 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6474 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6475 emitpcode(POC_RLF, popGet(AOP(result),offr));
6478 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6479 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6480 emitpcode(POC_RRF, popGet(AOP(result),offr));
6484 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6489 /*-----------------------------------------------------------------*/
6490 /* movLeft2Result - move byte from left to result */
6491 /*-----------------------------------------------------------------*/
6492 static void movLeft2Result (operand *left, int offl,
6493 operand *result, int offr)
6496 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6497 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6498 l = aopGet(AOP(left),offl,FALSE,FALSE);
6500 if (*l == '@' && (IS_AOP_PREG(result))) {
6501 pic14_emitcode("mov","a,%s",l);
6502 aopPut(AOP(result),"a",offr);
6504 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6505 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6510 /*-----------------------------------------------------------------*/
6511 /* shiftL2Left2Result - shift left two bytes from left to result */
6512 /*-----------------------------------------------------------------*/
6513 static void shiftL2Left2Result (operand *left, int offl,
6514 operand *result, int offr, int shCount)
6518 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6520 if(pic14_sameRegs(AOP(result), AOP(left))) {
6528 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6529 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6530 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6534 emitpcode(POC_RLF, popGet(AOP(result),offr));
6535 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6541 emitpcode(POC_MOVLW, popGetLit(0x0f));
6542 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6543 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6544 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6545 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6546 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6547 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6549 emitpcode(POC_RLF, popGet(AOP(result),offr));
6550 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6554 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6555 emitpcode(POC_RRF, popGet(AOP(result),offr));
6556 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6557 emitpcode(POC_RRF, popGet(AOP(result),offr));
6558 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6559 emitpcode(POC_ANDLW,popGetLit(0xc0));
6560 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6561 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6562 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6563 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6566 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6567 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6568 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6569 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6570 emitpcode(POC_RRF, popGet(AOP(result),offr));
6580 /* note, use a mov/add for the shift since the mov has a
6581 chance of getting optimized out */
6582 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6583 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6584 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6585 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6586 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6590 emitpcode(POC_RLF, popGet(AOP(result),offr));
6591 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6597 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6598 emitpcode(POC_ANDLW, popGetLit(0xF0));
6599 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6600 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6601 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6602 emitpcode(POC_ANDLW, popGetLit(0xF0));
6603 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6604 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6608 emitpcode(POC_RLF, popGet(AOP(result),offr));
6609 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6613 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6614 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6615 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6616 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6618 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6619 emitpcode(POC_RRF, popGet(AOP(result),offr));
6620 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6621 emitpcode(POC_ANDLW,popGetLit(0xc0));
6622 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6623 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6624 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6625 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6628 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6629 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6630 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6631 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6632 emitpcode(POC_RRF, popGet(AOP(result),offr));
6637 /*-----------------------------------------------------------------*/
6638 /* shiftR2Left2Result - shift right two bytes from left to result */
6639 /*-----------------------------------------------------------------*/
6640 static void shiftR2Left2Result (operand *left, int offl,
6641 operand *result, int offr,
6642 int shCount, int sign)
6646 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6647 same = pic14_sameRegs(AOP(result), AOP(left));
6649 if(same && ((offl + MSB16) == offr)){
6651 /* don't crash result[offr] */
6652 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6653 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6655 movLeft2Result(left,offl, result, offr);
6656 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6658 /* a:x >> shCount (x = lsb(result))*/
6661 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6663 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6672 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6677 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6678 emitpcode(POC_RRF,popGet(AOP(result),offr));
6680 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6681 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6683 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6688 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6691 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6692 emitpcode(POC_RRF,popGet(AOP(result),offr));
6699 emitpcode(POC_MOVLW, popGetLit(0xf0));
6700 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6701 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6703 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6704 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6705 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6706 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6708 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6709 emitpcode(POC_ANDLW, popGetLit(0x0f));
6710 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6712 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6713 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6714 emitpcode(POC_ANDLW, popGetLit(0xf0));
6715 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6716 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6720 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6721 emitpcode(POC_RRF, popGet(AOP(result),offr));
6725 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6726 emitpcode(POC_BTFSC,
6727 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6728 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_RLF, popGet(AOP(result),offr));
6737 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_RLF, popGet(AOP(result),offr));
6740 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6741 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6742 emitpcode(POC_ANDLW,popGetLit(0x03));
6744 emitpcode(POC_BTFSC,
6745 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6746 emitpcode(POC_IORLW,popGetLit(0xfc));
6748 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6749 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6751 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6753 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6754 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6756 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6757 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6758 emitpcode(POC_ANDLW,popGetLit(0x03));
6760 emitpcode(POC_BTFSC,
6761 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6762 emitpcode(POC_IORLW,popGetLit(0xfc));
6764 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6765 emitpcode(POC_RLF, popGet(AOP(result),offr));
6772 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6773 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6774 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6775 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6778 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6780 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6785 /*-----------------------------------------------------------------*/
6786 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6787 /*-----------------------------------------------------------------*/
6788 static void shiftLLeftOrResult (operand *left, int offl,
6789 operand *result, int offr, int shCount)
6791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6792 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6793 /* shift left accumulator */
6795 /* or with result */
6796 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6797 /* back to result */
6798 aopPut(AOP(result),"a",offr);
6801 /*-----------------------------------------------------------------*/
6802 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6803 /*-----------------------------------------------------------------*/
6804 static void shiftRLeftOrResult (operand *left, int offl,
6805 operand *result, int offr, int shCount)
6807 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6808 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6809 /* shift right accumulator */
6811 /* or with result */
6812 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6813 /* back to result */
6814 aopPut(AOP(result),"a",offr);
6817 /*-----------------------------------------------------------------*/
6818 /* genlshOne - left shift a one byte quantity by known count */
6819 /*-----------------------------------------------------------------*/
6820 static void genlshOne (operand *result, operand *left, int shCount)
6822 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6823 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6826 /*-----------------------------------------------------------------*/
6827 /* genlshTwo - left shift two bytes by known amount != 0 */
6828 /*-----------------------------------------------------------------*/
6829 static void genlshTwo (operand *result,operand *left, int shCount)
6833 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6834 size = pic14_getDataSize(result);
6836 /* if shCount >= 8 */
6842 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6844 movLeft2Result(left, LSB, result, MSB16);
6846 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6849 /* 1 <= shCount <= 7 */
6852 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6854 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6858 /*-----------------------------------------------------------------*/
6859 /* shiftLLong - shift left one long from left to result */
6860 /* offl = LSB or MSB16 */
6861 /*-----------------------------------------------------------------*/
6862 static void shiftLLong (operand *left, operand *result, int offr )
6865 int size = AOP_SIZE(result);
6867 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6868 if(size >= LSB+offr){
6869 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6871 pic14_emitcode("add","a,acc");
6872 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6873 size >= MSB16+offr && offr != LSB )
6874 pic14_emitcode("xch","a,%s",
6875 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6877 aopPut(AOP(result),"a",LSB+offr);
6880 if(size >= MSB16+offr){
6881 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6882 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6885 pic14_emitcode("rlc","a");
6886 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6887 size >= MSB24+offr && offr != LSB)
6888 pic14_emitcode("xch","a,%s",
6889 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6891 aopPut(AOP(result),"a",MSB16+offr);
6894 if(size >= MSB24+offr){
6895 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6896 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6899 pic14_emitcode("rlc","a");
6900 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6901 size >= MSB32+offr && offr != LSB )
6902 pic14_emitcode("xch","a,%s",
6903 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6905 aopPut(AOP(result),"a",MSB24+offr);
6908 if(size > MSB32+offr){
6909 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6910 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6913 pic14_emitcode("rlc","a");
6914 aopPut(AOP(result),"a",MSB32+offr);
6917 aopPut(AOP(result),zero,LSB);
6920 /*-----------------------------------------------------------------*/
6921 /* genlshFour - shift four byte by a known amount != 0 */
6922 /*-----------------------------------------------------------------*/
6923 static void genlshFour (operand *result, operand *left, int shCount)
6927 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6928 size = AOP_SIZE(result);
6930 /* if shifting more that 3 bytes */
6931 if (shCount >= 24 ) {
6934 /* lowest order of left goes to the highest
6935 order of the destination */
6936 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6938 movLeft2Result(left, LSB, result, MSB32);
6939 aopPut(AOP(result),zero,LSB);
6940 aopPut(AOP(result),zero,MSB16);
6941 aopPut(AOP(result),zero,MSB32);
6945 /* more than two bytes */
6946 else if ( shCount >= 16 ) {
6947 /* lower order two bytes goes to higher order two bytes */
6949 /* if some more remaining */
6951 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6953 movLeft2Result(left, MSB16, result, MSB32);
6954 movLeft2Result(left, LSB, result, MSB24);
6956 aopPut(AOP(result),zero,MSB16);
6957 aopPut(AOP(result),zero,LSB);
6961 /* if more than 1 byte */
6962 else if ( shCount >= 8 ) {
6963 /* lower order three bytes goes to higher order three bytes */
6967 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6969 movLeft2Result(left, LSB, result, MSB16);
6971 else{ /* size = 4 */
6973 movLeft2Result(left, MSB24, result, MSB32);
6974 movLeft2Result(left, MSB16, result, MSB24);
6975 movLeft2Result(left, LSB, result, MSB16);
6976 aopPut(AOP(result),zero,LSB);
6978 else if(shCount == 1)
6979 shiftLLong(left, result, MSB16);
6981 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
6982 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6983 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
6984 aopPut(AOP(result),zero,LSB);
6989 /* 1 <= shCount <= 7 */
6990 else if(shCount <= 2){
6991 shiftLLong(left, result, LSB);
6993 shiftLLong(result, result, LSB);
6995 /* 3 <= shCount <= 7, optimize */
6997 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
6998 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
6999 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7003 /*-----------------------------------------------------------------*/
7004 /* genLeftShiftLiteral - left shifting by known count */
7005 /*-----------------------------------------------------------------*/
7006 static void genLeftShiftLiteral (operand *left,
7011 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7014 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7015 freeAsmop(right,NULL,ic,TRUE);
7017 aopOp(left,ic,FALSE);
7018 aopOp(result,ic,FALSE);
7020 size = getSize(operandType(result));
7023 pic14_emitcode("; shift left ","result %d, left %d",size,
7027 /* I suppose that the left size >= result size */
7030 movLeft2Result(left, size, result, size);
7034 else if(shCount >= (size * 8))
7036 aopPut(AOP(result),zero,size);
7040 genlshOne (result,left,shCount);
7045 genlshTwo (result,left,shCount);
7049 genlshFour (result,left,shCount);
7053 freeAsmop(left,NULL,ic,TRUE);
7054 freeAsmop(result,NULL,ic,TRUE);
7057 /*-----------------------------------------------------------------*
7058 * genMultiAsm - repeat assembly instruction for size of register.
7059 * if endian == 1, then the high byte (i.e base address + size of
7060 * register) is used first else the low byte is used first;
7061 *-----------------------------------------------------------------*/
7062 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7067 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7080 emitpcode(poc, popGet(AOP(reg),offset));
7085 /*-----------------------------------------------------------------*/
7086 /* genLeftShift - generates code for left shifting */
7087 /*-----------------------------------------------------------------*/
7088 static void genLeftShift (iCode *ic)
7090 operand *left,*right, *result;
7093 symbol *tlbl , *tlbl1;
7096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7098 right = IC_RIGHT(ic);
7100 result = IC_RESULT(ic);
7102 aopOp(right,ic,FALSE);
7104 /* if the shift count is known then do it
7105 as efficiently as possible */
7106 if (AOP_TYPE(right) == AOP_LIT) {
7107 genLeftShiftLiteral (left,right,result,ic);
7111 /* shift count is unknown then we have to form
7112 a loop get the loop count in B : Note: we take
7113 only the lower order byte since shifting
7114 more that 32 bits make no sense anyway, ( the
7115 largest size of an object can be only 32 bits ) */
7118 aopOp(left,ic,FALSE);
7119 aopOp(result,ic,FALSE);
7121 /* now move the left to the result if they are not the
7123 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7124 AOP_SIZE(result) > 1) {
7126 size = AOP_SIZE(result);
7129 l = aopGet(AOP(left),offset,FALSE,TRUE);
7130 if (*l == '@' && (IS_AOP_PREG(result))) {
7132 pic14_emitcode("mov","a,%s",l);
7133 aopPut(AOP(result),"a",offset);
7135 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7136 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7137 //aopPut(AOP(result),l,offset);
7143 size = AOP_SIZE(result);
7145 /* if it is only one byte then */
7147 if(optimized_for_speed) {
7148 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7149 emitpcode(POC_ANDLW, popGetLit(0xf0));
7150 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7151 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7152 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7153 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7154 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7155 emitpcode(POC_RLFW, popGet(AOP(result),0));
7156 emitpcode(POC_ANDLW, popGetLit(0xfe));
7157 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7158 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7159 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7162 tlbl = newiTempLabel(NULL);
7163 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7164 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7165 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7168 emitpcode(POC_COMFW, popGet(AOP(right),0));
7169 emitpcode(POC_RRF, popGet(AOP(result),0));
7170 emitpLabel(tlbl->key);
7171 emitpcode(POC_RLF, popGet(AOP(result),0));
7172 emitpcode(POC_ADDLW, popGetLit(1));
7174 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7179 if (pic14_sameRegs(AOP(left),AOP(result))) {
7181 tlbl = newiTempLabel(NULL);
7182 emitpcode(POC_COMFW, popGet(AOP(right),0));
7183 genMultiAsm(POC_RRF, result, size,1);
7184 emitpLabel(tlbl->key);
7185 genMultiAsm(POC_RLF, result, size,0);
7186 emitpcode(POC_ADDLW, popGetLit(1));
7188 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7192 //tlbl = newiTempLabel(NULL);
7194 //tlbl1 = newiTempLabel(NULL);
7196 //reAdjustPreg(AOP(result));
7198 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7199 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7200 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7202 //pic14_emitcode("add","a,acc");
7203 //aopPut(AOP(result),"a",offset++);
7205 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7207 // pic14_emitcode("rlc","a");
7208 // aopPut(AOP(result),"a",offset++);
7210 //reAdjustPreg(AOP(result));
7212 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7213 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7216 tlbl = newiTempLabel(NULL);
7217 tlbl1= newiTempLabel(NULL);
7219 size = AOP_SIZE(result);
7222 pctemp = popGetTempReg(); /* grab a temporary working register. */
7224 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7226 /* offset should be 0, 1 or 3 */
7227 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7229 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7231 emitpcode(POC_MOVWF, pctemp);
7234 emitpLabel(tlbl->key);
7237 emitpcode(POC_RLF, popGet(AOP(result),0));
7239 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7241 emitpcode(POC_DECFSZ, pctemp);
7242 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7243 emitpLabel(tlbl1->key);
7245 popReleaseTempReg(pctemp);
7249 freeAsmop (right,NULL,ic,TRUE);
7250 freeAsmop(left,NULL,ic,TRUE);
7251 freeAsmop(result,NULL,ic,TRUE);
7254 /*-----------------------------------------------------------------*/
7255 /* genrshOne - right shift a one byte quantity by known count */
7256 /*-----------------------------------------------------------------*/
7257 static void genrshOne (operand *result, operand *left,
7258 int shCount, int sign)
7260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7261 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7264 /*-----------------------------------------------------------------*/
7265 /* genrshTwo - right shift two bytes by known amount != 0 */
7266 /*-----------------------------------------------------------------*/
7267 static void genrshTwo (operand *result,operand *left,
7268 int shCount, int sign)
7270 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7271 /* if shCount >= 8 */
7275 shiftR1Left2Result(left, MSB16, result, LSB,
7278 movLeft2Result(left, MSB16, result, LSB);
7280 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7283 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7284 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7288 /* 1 <= shCount <= 7 */
7290 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7293 /*-----------------------------------------------------------------*/
7294 /* shiftRLong - shift right one long from left to result */
7295 /* offl = LSB or MSB16 */
7296 /*-----------------------------------------------------------------*/
7297 static void shiftRLong (operand *left, int offl,
7298 operand *result, int sign)
7300 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7302 pic14_emitcode("clr","c");
7303 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7305 pic14_emitcode("mov","c,acc.7");
7306 pic14_emitcode("rrc","a");
7307 aopPut(AOP(result),"a",MSB32-offl);
7309 /* add sign of "a" */
7310 addSign(result, MSB32, sign);
7312 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7313 pic14_emitcode("rrc","a");
7314 aopPut(AOP(result),"a",MSB24-offl);
7316 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7317 pic14_emitcode("rrc","a");
7318 aopPut(AOP(result),"a",MSB16-offl);
7321 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7322 pic14_emitcode("rrc","a");
7323 aopPut(AOP(result),"a",LSB);
7327 /*-----------------------------------------------------------------*/
7328 /* genrshFour - shift four byte by a known amount != 0 */
7329 /*-----------------------------------------------------------------*/
7330 static void genrshFour (operand *result, operand *left,
7331 int shCount, int sign)
7333 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7334 /* if shifting more that 3 bytes */
7335 if(shCount >= 24 ) {
7338 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7340 movLeft2Result(left, MSB32, result, LSB);
7342 addSign(result, MSB16, sign);
7344 else if(shCount >= 16){
7347 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7349 movLeft2Result(left, MSB24, result, LSB);
7350 movLeft2Result(left, MSB32, result, MSB16);
7352 addSign(result, MSB24, sign);
7354 else if(shCount >= 8){
7357 shiftRLong(left, MSB16, result, sign);
7358 else if(shCount == 0){
7359 movLeft2Result(left, MSB16, result, LSB);
7360 movLeft2Result(left, MSB24, result, MSB16);
7361 movLeft2Result(left, MSB32, result, MSB24);
7362 addSign(result, MSB32, sign);
7365 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7366 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7367 /* the last shift is signed */
7368 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7369 addSign(result, MSB32, sign);
7372 else{ /* 1 <= shCount <= 7 */
7374 shiftRLong(left, LSB, result, sign);
7376 shiftRLong(result, LSB, result, sign);
7379 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7380 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7381 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7386 /*-----------------------------------------------------------------*/
7387 /* genRightShiftLiteral - right shifting by known count */
7388 /*-----------------------------------------------------------------*/
7389 static void genRightShiftLiteral (operand *left,
7395 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7398 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7399 freeAsmop(right,NULL,ic,TRUE);
7401 aopOp(left,ic,FALSE);
7402 aopOp(result,ic,FALSE);
7405 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7409 lsize = pic14_getDataSize(left);
7410 res_size = pic14_getDataSize(result);
7411 /* test the LEFT size !!! */
7413 /* I suppose that the left size >= result size */
7416 movLeft2Result(left, lsize, result, res_size);
7419 else if(shCount >= (lsize * 8)){
7422 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7424 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7425 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7430 emitpcode(POC_MOVLW, popGetLit(0));
7431 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7432 emitpcode(POC_MOVLW, popGetLit(0xff));
7434 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7439 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7446 genrshOne (result,left,shCount,sign);
7450 genrshTwo (result,left,shCount,sign);
7454 genrshFour (result,left,shCount,sign);
7462 freeAsmop(left,NULL,ic,TRUE);
7463 freeAsmop(result,NULL,ic,TRUE);
7466 /*-----------------------------------------------------------------*/
7467 /* genSignedRightShift - right shift of signed number */
7468 /*-----------------------------------------------------------------*/
7469 static void genSignedRightShift (iCode *ic)
7471 operand *right, *left, *result;
7474 symbol *tlbl, *tlbl1 ;
7477 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7479 /* we do it the hard way put the shift count in b
7480 and loop thru preserving the sign */
7481 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7483 right = IC_RIGHT(ic);
7485 result = IC_RESULT(ic);
7487 aopOp(right,ic,FALSE);
7488 aopOp(left,ic,FALSE);
7489 aopOp(result,ic,FALSE);
7492 if ( AOP_TYPE(right) == AOP_LIT) {
7493 genRightShiftLiteral (left,right,result,ic,1);
7496 /* shift count is unknown then we have to form
7497 a loop get the loop count in B : Note: we take
7498 only the lower order byte since shifting
7499 more that 32 bits make no sense anyway, ( the
7500 largest size of an object can be only 32 bits ) */
7502 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7503 //pic14_emitcode("inc","b");
7504 //freeAsmop (right,NULL,ic,TRUE);
7505 //aopOp(left,ic,FALSE);
7506 //aopOp(result,ic,FALSE);
7508 /* now move the left to the result if they are not the
7510 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7511 AOP_SIZE(result) > 1) {
7513 size = AOP_SIZE(result);
7517 l = aopGet(AOP(left),offset,FALSE,TRUE);
7518 if (*l == '@' && IS_AOP_PREG(result)) {
7520 pic14_emitcode("mov","a,%s",l);
7521 aopPut(AOP(result),"a",offset);
7523 aopPut(AOP(result),l,offset);
7525 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7526 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7532 /* mov the highest order bit to OVR */
7533 tlbl = newiTempLabel(NULL);
7534 tlbl1= newiTempLabel(NULL);
7536 size = AOP_SIZE(result);
7539 pctemp = popGetTempReg(); /* grab a temporary working register. */
7541 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7543 /* offset should be 0, 1 or 3 */
7544 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7546 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7548 emitpcode(POC_MOVWF, pctemp);
7551 emitpLabel(tlbl->key);
7553 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7554 emitpcode(POC_RRF, popGet(AOP(result),offset));
7557 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7560 emitpcode(POC_DECFSZ, pctemp);
7561 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7562 emitpLabel(tlbl1->key);
7564 popReleaseTempReg(pctemp);
7566 size = AOP_SIZE(result);
7568 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7569 pic14_emitcode("rlc","a");
7570 pic14_emitcode("mov","ov,c");
7571 /* if it is only one byte then */
7573 l = aopGet(AOP(left),0,FALSE,FALSE);
7575 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7576 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7577 pic14_emitcode("mov","c,ov");
7578 pic14_emitcode("rrc","a");
7579 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7580 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7581 aopPut(AOP(result),"a",0);
7585 reAdjustPreg(AOP(result));
7586 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7587 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7588 pic14_emitcode("mov","c,ov");
7590 l = aopGet(AOP(result),offset,FALSE,FALSE);
7592 pic14_emitcode("rrc","a");
7593 aopPut(AOP(result),"a",offset--);
7595 reAdjustPreg(AOP(result));
7596 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7597 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7602 freeAsmop(left,NULL,ic,TRUE);
7603 freeAsmop(result,NULL,ic,TRUE);
7604 freeAsmop(right,NULL,ic,TRUE);
7607 /*-----------------------------------------------------------------*/
7608 /* genRightShift - generate code for right shifting */
7609 /*-----------------------------------------------------------------*/
7610 static void genRightShift (iCode *ic)
7612 operand *right, *left, *result;
7616 symbol *tlbl, *tlbl1 ;
7618 /* if signed then we do it the hard way preserve the
7619 sign bit moving it inwards */
7620 retype = getSpec(operandType(IC_RESULT(ic)));
7621 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7623 if (!SPEC_USIGN(retype)) {
7624 genSignedRightShift (ic);
7628 /* signed & unsigned types are treated the same : i.e. the
7629 signed is NOT propagated inwards : quoting from the
7630 ANSI - standard : "for E1 >> E2, is equivalent to division
7631 by 2**E2 if unsigned or if it has a non-negative value,
7632 otherwise the result is implementation defined ", MY definition
7633 is that the sign does not get propagated */
7635 right = IC_RIGHT(ic);
7637 result = IC_RESULT(ic);
7639 aopOp(right,ic,FALSE);
7641 /* if the shift count is known then do it
7642 as efficiently as possible */
7643 if (AOP_TYPE(right) == AOP_LIT) {
7644 genRightShiftLiteral (left,right,result,ic, 0);
7648 /* shift count is unknown then we have to form
7649 a loop get the loop count in B : Note: we take
7650 only the lower order byte since shifting
7651 more that 32 bits make no sense anyway, ( the
7652 largest size of an object can be only 32 bits ) */
7654 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7655 pic14_emitcode("inc","b");
7656 aopOp(left,ic,FALSE);
7657 aopOp(result,ic,FALSE);
7659 /* now move the left to the result if they are not the
7661 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7662 AOP_SIZE(result) > 1) {
7664 size = AOP_SIZE(result);
7667 l = aopGet(AOP(left),offset,FALSE,TRUE);
7668 if (*l == '@' && IS_AOP_PREG(result)) {
7670 pic14_emitcode("mov","a,%s",l);
7671 aopPut(AOP(result),"a",offset);
7673 aopPut(AOP(result),l,offset);
7678 tlbl = newiTempLabel(NULL);
7679 tlbl1= newiTempLabel(NULL);
7680 size = AOP_SIZE(result);
7683 /* if it is only one byte then */
7686 tlbl = newiTempLabel(NULL);
7687 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7688 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7689 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7692 emitpcode(POC_COMFW, popGet(AOP(right),0));
7693 emitpcode(POC_RLF, popGet(AOP(result),0));
7694 emitpLabel(tlbl->key);
7695 emitpcode(POC_RRF, popGet(AOP(result),0));
7696 emitpcode(POC_ADDLW, popGetLit(1));
7698 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7703 reAdjustPreg(AOP(result));
7704 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7705 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7708 l = aopGet(AOP(result),offset,FALSE,FALSE);
7710 pic14_emitcode("rrc","a");
7711 aopPut(AOP(result),"a",offset--);
7713 reAdjustPreg(AOP(result));
7715 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7716 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7719 freeAsmop(left,NULL,ic,TRUE);
7720 freeAsmop (right,NULL,ic,TRUE);
7721 freeAsmop(result,NULL,ic,TRUE);
7724 /*-----------------------------------------------------------------*/
7725 /* genUnpackBits - generates code for unpacking bits */
7726 /*-----------------------------------------------------------------*/
7727 static void genUnpackBits (operand *result, char *rname, int ptype)
7734 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7735 etype = getSpec(operandType(result));
7737 /* read the first byte */
7742 pic14_emitcode("mov","a,@%s",rname);
7746 pic14_emitcode("movx","a,@%s",rname);
7750 pic14_emitcode("movx","a,@dptr");
7754 pic14_emitcode("clr","a");
7755 pic14_emitcode("movc","a","@a+dptr");
7759 pic14_emitcode("lcall","__gptrget");
7763 /* if we have bitdisplacement then it fits */
7764 /* into this byte completely or if length is */
7765 /* less than a byte */
7766 if ((shCnt = SPEC_BSTR(etype)) ||
7767 (SPEC_BLEN(etype) <= 8)) {
7769 /* shift right acc */
7772 pic14_emitcode("anl","a,#0x%02x",
7773 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7774 aopPut(AOP(result),"a",offset);
7778 /* bit field did not fit in a byte */
7779 rlen = SPEC_BLEN(etype) - 8;
7780 aopPut(AOP(result),"a",offset++);
7787 pic14_emitcode("inc","%s",rname);
7788 pic14_emitcode("mov","a,@%s",rname);
7792 pic14_emitcode("inc","%s",rname);
7793 pic14_emitcode("movx","a,@%s",rname);
7797 pic14_emitcode("inc","dptr");
7798 pic14_emitcode("movx","a,@dptr");
7802 pic14_emitcode("clr","a");
7803 pic14_emitcode("inc","dptr");
7804 pic14_emitcode("movc","a","@a+dptr");
7808 pic14_emitcode("inc","dptr");
7809 pic14_emitcode("lcall","__gptrget");
7814 /* if we are done */
7818 aopPut(AOP(result),"a",offset++);
7823 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7824 aopPut(AOP(result),"a",offset);
7831 /*-----------------------------------------------------------------*/
7832 /* genDataPointerGet - generates code when ptr offset is known */
7833 /*-----------------------------------------------------------------*/
7834 static void genDataPointerGet (operand *left,
7838 int size , offset = 0;
7841 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7844 /* optimization - most of the time, left and result are the same
7845 * address, but different types. for the pic code, we could omit
7849 aopOp(result,ic,TRUE);
7851 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7853 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7855 size = AOP_SIZE(result);
7858 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7862 freeAsmop(left,NULL,ic,TRUE);
7863 freeAsmop(result,NULL,ic,TRUE);
7866 /*-----------------------------------------------------------------*/
7867 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7868 /*-----------------------------------------------------------------*/
7869 static void genNearPointerGet (operand *left,
7876 sym_link *rtype, *retype;
7877 sym_link *ltype = operandType(left);
7880 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7882 rtype = operandType(result);
7883 retype= getSpec(rtype);
7885 aopOp(left,ic,FALSE);
7887 /* if left is rematerialisable and
7888 result is not bit variable type and
7889 the left is pointer to data space i.e
7890 lower 128 bytes of space */
7891 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7892 !IS_BITVAR(retype) &&
7893 DCL_TYPE(ltype) == POINTER) {
7894 //genDataPointerGet (left,result,ic);
7898 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7900 /* if the value is already in a pointer register
7901 then don't need anything more */
7902 if (!AOP_INPREG(AOP(left))) {
7903 /* otherwise get a free pointer register */
7904 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7907 preg = getFreePtr(ic,&aop,FALSE);
7908 pic14_emitcode("mov","%s,%s",
7910 aopGet(AOP(left),0,FALSE,TRUE));
7911 rname = preg->name ;
7915 rname = aopGet(AOP(left),0,FALSE,FALSE);
7917 aopOp (result,ic,FALSE);
7919 /* if bitfield then unpack the bits */
7920 if (IS_BITVAR(retype))
7921 genUnpackBits (result,rname,POINTER);
7923 /* we have can just get the values */
7924 int size = AOP_SIZE(result);
7927 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7929 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7930 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7932 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7933 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7935 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
7939 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
7941 pic14_emitcode("mov","a,@%s",rname);
7942 aopPut(AOP(result),"a",offset);
7944 sprintf(buffer,"@%s",rname);
7945 aopPut(AOP(result),buffer,offset);
7949 pic14_emitcode("inc","%s",rname);
7954 /* now some housekeeping stuff */
7956 /* we had to allocate for this iCode */
7957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7958 freeAsmop(NULL,aop,ic,TRUE);
7960 /* we did not allocate which means left
7961 already in a pointer register, then
7962 if size > 0 && this could be used again
7963 we have to point it back to where it
7965 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7966 if (AOP_SIZE(result) > 1 &&
7967 !OP_SYMBOL(left)->remat &&
7968 ( OP_SYMBOL(left)->liveTo > ic->seq ||
7970 int size = AOP_SIZE(result) - 1;
7972 pic14_emitcode("dec","%s",rname);
7977 freeAsmop(left,NULL,ic,TRUE);
7978 freeAsmop(result,NULL,ic,TRUE);
7982 /*-----------------------------------------------------------------*/
7983 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
7984 /*-----------------------------------------------------------------*/
7985 static void genPagedPointerGet (operand *left,
7992 sym_link *rtype, *retype;
7994 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7996 rtype = operandType(result);
7997 retype= getSpec(rtype);
7999 aopOp(left,ic,FALSE);
8001 /* if the value is already in a pointer register
8002 then don't need anything more */
8003 if (!AOP_INPREG(AOP(left))) {
8004 /* otherwise get a free pointer register */
8006 preg = getFreePtr(ic,&aop,FALSE);
8007 pic14_emitcode("mov","%s,%s",
8009 aopGet(AOP(left),0,FALSE,TRUE));
8010 rname = preg->name ;
8012 rname = aopGet(AOP(left),0,FALSE,FALSE);
8014 freeAsmop(left,NULL,ic,TRUE);
8015 aopOp (result,ic,FALSE);
8017 /* if bitfield then unpack the bits */
8018 if (IS_BITVAR(retype))
8019 genUnpackBits (result,rname,PPOINTER);
8021 /* we have can just get the values */
8022 int size = AOP_SIZE(result);
8027 pic14_emitcode("movx","a,@%s",rname);
8028 aopPut(AOP(result),"a",offset);
8033 pic14_emitcode("inc","%s",rname);
8037 /* now some housekeeping stuff */
8039 /* we had to allocate for this iCode */
8040 freeAsmop(NULL,aop,ic,TRUE);
8042 /* we did not allocate which means left
8043 already in a pointer register, then
8044 if size > 0 && this could be used again
8045 we have to point it back to where it
8047 if (AOP_SIZE(result) > 1 &&
8048 !OP_SYMBOL(left)->remat &&
8049 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8051 int size = AOP_SIZE(result) - 1;
8053 pic14_emitcode("dec","%s",rname);
8058 freeAsmop(result,NULL,ic,TRUE);
8063 /*-----------------------------------------------------------------*/
8064 /* genFarPointerGet - gget value from far space */
8065 /*-----------------------------------------------------------------*/
8066 static void genFarPointerGet (operand *left,
8067 operand *result, iCode *ic)
8070 sym_link *retype = getSpec(operandType(result));
8072 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8074 aopOp(left,ic,FALSE);
8076 /* if the operand is already in dptr
8077 then we do nothing else we move the value to dptr */
8078 if (AOP_TYPE(left) != AOP_STR) {
8079 /* if this is remateriazable */
8080 if (AOP_TYPE(left) == AOP_IMMD)
8081 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8082 else { /* we need to get it byte by byte */
8083 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8084 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8085 if (options.model == MODEL_FLAT24)
8087 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8091 /* so dptr know contains the address */
8092 freeAsmop(left,NULL,ic,TRUE);
8093 aopOp(result,ic,FALSE);
8095 /* if bit then unpack */
8096 if (IS_BITVAR(retype))
8097 genUnpackBits(result,"dptr",FPOINTER);
8099 size = AOP_SIZE(result);
8103 pic14_emitcode("movx","a,@dptr");
8104 aopPut(AOP(result),"a",offset++);
8106 pic14_emitcode("inc","dptr");
8110 freeAsmop(result,NULL,ic,TRUE);
8113 /*-----------------------------------------------------------------*/
8114 /* genCodePointerGet - get value from code space */
8115 /*-----------------------------------------------------------------*/
8116 static void genCodePointerGet (operand *left,
8117 operand *result, iCode *ic)
8120 sym_link *retype = getSpec(operandType(result));
8122 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8124 aopOp(left,ic,FALSE);
8126 /* if the operand is already in dptr
8127 then we do nothing else we move the value to dptr */
8128 if (AOP_TYPE(left) != AOP_STR) {
8129 /* if this is remateriazable */
8130 if (AOP_TYPE(left) == AOP_IMMD)
8131 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8132 else { /* we need to get it byte by byte */
8133 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8134 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8135 if (options.model == MODEL_FLAT24)
8137 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8141 /* so dptr know contains the address */
8142 freeAsmop(left,NULL,ic,TRUE);
8143 aopOp(result,ic,FALSE);
8145 /* if bit then unpack */
8146 if (IS_BITVAR(retype))
8147 genUnpackBits(result,"dptr",CPOINTER);
8149 size = AOP_SIZE(result);
8153 pic14_emitcode("clr","a");
8154 pic14_emitcode("movc","a,@a+dptr");
8155 aopPut(AOP(result),"a",offset++);
8157 pic14_emitcode("inc","dptr");
8161 freeAsmop(result,NULL,ic,TRUE);
8164 /*-----------------------------------------------------------------*/
8165 /* genGenPointerGet - gget value from generic pointer space */
8166 /*-----------------------------------------------------------------*/
8167 static void genGenPointerGet (operand *left,
8168 operand *result, iCode *ic)
8171 sym_link *retype = getSpec(operandType(result));
8173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8174 aopOp(left,ic,FALSE);
8175 aopOp(result,ic,FALSE);
8178 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8180 /* if the operand is already in dptr
8181 then we do nothing else we move the value to dptr */
8182 // if (AOP_TYPE(left) != AOP_STR) {
8183 /* if this is remateriazable */
8184 if (AOP_TYPE(left) == AOP_IMMD) {
8185 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8186 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8188 else { /* we need to get it byte by byte */
8190 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8191 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8193 size = AOP_SIZE(result);
8197 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8198 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8200 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8205 /* so dptr know contains the address */
8207 /* if bit then unpack */
8208 //if (IS_BITVAR(retype))
8209 // genUnpackBits(result,"dptr",GPOINTER);
8212 freeAsmop(left,NULL,ic,TRUE);
8213 freeAsmop(result,NULL,ic,TRUE);
8217 /*-----------------------------------------------------------------*/
8218 /* genConstPointerGet - get value from const generic pointer space */
8219 /*-----------------------------------------------------------------*/
8220 static void genConstPointerGet (operand *left,
8221 operand *result, iCode *ic)
8223 //sym_link *retype = getSpec(operandType(result));
8224 symbol *albl = newiTempLabel(NULL);
8225 symbol *blbl = newiTempLabel(NULL);
8228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8229 aopOp(left,ic,FALSE);
8230 aopOp(result,ic,FALSE);
8233 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8235 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8237 emitpcode(POC_CALL,popGetLabel(albl->key));
8238 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8239 emitpLabel(albl->key);
8241 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8243 emitpcode(poc,popGet(AOP(left),1));
8244 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8245 emitpcode(poc,popGet(AOP(left),0));
8246 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8248 emitpLabel(blbl->key);
8250 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8253 freeAsmop(left,NULL,ic,TRUE);
8254 freeAsmop(result,NULL,ic,TRUE);
8257 /*-----------------------------------------------------------------*/
8258 /* genPointerGet - generate code for pointer get */
8259 /*-----------------------------------------------------------------*/
8260 static void genPointerGet (iCode *ic)
8262 operand *left, *result ;
8263 sym_link *type, *etype;
8266 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8269 result = IC_RESULT(ic) ;
8271 /* depending on the type of pointer we need to
8272 move it to the correct pointer register */
8273 type = operandType(left);
8274 etype = getSpec(type);
8276 if (IS_PTR_CONST(type))
8277 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8279 /* if left is of type of pointer then it is simple */
8280 if (IS_PTR(type) && !IS_FUNC(type->next))
8281 p_type = DCL_TYPE(type);
8283 /* we have to go by the storage class */
8284 p_type = PTR_TYPE(SPEC_OCLS(etype));
8286 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8288 if (SPEC_OCLS(etype)->codesp ) {
8289 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8290 //p_type = CPOINTER ;
8293 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8294 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8295 /*p_type = FPOINTER ;*/
8297 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8298 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8299 /* p_type = PPOINTER; */
8301 if (SPEC_OCLS(etype) == idata )
8302 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8303 /* p_type = IPOINTER; */
8305 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8306 /* p_type = POINTER ; */
8309 /* now that we have the pointer type we assign
8310 the pointer values */
8315 genNearPointerGet (left,result,ic);
8319 genPagedPointerGet(left,result,ic);
8323 genFarPointerGet (left,result,ic);
8327 genConstPointerGet (left,result,ic);
8328 //pic14_emitcodePointerGet (left,result,ic);
8332 if (IS_PTR_CONST(type))
8333 genConstPointerGet (left,result,ic);
8335 genGenPointerGet (left,result,ic);
8341 /*-----------------------------------------------------------------*/
8342 /* genPackBits - generates code for packed bit storage */
8343 /*-----------------------------------------------------------------*/
8344 static void genPackBits (sym_link *etype ,
8346 char *rname, int p_type)
8354 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8355 blen = SPEC_BLEN(etype);
8356 bstr = SPEC_BSTR(etype);
8358 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8361 /* if the bit lenth is less than or */
8362 /* it exactly fits a byte then */
8363 if (SPEC_BLEN(etype) <= 8 ) {
8364 shCount = SPEC_BSTR(etype) ;
8366 /* shift left acc */
8369 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8374 pic14_emitcode ("mov","b,a");
8375 pic14_emitcode("mov","a,@%s",rname);
8379 pic14_emitcode ("mov","b,a");
8380 pic14_emitcode("movx","a,@dptr");
8384 pic14_emitcode ("push","b");
8385 pic14_emitcode ("push","acc");
8386 pic14_emitcode ("lcall","__gptrget");
8387 pic14_emitcode ("pop","b");
8391 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8392 ((unsigned char)(0xFF << (blen+bstr)) |
8393 (unsigned char)(0xFF >> (8-bstr)) ) );
8394 pic14_emitcode ("orl","a,b");
8395 if (p_type == GPOINTER)
8396 pic14_emitcode("pop","b");
8402 pic14_emitcode("mov","@%s,a",rname);
8406 pic14_emitcode("movx","@dptr,a");
8410 DEBUGpic14_emitcode(";lcall","__gptrput");
8415 if ( SPEC_BLEN(etype) <= 8 )
8418 pic14_emitcode("inc","%s",rname);
8419 rLen = SPEC_BLEN(etype) ;
8421 /* now generate for lengths greater than one byte */
8424 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8434 pic14_emitcode("mov","@%s,a",rname);
8436 pic14_emitcode("mov","@%s,%s",rname,l);
8441 pic14_emitcode("movx","@dptr,a");
8446 DEBUGpic14_emitcode(";lcall","__gptrput");
8449 pic14_emitcode ("inc","%s",rname);
8454 /* last last was not complete */
8456 /* save the byte & read byte */
8459 pic14_emitcode ("mov","b,a");
8460 pic14_emitcode("mov","a,@%s",rname);
8464 pic14_emitcode ("mov","b,a");
8465 pic14_emitcode("movx","a,@dptr");
8469 pic14_emitcode ("push","b");
8470 pic14_emitcode ("push","acc");
8471 pic14_emitcode ("lcall","__gptrget");
8472 pic14_emitcode ("pop","b");
8476 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8477 pic14_emitcode ("orl","a,b");
8480 if (p_type == GPOINTER)
8481 pic14_emitcode("pop","b");
8486 pic14_emitcode("mov","@%s,a",rname);
8490 pic14_emitcode("movx","@dptr,a");
8494 DEBUGpic14_emitcode(";lcall","__gptrput");
8498 /*-----------------------------------------------------------------*/
8499 /* genDataPointerSet - remat pointer to data space */
8500 /*-----------------------------------------------------------------*/
8501 static void genDataPointerSet(operand *right,
8505 int size, offset = 0 ;
8506 char *l, buffer[256];
8508 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8509 aopOp(right,ic,FALSE);
8511 l = aopGet(AOP(result),0,FALSE,TRUE);
8512 size = AOP_SIZE(right);
8514 if ( AOP_TYPE(result) == AOP_PCODE) {
8515 fprintf(stderr,"genDataPointerSet %s, %d\n",
8516 AOP(result)->aopu.pcop->name,
8517 PCOI(AOP(result)->aopu.pcop)->offset);
8521 // tsd, was l+1 - the underline `_' prefix was being stripped
8524 sprintf(buffer,"(%s + %d)",l,offset);
8525 fprintf(stderr,"oops %s\n",buffer);
8527 sprintf(buffer,"%s",l);
8529 if (AOP_TYPE(right) == AOP_LIT) {
8530 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8531 lit = lit >> (8*offset);
8533 pic14_emitcode("movlw","%d",lit);
8534 pic14_emitcode("movwf","%s",buffer);
8536 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8537 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8538 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8541 pic14_emitcode("clrf","%s",buffer);
8542 //emitpcode(POC_CLRF, popRegFromString(buffer));
8543 emitpcode(POC_CLRF, popGet(AOP(result),0));
8546 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8547 pic14_emitcode("movwf","%s",buffer);
8549 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8550 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8551 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8558 freeAsmop(right,NULL,ic,TRUE);
8559 freeAsmop(result,NULL,ic,TRUE);
8562 /*-----------------------------------------------------------------*/
8563 /* genNearPointerSet - pic14_emitcode for near pointer put */
8564 /*-----------------------------------------------------------------*/
8565 static void genNearPointerSet (operand *right,
8572 sym_link *ptype = operandType(result);
8575 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8576 retype= getSpec(operandType(right));
8578 aopOp(result,ic,FALSE);
8581 /* if the result is rematerializable &
8582 in data space & not a bit variable */
8583 //if (AOP_TYPE(result) == AOP_IMMD &&
8584 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8585 DCL_TYPE(ptype) == POINTER &&
8586 !IS_BITVAR(retype)) {
8587 genDataPointerSet (right,result,ic);
8588 freeAsmop(result,NULL,ic,TRUE);
8592 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8593 aopOp(right,ic,FALSE);
8594 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8596 /* if the value is already in a pointer register
8597 then don't need anything more */
8598 if (!AOP_INPREG(AOP(result))) {
8599 /* otherwise get a free pointer register */
8600 //aop = newAsmop(0);
8601 //preg = getFreePtr(ic,&aop,FALSE);
8602 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8603 //pic14_emitcode("mov","%s,%s",
8605 // aopGet(AOP(result),0,FALSE,TRUE));
8606 //rname = preg->name ;
8607 //pic14_emitcode("movwf","fsr");
8608 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8609 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8610 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8611 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8615 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8618 /* if bitfield then unpack the bits */
8619 if (IS_BITVAR(retype)) {
8620 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8621 "The programmer is obviously confused");
8622 //genPackBits (retype,right,rname,POINTER);
8626 /* we have can just get the values */
8627 int size = AOP_SIZE(right);
8630 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8632 l = aopGet(AOP(right),offset,FALSE,TRUE);
8635 //pic14_emitcode("mov","@%s,a",rname);
8636 pic14_emitcode("movf","indf,w ;1");
8639 if (AOP_TYPE(right) == AOP_LIT) {
8640 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8642 pic14_emitcode("movlw","%s",l);
8643 pic14_emitcode("movwf","indf ;2");
8645 pic14_emitcode("clrf","indf");
8647 pic14_emitcode("movf","%s,w",l);
8648 pic14_emitcode("movwf","indf ;2");
8650 //pic14_emitcode("mov","@%s,%s",rname,l);
8653 pic14_emitcode("incf","fsr,f ;3");
8654 //pic14_emitcode("inc","%s",rname);
8659 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8660 /* now some housekeeping stuff */
8662 /* we had to allocate for this iCode */
8663 freeAsmop(NULL,aop,ic,TRUE);
8665 /* we did not allocate which means left
8666 already in a pointer register, then
8667 if size > 0 && this could be used again
8668 we have to point it back to where it
8670 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8671 if (AOP_SIZE(right) > 1 &&
8672 !OP_SYMBOL(result)->remat &&
8673 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8675 int size = AOP_SIZE(right) - 1;
8677 pic14_emitcode("decf","fsr,f");
8678 //pic14_emitcode("dec","%s",rname);
8682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8685 freeAsmop(right,NULL,ic,TRUE);
8686 freeAsmop(result,NULL,ic,TRUE);
8689 /*-----------------------------------------------------------------*/
8690 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8691 /*-----------------------------------------------------------------*/
8692 static void genPagedPointerSet (operand *right,
8701 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8703 retype= getSpec(operandType(right));
8705 aopOp(result,ic,FALSE);
8707 /* if the value is already in a pointer register
8708 then don't need anything more */
8709 if (!AOP_INPREG(AOP(result))) {
8710 /* otherwise get a free pointer register */
8712 preg = getFreePtr(ic,&aop,FALSE);
8713 pic14_emitcode("mov","%s,%s",
8715 aopGet(AOP(result),0,FALSE,TRUE));
8716 rname = preg->name ;
8718 rname = aopGet(AOP(result),0,FALSE,FALSE);
8720 freeAsmop(result,NULL,ic,TRUE);
8721 aopOp (right,ic,FALSE);
8723 /* if bitfield then unpack the bits */
8724 if (IS_BITVAR(retype))
8725 genPackBits (retype,right,rname,PPOINTER);
8727 /* we have can just get the values */
8728 int size = AOP_SIZE(right);
8732 l = aopGet(AOP(right),offset,FALSE,TRUE);
8735 pic14_emitcode("movx","@%s,a",rname);
8738 pic14_emitcode("inc","%s",rname);
8744 /* now some housekeeping stuff */
8746 /* we had to allocate for this iCode */
8747 freeAsmop(NULL,aop,ic,TRUE);
8749 /* we did not allocate which means left
8750 already in a pointer register, then
8751 if size > 0 && this could be used again
8752 we have to point it back to where it
8754 if (AOP_SIZE(right) > 1 &&
8755 !OP_SYMBOL(result)->remat &&
8756 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8758 int size = AOP_SIZE(right) - 1;
8760 pic14_emitcode("dec","%s",rname);
8765 freeAsmop(right,NULL,ic,TRUE);
8770 /*-----------------------------------------------------------------*/
8771 /* genFarPointerSet - set value from far space */
8772 /*-----------------------------------------------------------------*/
8773 static void genFarPointerSet (operand *right,
8774 operand *result, iCode *ic)
8777 sym_link *retype = getSpec(operandType(right));
8779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8780 aopOp(result,ic,FALSE);
8782 /* if the operand is already in dptr
8783 then we do nothing else we move the value to dptr */
8784 if (AOP_TYPE(result) != AOP_STR) {
8785 /* if this is remateriazable */
8786 if (AOP_TYPE(result) == AOP_IMMD)
8787 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8788 else { /* we need to get it byte by byte */
8789 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8790 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8791 if (options.model == MODEL_FLAT24)
8793 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8797 /* so dptr know contains the address */
8798 freeAsmop(result,NULL,ic,TRUE);
8799 aopOp(right,ic,FALSE);
8801 /* if bit then unpack */
8802 if (IS_BITVAR(retype))
8803 genPackBits(retype,right,"dptr",FPOINTER);
8805 size = AOP_SIZE(right);
8809 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8811 pic14_emitcode("movx","@dptr,a");
8813 pic14_emitcode("inc","dptr");
8817 freeAsmop(right,NULL,ic,TRUE);
8820 /*-----------------------------------------------------------------*/
8821 /* genGenPointerSet - set value from generic pointer space */
8822 /*-----------------------------------------------------------------*/
8823 static void genGenPointerSet (operand *right,
8824 operand *result, iCode *ic)
8827 sym_link *retype = getSpec(operandType(right));
8829 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8831 aopOp(result,ic,FALSE);
8832 aopOp(right,ic,FALSE);
8833 size = AOP_SIZE(right);
8835 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8837 /* if the operand is already in dptr
8838 then we do nothing else we move the value to dptr */
8839 if (AOP_TYPE(result) != AOP_STR) {
8840 /* if this is remateriazable */
8841 if (AOP_TYPE(result) == AOP_IMMD) {
8842 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8843 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8845 else { /* we need to get it byte by byte */
8846 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8847 size = AOP_SIZE(right);
8850 /* hack hack! see if this the FSR. If so don't load W */
8851 if(AOP_TYPE(right) != AOP_ACC) {
8853 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8854 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8857 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8859 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8860 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8864 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8865 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8868 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8875 if(aopIdx(AOP(result),0) != 4) {
8877 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8881 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8886 /* so dptr know contains the address */
8889 /* if bit then unpack */
8890 if (IS_BITVAR(retype))
8891 genPackBits(retype,right,"dptr",GPOINTER);
8893 size = AOP_SIZE(right);
8897 //char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8899 pic14_emitcode("incf","fsr,f");
8900 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset++,FALSE,FALSE));
8901 pic14_emitcode("movwf","indf");
8903 //DEBUGpic14_emitcode(";lcall","__gptrput");
8905 // pic14_emitcode("inc","dptr");
8910 freeAsmop(right,NULL,ic,TRUE);
8911 freeAsmop(result,NULL,ic,TRUE);
8914 /*-----------------------------------------------------------------*/
8915 /* genPointerSet - stores the value into a pointer location */
8916 /*-----------------------------------------------------------------*/
8917 static void genPointerSet (iCode *ic)
8919 operand *right, *result ;
8920 sym_link *type, *etype;
8923 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8925 right = IC_RIGHT(ic);
8926 result = IC_RESULT(ic) ;
8928 /* depending on the type of pointer we need to
8929 move it to the correct pointer register */
8930 type = operandType(result);
8931 etype = getSpec(type);
8932 /* if left is of type of pointer then it is simple */
8933 if (IS_PTR(type) && !IS_FUNC(type->next)) {
8934 p_type = DCL_TYPE(type);
8937 /* we have to go by the storage class */
8938 p_type = PTR_TYPE(SPEC_OCLS(etype));
8940 /* if (SPEC_OCLS(etype)->codesp ) { */
8941 /* p_type = CPOINTER ; */
8944 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
8945 /* p_type = FPOINTER ; */
8947 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
8948 /* p_type = PPOINTER ; */
8950 /* if (SPEC_OCLS(etype) == idata ) */
8951 /* p_type = IPOINTER ; */
8953 /* p_type = POINTER ; */
8956 /* now that we have the pointer type we assign
8957 the pointer values */
8962 genNearPointerSet (right,result,ic);
8966 genPagedPointerSet (right,result,ic);
8970 genFarPointerSet (right,result,ic);
8974 genGenPointerSet (right,result,ic);
8978 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
8979 "genPointerSet: illegal pointer type");
8983 /*-----------------------------------------------------------------*/
8984 /* genIfx - generate code for Ifx statement */
8985 /*-----------------------------------------------------------------*/
8986 static void genIfx (iCode *ic, iCode *popIc)
8988 operand *cond = IC_COND(ic);
8991 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8993 aopOp(cond,ic,FALSE);
8995 /* get the value into acc */
8996 if (AOP_TYPE(cond) != AOP_CRY)
8997 pic14_toBoolean(cond);
9000 /* the result is now in the accumulator */
9001 freeAsmop(cond,NULL,ic,TRUE);
9003 /* if there was something to be popped then do it */
9007 /* if the condition is a bit variable */
9008 if (isbit && IS_ITEMP(cond) &&
9010 genIfxJump(ic,SPIL_LOC(cond)->rname);
9011 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9014 if (isbit && !IS_ITEMP(cond))
9015 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9023 /*-----------------------------------------------------------------*/
9024 /* genAddrOf - generates code for address of */
9025 /*-----------------------------------------------------------------*/
9026 static void genAddrOf (iCode *ic)
9028 operand *right, *result, *left;
9031 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9034 //aopOp(IC_RESULT(ic),ic,FALSE);
9036 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9037 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9038 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9040 DEBUGpic14_AopType(__LINE__,left,right,result);
9042 size = AOP_SIZE(IC_RESULT(ic));
9046 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9047 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9051 freeAsmop(left,NULL,ic,FALSE);
9052 freeAsmop(result,NULL,ic,TRUE);
9057 /*-----------------------------------------------------------------*/
9058 /* genFarFarAssign - assignment when both are in far space */
9059 /*-----------------------------------------------------------------*/
9060 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9062 int size = AOP_SIZE(right);
9065 /* first push the right side on to the stack */
9067 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9069 pic14_emitcode ("push","acc");
9072 freeAsmop(right,NULL,ic,FALSE);
9073 /* now assign DPTR to result */
9074 aopOp(result,ic,FALSE);
9075 size = AOP_SIZE(result);
9077 pic14_emitcode ("pop","acc");
9078 aopPut(AOP(result),"a",--offset);
9080 freeAsmop(result,NULL,ic,FALSE);
9085 /*-----------------------------------------------------------------*/
9086 /* genAssign - generate code for assignment */
9087 /*-----------------------------------------------------------------*/
9088 static void genAssign (iCode *ic)
9090 operand *result, *right;
9091 int size, offset,know_W;
9092 unsigned long lit = 0L;
9094 result = IC_RESULT(ic);
9095 right = IC_RIGHT(ic) ;
9097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9099 /* if they are the same */
9100 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9103 aopOp(right,ic,FALSE);
9104 aopOp(result,ic,TRUE);
9106 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9108 /* if they are the same registers */
9109 if (pic14_sameRegs(AOP(right),AOP(result)))
9112 /* if the result is a bit */
9113 if (AOP_TYPE(result) == AOP_CRY) {
9115 /* if the right size is a literal then
9116 we know what the value is */
9117 if (AOP_TYPE(right) == AOP_LIT) {
9119 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9120 popGet(AOP(result),0));
9122 if (((int) operandLitValue(right)))
9123 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9124 AOP(result)->aopu.aop_dir,
9125 AOP(result)->aopu.aop_dir);
9127 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9128 AOP(result)->aopu.aop_dir,
9129 AOP(result)->aopu.aop_dir);
9133 /* the right is also a bit variable */
9134 if (AOP_TYPE(right) == AOP_CRY) {
9135 emitpcode(POC_BCF, popGet(AOP(result),0));
9136 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9137 emitpcode(POC_BSF, popGet(AOP(result),0));
9139 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9140 AOP(result)->aopu.aop_dir,
9141 AOP(result)->aopu.aop_dir);
9142 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9143 AOP(right)->aopu.aop_dir,
9144 AOP(right)->aopu.aop_dir);
9145 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9146 AOP(result)->aopu.aop_dir,
9147 AOP(result)->aopu.aop_dir);
9152 emitpcode(POC_BCF, popGet(AOP(result),0));
9153 pic14_toBoolean(right);
9155 emitpcode(POC_BSF, popGet(AOP(result),0));
9156 //aopPut(AOP(result),"a",0);
9160 /* bit variables done */
9162 size = AOP_SIZE(result);
9164 if(AOP_TYPE(right) == AOP_LIT)
9165 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9167 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9169 if(aopIdx(AOP(result),0) == 4) {
9170 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9171 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9172 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9175 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9181 if(AOP_TYPE(right) == AOP_LIT) {
9183 if(know_W != (lit&0xff))
9184 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9186 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9188 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9192 } else if (AOP_TYPE(right) == AOP_CRY) {
9193 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9195 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9196 emitpcode(POC_INCF, popGet(AOP(result),0));
9199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9200 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9201 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9209 freeAsmop (right,NULL,ic,FALSE);
9210 freeAsmop (result,NULL,ic,TRUE);
9213 /*-----------------------------------------------------------------*/
9214 /* genJumpTab - genrates code for jump table */
9215 /*-----------------------------------------------------------------*/
9216 static void genJumpTab (iCode *ic)
9221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9223 aopOp(IC_JTCOND(ic),ic,FALSE);
9224 /* get the condition into accumulator */
9225 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9227 /* multiply by three */
9228 pic14_emitcode("add","a,acc");
9229 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9231 jtab = newiTempLabel(NULL);
9232 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9233 pic14_emitcode("jmp","@a+dptr");
9234 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9236 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9237 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9239 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9240 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9241 emitpLabel(jtab->key);
9243 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9245 /* now generate the jump labels */
9246 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9247 jtab = setNextItem(IC_JTLABELS(ic))) {
9248 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9249 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9255 /*-----------------------------------------------------------------*/
9256 /* genMixedOperation - gen code for operators between mixed types */
9257 /*-----------------------------------------------------------------*/
9259 TSD - Written for the PIC port - but this unfortunately is buggy.
9260 This routine is good in that it is able to efficiently promote
9261 types to different (larger) sizes. Unfortunately, the temporary
9262 variables that are optimized out by this routine are sometimes
9263 used in other places. So until I know how to really parse the
9264 iCode tree, I'm going to not be using this routine :(.
9266 static int genMixedOperation (iCode *ic)
9269 operand *result = IC_RESULT(ic);
9270 sym_link *ctype = operandType(IC_LEFT(ic));
9271 operand *right = IC_RIGHT(ic);
9277 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9279 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9285 nextright = IC_RIGHT(nextic);
9286 nextleft = IC_LEFT(nextic);
9287 nextresult = IC_RESULT(nextic);
9289 aopOp(right,ic,FALSE);
9290 aopOp(result,ic,FALSE);
9291 aopOp(nextright, nextic, FALSE);
9292 aopOp(nextleft, nextic, FALSE);
9293 aopOp(nextresult, nextic, FALSE);
9295 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9301 pic14_emitcode(";remove right +","");
9303 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9309 pic14_emitcode(";remove left +","");
9313 big = AOP_SIZE(nextleft);
9314 small = AOP_SIZE(nextright);
9316 switch(nextic->op) {
9319 pic14_emitcode(";optimize a +","");
9320 /* if unsigned or not an integral type */
9321 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9322 pic14_emitcode(";add a bit to something","");
9325 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9327 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9328 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9329 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9331 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9339 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9340 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9341 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9344 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9346 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9347 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9348 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9349 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9350 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9353 pic14_emitcode("rlf","known_zero,w");
9360 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9361 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9362 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9364 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9374 freeAsmop(right,NULL,ic,TRUE);
9375 freeAsmop(result,NULL,ic,TRUE);
9376 freeAsmop(nextright,NULL,ic,TRUE);
9377 freeAsmop(nextleft,NULL,ic,TRUE);
9379 nextic->generated = 1;
9386 /*-----------------------------------------------------------------*/
9387 /* genCast - gen code for casting */
9388 /*-----------------------------------------------------------------*/
9389 static void genCast (iCode *ic)
9391 operand *result = IC_RESULT(ic);
9392 sym_link *ctype = operandType(IC_LEFT(ic));
9393 sym_link *rtype = operandType(IC_RIGHT(ic));
9394 operand *right = IC_RIGHT(ic);
9397 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9398 /* if they are equivalent then do nothing */
9399 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9402 aopOp(right,ic,FALSE) ;
9403 aopOp(result,ic,FALSE);
9405 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9407 /* if the result is a bit */
9408 if (AOP_TYPE(result) == AOP_CRY) {
9409 /* if the right size is a literal then
9410 we know what the value is */
9411 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9412 if (AOP_TYPE(right) == AOP_LIT) {
9414 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9415 popGet(AOP(result),0));
9417 if (((int) operandLitValue(right)))
9418 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9419 AOP(result)->aopu.aop_dir,
9420 AOP(result)->aopu.aop_dir);
9422 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9423 AOP(result)->aopu.aop_dir,
9424 AOP(result)->aopu.aop_dir);
9429 /* the right is also a bit variable */
9430 if (AOP_TYPE(right) == AOP_CRY) {
9433 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9435 pic14_emitcode("clrc","");
9436 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9437 AOP(right)->aopu.aop_dir,
9438 AOP(right)->aopu.aop_dir);
9439 aopPut(AOP(result),"c",0);
9444 if (AOP_TYPE(right) == AOP_REG) {
9445 emitpcode(POC_BCF, popGet(AOP(result),0));
9446 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9447 emitpcode(POC_BSF, popGet(AOP(result),0));
9449 pic14_toBoolean(right);
9450 aopPut(AOP(result),"a",0);
9454 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9456 size = AOP_SIZE(result);
9458 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9460 emitpcode(POC_CLRF, popGet(AOP(result),0));
9461 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9462 emitpcode(POC_INCF, popGet(AOP(result),0));
9465 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9470 /* if they are the same size : or less */
9471 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9473 /* if they are in the same place */
9474 if (pic14_sameRegs(AOP(right),AOP(result)))
9477 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9478 if (IS_PTR_CONST(rtype))
9479 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9480 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9481 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9483 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9484 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9485 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9486 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9487 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9488 if(AOP_SIZE(result) <2)
9489 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9493 /* if they in different places then copy */
9494 size = AOP_SIZE(result);
9497 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9498 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9500 //aopPut(AOP(result),
9501 // aopGet(AOP(right),offset,FALSE,FALSE),
9511 /* if the result is of type pointer */
9512 if (IS_PTR(ctype)) {
9515 sym_link *type = operandType(right);
9516 sym_link *etype = getSpec(type);
9517 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9519 /* pointer to generic pointer */
9520 if (IS_GENPTR(ctype)) {
9524 p_type = DCL_TYPE(type);
9526 /* we have to go by the storage class */
9527 p_type = PTR_TYPE(SPEC_OCLS(etype));
9529 /* if (SPEC_OCLS(etype)->codesp ) */
9530 /* p_type = CPOINTER ; */
9532 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9533 /* p_type = FPOINTER ; */
9535 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9536 /* p_type = PPOINTER; */
9538 /* if (SPEC_OCLS(etype) == idata ) */
9539 /* p_type = IPOINTER ; */
9541 /* p_type = POINTER ; */
9544 /* the first two bytes are known */
9545 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9546 size = GPTRSIZE - 1;
9549 if(offset < AOP_SIZE(right)) {
9550 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9551 if ((AOP_TYPE(right) == AOP_PCODE) &&
9552 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9553 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9554 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9557 aopGet(AOP(right),offset,FALSE,FALSE),
9561 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9564 /* the last byte depending on type */
9568 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9571 pic14_emitcode(";BUG!? ","%d",__LINE__);
9575 pic14_emitcode(";BUG!? ","%d",__LINE__);
9579 pic14_emitcode(";BUG!? ","%d",__LINE__);
9584 /* this should never happen */
9585 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9586 "got unknown pointer type");
9589 //aopPut(AOP(result),l, GPTRSIZE - 1);
9593 /* just copy the pointers */
9594 size = AOP_SIZE(result);
9598 aopGet(AOP(right),offset,FALSE,FALSE),
9607 /* so we now know that the size of destination is greater
9608 than the size of the source.
9609 Now, if the next iCode is an operator then we might be
9610 able to optimize the operation without performing a cast.
9612 if(genMixedOperation(ic))
9615 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9617 /* we move to result for the size of source */
9618 size = AOP_SIZE(right);
9621 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9622 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9626 /* now depending on the sign of the destination */
9627 size = AOP_SIZE(result) - AOP_SIZE(right);
9628 /* if unsigned or not an integral type */
9629 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9631 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9633 /* we need to extend the sign :{ */
9636 /* Save one instruction of casting char to int */
9637 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9638 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9639 emitpcode(POC_DECF, popGet(AOP(result),offset));
9641 emitpcodeNULLop(POC_CLRW);
9644 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9646 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9648 emitpcode(POC_MOVLW, popGetLit(0xff));
9651 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9656 freeAsmop(right,NULL,ic,TRUE);
9657 freeAsmop(result,NULL,ic,TRUE);
9661 /*-----------------------------------------------------------------*/
9662 /* genDjnz - generate decrement & jump if not zero instrucion */
9663 /*-----------------------------------------------------------------*/
9664 static int genDjnz (iCode *ic, iCode *ifx)
9667 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9672 /* if the if condition has a false label
9673 then we cannot save */
9677 /* if the minus is not of the form
9679 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9680 !IS_OP_LITERAL(IC_RIGHT(ic)))
9683 if (operandLitValue(IC_RIGHT(ic)) != 1)
9686 /* if the size of this greater than one then no
9688 if (getSize(operandType(IC_RESULT(ic))) > 1)
9691 /* otherwise we can save BIG */
9692 lbl = newiTempLabel(NULL);
9693 lbl1= newiTempLabel(NULL);
9695 aopOp(IC_RESULT(ic),ic,FALSE);
9697 if (IS_AOP_PREG(IC_RESULT(ic))) {
9698 pic14_emitcode("dec","%s",
9699 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9700 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9701 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9705 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9706 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9708 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9709 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9712 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9713 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9714 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9715 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9718 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9723 /*-----------------------------------------------------------------*/
9724 /* genReceive - generate code for a receive iCode */
9725 /*-----------------------------------------------------------------*/
9726 static void genReceive (iCode *ic)
9728 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9730 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9731 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9732 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9734 int size = getSize(operandType(IC_RESULT(ic)));
9735 int offset = fReturnSizePic - size;
9737 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9738 fReturn[fReturnSizePic - offset - 1] : "acc"));
9741 aopOp(IC_RESULT(ic),ic,FALSE);
9742 size = AOP_SIZE(IC_RESULT(ic));
9745 pic14_emitcode ("pop","acc");
9746 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9751 aopOp(IC_RESULT(ic),ic,FALSE);
9753 assignResultValue(IC_RESULT(ic));
9756 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9759 /*-----------------------------------------------------------------*/
9760 /* genpic14Code - generate code for pic14 based controllers */
9761 /*-----------------------------------------------------------------*/
9763 * At this point, ralloc.c has gone through the iCode and attempted
9764 * to optimize in a way suitable for a PIC. Now we've got to generate
9765 * PIC instructions that correspond to the iCode.
9767 * Once the instructions are generated, we'll pass through both the
9768 * peep hole optimizer and the pCode optimizer.
9769 *-----------------------------------------------------------------*/
9771 void genpic14Code (iCode *lic)
9776 lineHead = lineCurr = NULL;
9778 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9781 /* if debug information required */
9782 if (options.debug && currFunc) {
9784 cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
9786 if (IS_STATIC(currFunc->etype)) {
9787 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9788 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9790 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9791 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9798 for (ic = lic ; ic ; ic = ic->next ) {
9800 DEBUGpic14_emitcode(";ic","");
9801 if ( cln != ic->lineno ) {
9802 if ( options.debug ) {
9804 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9805 FileBaseName(ic->filename),ic->lineno,
9806 ic->level,ic->block);
9810 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9811 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9812 printCLine(ic->filename, ic->lineno));
9815 newpCodeCSource(ic->lineno,
9817 printCLine(ic->filename, ic->lineno)));
9821 /* if the result is marked as
9822 spilt and rematerializable or code for
9823 this has already been generated then
9825 if (resultRemat(ic) || ic->generated )
9828 /* depending on the operation */
9847 /* IPOP happens only when trying to restore a
9848 spilt live range, if there is an ifx statement
9849 following this pop then the if statement might
9850 be using some of the registers being popped which
9851 would destory the contents of the register so
9852 we need to check for this condition and handle it */
9854 ic->next->op == IFX &&
9855 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9856 genIfx (ic->next,ic);
9874 genEndFunction (ic);
9894 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
9911 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
9915 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
9922 /* note these two are xlated by algebraic equivalence
9923 during parsing SDCC.y */
9924 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9925 "got '>=' or '<=' shouldn't have come here");
9929 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
9941 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
9945 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
9949 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
9976 case GET_VALUE_AT_ADDRESS:
9981 if (POINTER_SET(ic))
10008 addSet(&_G.sendSet,ic);
10017 /* now we are ready to call the
10018 peep hole optimizer */
10019 if (!options.nopeep) {
10020 peepHole (&lineHead);
10022 /* now do the actual printing */
10023 printLine (lineHead,codeOutFile);
10026 DFPRINTF((stderr,"printing pBlock\n\n"));
10027 printpBlock(stdout,pb);