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"
40 #include "SDCCpeeph.h"
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
56 /* max_key keeps track of the largest label number used in
57 a function. This is then used to adjust the label offset
58 for the next function.
61 static int GpsuedoStkPtr=0;
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
70 /* this is the down and dirty file with all kinds of
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
75 static char *zero = "#0x00";
76 static char *one = "#0x01";
77 static char *spname = "sp";
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
84 static char *accUse[] = {"a","b"};
86 //static short rbank = -1;
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
101 typedef struct resolvedIfx {
102 symbol *lbl; /* pointer to a label */
103 int condition; /* true or false ifx */
104 int generated; /* set true when the code associated with the ifx
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
116 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
123 /*-----------------------------------------------------------------*/
124 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
125 /* exponent of 2 is returned, otherwise -1 is */
127 /* note that this is similar to the function `powof2' in SDCCsymt */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
135 if( (num & (num-1)) == 0) {
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
151 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
153 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155 ((left) ? AopType(AOP_TYPE(left)) : "-"),
156 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157 ((right) ? AopType(AOP_TYPE(right)) : "-"),
158 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159 ((result) ? AOP_SIZE(result) : 0));
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
180 char lb[INITIAL_INLINEASM];
190 sprintf(lb,"%s\t",inst);
192 sprintf(lb,"%s",inst);
193 vsprintf(lb+(strlen(lb)),fmt,ap);
197 while (isspace(*lbp)) lbp++;
200 lineCurr = (lineCurr ?
201 connectLine(lineCurr,newLineNode(lb)) :
202 (lineHead = newLineNode(lb)));
203 lineCurr->isInline = _G.inLine;
204 lineCurr->isDebug = _G.debugLine;
206 addpCode2pBlock(pb,newpCodeCharP(lb));
212 void emitpLabel(int key)
214 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
221 addpCode2pBlock(pb,newpCode(poc,pcop));
223 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
226 void emitpcodeNULLop(PIC_OPCODE poc)
229 addpCode2pBlock(pb,newpCode(poc,NULL));
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
239 char lb[INITIAL_INLINEASM];
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
263 addpCode2pBlock(pb,newpCodeCharP(lb));
269 /*-----------------------------------------------------------------*/
270 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
271 /*-----------------------------------------------------------------*/
272 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
274 bool r0iu = FALSE , r1iu = FALSE;
275 bool r0ou = FALSE , r1ou = FALSE;
277 /* the logic: if r0 & r1 used in the instruction
278 then we are in trouble otherwise */
280 /* first check if r0 & r1 are used by this
281 instruction, in which case we are in trouble */
282 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
283 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
288 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
289 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
291 /* if no usage of r0 then return it */
292 if (!r0iu && !r0ou) {
293 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
294 (*aopp)->type = AOP_R0;
296 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
299 /* if no usage of r1 then return it */
300 if (!r1iu && !r1ou) {
301 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
302 (*aopp)->type = AOP_R1;
304 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
307 /* now we know they both have usage */
308 /* if r0 not used in this instruction */
310 /* push it if not already pushed */
312 //pic14_emitcode ("push","%s",
313 // pic14_regWithIdx(R0_IDX)->dname);
317 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
318 (*aopp)->type = AOP_R0;
320 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
323 /* if r1 not used then */
326 /* push it if not already pushed */
328 //pic14_emitcode ("push","%s",
329 // pic14_regWithIdx(R1_IDX)->dname);
333 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
334 (*aopp)->type = AOP_R1;
335 return pic14_regWithIdx(R1_IDX);
339 /* I said end of world but not quite end of world yet */
340 /* if this is a result then we can push it on the stack*/
342 (*aopp)->type = AOP_STK;
346 /* other wise this is true end of the world */
347 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
348 "getFreePtr should never reach here");
352 /*-----------------------------------------------------------------*/
353 /* newAsmop - creates a new asmOp */
354 /*-----------------------------------------------------------------*/
355 asmop *newAsmop (short type)
359 aop = Safe_calloc(1,sizeof(asmop));
364 static void genSetDPTR(int n)
368 pic14_emitcode(";", "Select standard DPTR");
369 pic14_emitcode("mov", "dps, #0x00");
373 pic14_emitcode(";", "Select alternate DPTR");
374 pic14_emitcode("mov", "dps, #0x01");
378 /*-----------------------------------------------------------------*/
379 /* resolveIfx - converts an iCode ifx into a form more useful for */
380 /* generating code */
381 /*-----------------------------------------------------------------*/
382 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
387 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
389 resIfx->condition = 1; /* assume that the ifx is true */
390 resIfx->generated = 0; /* indicate that the ifx has not been used */
393 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
395 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
396 __FUNCTION__,__LINE__,resIfx->lbl->key);
400 resIfx->lbl = IC_TRUE(ifx);
402 resIfx->lbl = IC_FALSE(ifx);
403 resIfx->condition = 0;
407 DEBUGpic14_emitcode("; ***","ifx true is non-null");
409 DEBUGpic14_emitcode("; ***","ifx false is non-null");
413 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
416 /*-----------------------------------------------------------------*/
417 /* pointerCode - returns the code for a pointer type */
418 /*-----------------------------------------------------------------*/
419 static int pointerCode (sym_link *etype)
422 return PTR_TYPE(SPEC_OCLS(etype));
426 /*-----------------------------------------------------------------*/
427 /* aopForSym - for a true symbol */
428 /*-----------------------------------------------------------------*/
429 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
432 memmap *space= SPEC_OCLS(sym->etype);
434 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
435 /* if already has one */
439 /* assign depending on the storage class */
440 /* if it is on the stack or indirectly addressable */
441 /* space we need to assign either r0 or r1 to it */
442 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
443 sym->aop = aop = newAsmop(0);
444 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
445 aop->size = getSize(sym->type);
447 /* now assign the address of the variable to
448 the pointer register */
449 if (aop->type != AOP_STK) {
453 pic14_emitcode("push","acc");
455 pic14_emitcode("mov","a,_bp");
456 pic14_emitcode("add","a,#0x%02x",
458 ((char)(sym->stack - _G.nRegsSaved )) :
459 ((char)sym->stack)) & 0xff);
460 pic14_emitcode("mov","%s,a",
461 aop->aopu.aop_ptr->name);
464 pic14_emitcode("pop","acc");
466 pic14_emitcode("mov","%s,#%s",
467 aop->aopu.aop_ptr->name,
469 aop->paged = space->paged;
471 aop->aopu.aop_stk = sym->stack;
475 if (sym->onStack && options.stack10bit)
477 /* It's on the 10 bit stack, which is located in
481 //DEBUGpic14_emitcode(";","%d",__LINE__);
484 pic14_emitcode("push","acc");
486 pic14_emitcode("mov","a,_bp");
487 pic14_emitcode("add","a,#0x%02x",
489 ((char)(sym->stack - _G.nRegsSaved )) :
490 ((char)sym->stack)) & 0xff);
493 pic14_emitcode ("mov","dpx1,#0x40");
494 pic14_emitcode ("mov","dph1,#0x00");
495 pic14_emitcode ("mov","dpl1, a");
499 pic14_emitcode("pop","acc");
501 sym->aop = aop = newAsmop(AOP_DPTR2);
502 aop->size = getSize(sym->type);
506 //DEBUGpic14_emitcode(";","%d",__LINE__);
507 /* if in bit space */
508 if (IN_BITSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_CRY);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
515 /* if it is in direct space */
516 if (IN_DIRSPACE(space)) {
517 sym->aop = aop = newAsmop (AOP_DIR);
518 aop->aopu.aop_dir = sym->rname ;
519 aop->size = getSize(sym->type);
520 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
524 /* special case for a function */
525 if (IS_FUNC(sym->type)) {
526 sym->aop = aop = newAsmop(AOP_IMMD);
527 //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
528 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
529 strcpy(aop->aopu.aop_immd,sym->rname);
530 aop->size = FPTRSIZE;
531 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
536 /* only remaining is far space */
537 /* in which case DPTR gets the address */
538 sym->aop = aop = newAsmop(AOP_PCODE);
540 aop->aopu.pcop = popGetImmd(sym->rname,0,0);
541 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
542 PCOI(aop->aopu.pcop)->index = 0;
544 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
545 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
547 allocDirReg (IC_LEFT(ic));
549 aop->size = FPTRSIZE;
551 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
552 sym->aop = aop = newAsmop(AOP_DPTR);
553 pic14_emitcode ("mov","dptr,#%s", sym->rname);
554 aop->size = getSize(sym->type);
556 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
559 /* if it is in code space */
560 if (IN_CODESPACE(space))
566 /*-----------------------------------------------------------------*/
567 /* aopForRemat - rematerialzes an object */
568 /*-----------------------------------------------------------------*/
569 static asmop *aopForRemat (operand *op) // x symbol *sym)
571 symbol *sym = OP_SYMBOL(op);
573 asmop *aop = newAsmop(AOP_PCODE);
577 ic = sym->rematiCode;
579 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
580 if(IS_OP_POINTER(op)) {
581 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
585 val += (int) operandLitValue(IC_RIGHT(ic));
586 } else if (ic->op == '-') {
587 val -= (int) operandLitValue(IC_RIGHT(ic));
591 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
594 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
595 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
596 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
597 PCOI(aop->aopu.pcop)->index = val;
599 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
600 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
601 val, IS_PTR_CONST(operandType(op)));
603 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
605 allocDirReg (IC_LEFT(ic));
610 int aopIdx (asmop *aop, int offset)
615 if(aop->type != AOP_REG)
618 return aop->aopu.aop_reg[offset]->rIdx;
621 /*-----------------------------------------------------------------*/
622 /* regsInCommon - two operands have some registers in common */
623 /*-----------------------------------------------------------------*/
624 static bool regsInCommon (operand *op1, operand *op2)
629 /* if they have registers in common */
630 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
633 sym1 = OP_SYMBOL(op1);
634 sym2 = OP_SYMBOL(op2);
636 if (sym1->nRegs == 0 || sym2->nRegs == 0)
639 for (i = 0 ; i < sym1->nRegs ; i++) {
644 for (j = 0 ; j < sym2->nRegs ;j++ ) {
648 if (sym2->regs[j] == sym1->regs[i])
656 /*-----------------------------------------------------------------*/
657 /* operandsEqu - equivalent */
658 /*-----------------------------------------------------------------*/
659 static bool operandsEqu ( operand *op1, operand *op2)
663 /* if they not symbols */
664 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
667 sym1 = OP_SYMBOL(op1);
668 sym2 = OP_SYMBOL(op2);
670 /* if both are itemps & one is spilt
671 and the other is not then false */
672 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
673 sym1->isspilt != sym2->isspilt )
676 /* if they are the same */
680 if (strcmp(sym1->rname,sym2->rname) == 0)
684 /* if left is a tmp & right is not */
688 (sym1->usl.spillLoc == sym2))
695 (sym2->usl.spillLoc == sym1))
701 /*-----------------------------------------------------------------*/
702 /* pic14_sameRegs - two asmops have the same registers */
703 /*-----------------------------------------------------------------*/
704 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
711 if (aop1->type != AOP_REG ||
712 aop2->type != AOP_REG )
715 if (aop1->size != aop2->size )
718 for (i = 0 ; i < aop1->size ; i++ )
719 if (aop1->aopu.aop_reg[i] !=
720 aop2->aopu.aop_reg[i] )
726 /*-----------------------------------------------------------------*/
727 /* aopOp - allocates an asmop for an operand : */
728 /*-----------------------------------------------------------------*/
729 void aopOp (operand *op, iCode *ic, bool result)
738 // DEBUGpic14_emitcode(";","%d",__LINE__);
739 /* if this a literal */
740 if (IS_OP_LITERAL(op)) {
741 op->aop = aop = newAsmop(AOP_LIT);
742 aop->aopu.aop_lit = op->operand.valOperand;
743 aop->size = getSize(operandType(op));
748 sym_link *type = operandType(op);
749 if(IS_PTR_CONST(type))
750 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
753 /* if already has a asmop then continue */
757 /* if the underlying symbol has a aop */
758 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
759 DEBUGpic14_emitcode(";","%d",__LINE__);
760 op->aop = OP_SYMBOL(op)->aop;
764 /* if this is a true symbol */
765 if (IS_TRUE_SYMOP(op)) {
766 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
767 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
771 /* this is a temporary : this has
777 e) can be a return use only */
782 /* if the type is a conditional */
783 if (sym->regType == REG_CND) {
784 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
789 /* if it is spilt then two situations
791 b) has a spill location */
792 if (sym->isspilt || sym->nRegs == 0) {
794 DEBUGpic14_emitcode(";","%d",__LINE__);
795 /* rematerialize it NOW */
798 sym->aop = op->aop = aop =
800 aop->size = getSize(sym->type);
801 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
807 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
808 aop->size = getSize(sym->type);
809 for ( i = 0 ; i < 2 ; i++ )
810 aop->aopu.aop_str[i] = accUse[i];
811 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
816 if(sym->isptr) { // && sym->uptr
817 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
818 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
820 //PCOI(aop->aopu.pcop)->_const = 0;
821 //PCOI(aop->aopu.pcop)->index = 0;
823 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
824 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
826 //allocDirReg (IC_LEFT(ic));
828 aop->size = getSize(sym->type);
829 DEBUGpic14_emitcode(";","%d",__LINE__);
836 aop = op->aop = sym->aop = newAsmop(AOP_STR);
837 aop->size = getSize(sym->type);
838 for ( i = 0 ; i < fReturnSizePic ; i++ )
839 aop->aopu.aop_str[i] = fReturn[i];
841 DEBUGpic14_emitcode(";","%d",__LINE__);
846 /* else spill location */
847 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
848 /* force a new aop if sizes differ */
849 sym->usl.spillLoc->aop = NULL;
851 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
852 __FUNCTION__,__LINE__,
853 sym->usl.spillLoc->rname,
854 sym->rname, sym->usl.spillLoc->offset);
856 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
857 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
858 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
860 sym->usl.spillLoc->offset);
861 aop->size = getSize(sym->type);
867 sym_link *type = operandType(op);
868 if(IS_PTR_CONST(type))
869 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
872 /* must be in a register */
873 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
874 sym->aop = op->aop = aop = newAsmop(AOP_REG);
875 aop->size = sym->nRegs;
876 for ( i = 0 ; i < sym->nRegs ;i++)
877 aop->aopu.aop_reg[i] = sym->regs[i];
880 /*-----------------------------------------------------------------*/
881 /* freeAsmop - free up the asmop given to an operand */
882 /*----------------------------------------------------------------*/
883 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
900 /* depending on the asmop type only three cases need work AOP_RO
901 , AOP_R1 && AOP_STK */
907 pic14_emitcode ("pop","ar0");
911 bitVectUnSetBit(ic->rUsed,R0_IDX);
917 pic14_emitcode ("pop","ar1");
921 bitVectUnSetBit(ic->rUsed,R1_IDX);
927 int stk = aop->aopu.aop_stk + aop->size;
928 bitVectUnSetBit(ic->rUsed,R0_IDX);
929 bitVectUnSetBit(ic->rUsed,R1_IDX);
931 getFreePtr(ic,&aop,FALSE);
933 if (options.stack10bit)
935 /* I'm not sure what to do here yet... */
938 "*** Warning: probably generating bad code for "
939 "10 bit stack mode.\n");
943 pic14_emitcode ("mov","a,_bp");
944 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
945 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
947 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
951 pic14_emitcode("pop","acc");
952 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
954 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
957 freeAsmop(op,NULL,ic,TRUE);
959 pic14_emitcode("pop","ar0");
964 pic14_emitcode("pop","ar1");
972 /* all other cases just dealloc */
976 OP_SYMBOL(op)->aop = NULL;
977 /* if the symbol has a spill */
979 SPIL_LOC(op)->aop = NULL;
984 /*-----------------------------------------------------------------*/
985 /* aopGet - for fetching value of the aop */
986 /*-----------------------------------------------------------------*/
987 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
992 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
993 /* offset is greater than
995 if (offset > (aop->size - 1) &&
996 aop->type != AOP_LIT)
999 /* depending on type */
1000 switch (aop->type) {
1004 DEBUGpic14_emitcode(";","%d",__LINE__);
1005 /* if we need to increment it */
1006 while (offset > aop->coff) {
1007 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1011 while (offset < aop->coff) {
1012 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1016 aop->coff = offset ;
1018 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1019 return (dname ? "acc" : "a");
1021 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1022 rs = Safe_calloc(1,strlen(s)+1);
1028 DEBUGpic14_emitcode(";","%d",__LINE__);
1029 if (aop->type == AOP_DPTR2)
1034 while (offset > aop->coff) {
1035 pic14_emitcode ("inc","dptr");
1039 while (offset < aop->coff) {
1040 pic14_emitcode("lcall","__decdptr");
1046 pic14_emitcode("clr","a");
1047 pic14_emitcode("movc","a,@a+dptr");
1050 pic14_emitcode("movx","a,@dptr");
1053 if (aop->type == AOP_DPTR2)
1058 return (dname ? "acc" : "a");
1063 sprintf (s,"%s",aop->aopu.aop_immd);
1066 sprintf(s,"(%s >> %d)",
1071 aop->aopu.aop_immd);
1072 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1073 rs = Safe_calloc(1,strlen(s)+1);
1079 sprintf(s,"(%s + %d)",
1082 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1084 sprintf(s,"%s",aop->aopu.aop_dir);
1085 rs = Safe_calloc(1,strlen(s)+1);
1091 // return aop->aopu.aop_reg[offset]->dname;
1093 return aop->aopu.aop_reg[offset]->name;
1096 //pic14_emitcode(";","%d",__LINE__);
1097 return aop->aopu.aop_dir;
1100 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1101 return "AOP_accumulator_bug";
1104 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1105 rs = Safe_calloc(1,strlen(s)+1);
1110 aop->coff = offset ;
1111 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1114 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1116 return aop->aopu.aop_str[offset];
1120 pCodeOp *pcop = aop->aopu.pcop;
1121 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1123 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1124 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1125 sprintf(s,"%s", pcop->name);
1127 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1130 rs = Safe_calloc(1,strlen(s)+1);
1136 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1137 "aopget got unsupported aop->type");
1142 /*-----------------------------------------------------------------*/
1143 /* popGetTempReg - create a new temporary pCodeOp */
1144 /*-----------------------------------------------------------------*/
1145 pCodeOp *popGetTempReg(void)
1150 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1151 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1152 PCOR(pcop)->r->wasUsed=1;
1153 PCOR(pcop)->r->isFree=0;
1159 /*-----------------------------------------------------------------*/
1160 /* popGetTempReg - create a new temporary pCodeOp */
1161 /*-----------------------------------------------------------------*/
1162 void popReleaseTempReg(pCodeOp *pcop)
1165 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1166 PCOR(pcop)->r->isFree = 1;
1169 /*-----------------------------------------------------------------*/
1170 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1171 /*-----------------------------------------------------------------*/
1172 pCodeOp *popGetLabel(unsigned int key)
1175 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1180 return newpCodeOpLabel(NULL,key+100+labelOffset);
1183 /*-----------------------------------------------------------------*/
1184 /* popCopyReg - copy a pcode operator */
1185 /*-----------------------------------------------------------------*/
1186 pCodeOp *popCopyReg(pCodeOpReg *pc)
1190 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1191 pcor->pcop.type = pc->pcop.type;
1193 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1194 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1196 pcor->pcop.name = NULL;
1199 pcor->rIdx = pc->rIdx;
1202 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1206 /*-----------------------------------------------------------------*/
1207 /* popGet - asm operator to pcode operator conversion */
1208 /*-----------------------------------------------------------------*/
1209 pCodeOp *popGetLit(unsigned int lit)
1212 return newpCodeOpLit(lit);
1216 /*-----------------------------------------------------------------*/
1217 /* popGetImmd - asm operator to pcode immediate conversion */
1218 /*-----------------------------------------------------------------*/
1219 pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
1222 return newpCodeOpImmd(name, offset,index, 0);
1226 /*-----------------------------------------------------------------*/
1227 /* popGet - asm operator to pcode operator conversion */
1228 /*-----------------------------------------------------------------*/
1229 pCodeOp *popGetWithString(char *str)
1235 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1239 pcop = newpCodeOp(str,PO_STR);
1244 /*-----------------------------------------------------------------*/
1245 /* popRegFromString - */
1246 /*-----------------------------------------------------------------*/
1247 pCodeOp *popRegFromString(char *str, int size, int offset)
1250 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1251 pcop->type = PO_DIR;
1253 DEBUGpic14_emitcode(";","%d",__LINE__);
1258 pcop->name = Safe_calloc(1,strlen(str)+1);
1259 strcpy(pcop->name,str);
1261 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1263 PCOR(pcop)->r = dirregWithName(pcop->name);
1264 if(PCOR(pcop)->r == NULL) {
1265 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1266 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1267 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1269 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1271 PCOR(pcop)->instance = offset;
1276 pCodeOp *popRegFromIdx(int rIdx)
1280 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1281 __FUNCTION__,__LINE__,rIdx);
1283 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1285 PCOR(pcop)->rIdx = rIdx;
1286 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1287 PCOR(pcop)->r->isFree = 0;
1288 PCOR(pcop)->r->wasUsed = 1;
1290 pcop->type = PCOR(pcop)->r->pc_type;
1295 /*-----------------------------------------------------------------*/
1296 /* popGet - asm operator to pcode operator conversion */
1297 /*-----------------------------------------------------------------*/
1298 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1300 //char *s = buffer ;
1305 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1306 /* offset is greater than
1309 if (offset > (aop->size - 1) &&
1310 aop->type != AOP_LIT)
1311 return NULL; //zero;
1313 /* depending on type */
1314 switch (aop->type) {
1321 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1325 DEBUGpic14_emitcode(";","%d",__LINE__);
1326 return popGetImmd(aop->aopu.aop_immd,offset,0);
1329 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1331 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1332 pcop->type = PO_DIR;
1336 sprintf(s,"(%s + %d)",
1340 sprintf(s,"%s",aop->aopu.aop_dir);
1341 pcop->name = Safe_calloc(1,strlen(s)+1);
1342 strcpy(pcop->name,s);
1344 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1345 strcpy(pcop->name,aop->aopu.aop_dir);
1346 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1347 if(PCOR(pcop)->r == NULL) {
1348 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1349 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1350 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1352 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1354 PCOR(pcop)->instance = offset;
1361 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1363 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1364 PCOR(pcop)->rIdx = rIdx;
1365 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1366 PCOR(pcop)->r->wasUsed=1;
1367 PCOR(pcop)->r->isFree=0;
1369 PCOR(pcop)->instance = offset;
1370 pcop->type = PCOR(pcop)->r->pc_type;
1371 //rs = aop->aopu.aop_reg[offset]->name;
1372 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1377 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1378 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1379 //if(PCOR(pcop)->r == NULL)
1380 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1384 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1387 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1388 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1390 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1391 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1392 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1393 pcop->type = PCOR(pcop)->r->pc_type;
1394 pcop->name = PCOR(pcop)->r->name;
1400 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1402 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1403 pcop = pCodeOpCopy(aop->aopu.pcop);
1404 PCOI(pcop)->offset = offset;
1408 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1409 "popGet got unsupported aop->type");
1412 /*-----------------------------------------------------------------*/
1413 /* aopPut - puts a string for a aop */
1414 /*-----------------------------------------------------------------*/
1415 void aopPut (asmop *aop, char *s, int offset)
1420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1422 if (aop->size && offset > ( aop->size - 1)) {
1423 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1424 "aopPut got offset > aop->size");
1428 /* will assign value to value */
1429 /* depending on where it is ofcourse */
1430 switch (aop->type) {
1433 sprintf(d,"(%s + %d)",
1434 aop->aopu.aop_dir,offset);
1435 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1438 sprintf(d,"%s",aop->aopu.aop_dir);
1441 DEBUGpic14_emitcode(";","%d",__LINE__);
1443 pic14_emitcode("movf","%s,w",s);
1444 pic14_emitcode("movwf","%s",d);
1447 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1448 if(offset >= aop->size) {
1449 emitpcode(POC_CLRF,popGet(aop,offset));
1452 emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
1455 emitpcode(POC_MOVWF,popGet(aop,offset));
1462 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1463 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1466 strcmp(s,"r0") == 0 ||
1467 strcmp(s,"r1") == 0 ||
1468 strcmp(s,"r2") == 0 ||
1469 strcmp(s,"r3") == 0 ||
1470 strcmp(s,"r4") == 0 ||
1471 strcmp(s,"r5") == 0 ||
1472 strcmp(s,"r6") == 0 ||
1473 strcmp(s,"r7") == 0 )
1474 pic14_emitcode("mov","%s,%s ; %d",
1475 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1479 if(strcmp(s,"W")==0 )
1480 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1482 pic14_emitcode("movwf","%s",
1483 aop->aopu.aop_reg[offset]->name);
1485 if(strcmp(s,zero)==0) {
1486 emitpcode(POC_CLRF,popGet(aop,offset));
1488 } else if(strcmp(s,"W")==0) {
1489 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1490 pcop->type = PO_GPR_REGISTER;
1492 PCOR(pcop)->rIdx = -1;
1493 PCOR(pcop)->r = NULL;
1495 DEBUGpic14_emitcode(";","%d",__LINE__);
1496 pcop->name = Safe_strdup(s);
1497 emitpcode(POC_MOVFW,pcop);
1498 emitpcode(POC_MOVWF,popGet(aop,offset));
1499 } else if(strcmp(s,one)==0) {
1500 emitpcode(POC_CLRF,popGet(aop,offset));
1501 emitpcode(POC_INCF,popGet(aop,offset));
1503 emitpcode(POC_MOVWF,popGet(aop,offset));
1511 if (aop->type == AOP_DPTR2)
1517 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1518 "aopPut writting to code space");
1522 while (offset > aop->coff) {
1524 pic14_emitcode ("inc","dptr");
1527 while (offset < aop->coff) {
1529 pic14_emitcode("lcall","__decdptr");
1534 /* if not in accumulater */
1537 pic14_emitcode ("movx","@dptr,a");
1539 if (aop->type == AOP_DPTR2)
1547 while (offset > aop->coff) {
1549 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1551 while (offset < aop->coff) {
1553 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1559 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1564 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1566 if (strcmp(s,"r0") == 0 ||
1567 strcmp(s,"r1") == 0 ||
1568 strcmp(s,"r2") == 0 ||
1569 strcmp(s,"r3") == 0 ||
1570 strcmp(s,"r4") == 0 ||
1571 strcmp(s,"r5") == 0 ||
1572 strcmp(s,"r6") == 0 ||
1573 strcmp(s,"r7") == 0 ) {
1575 sprintf(buffer,"a%s",s);
1576 pic14_emitcode("mov","@%s,%s",
1577 aop->aopu.aop_ptr->name,buffer);
1579 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1584 if (strcmp(s,"a") == 0)
1585 pic14_emitcode("push","acc");
1587 pic14_emitcode("push","%s",s);
1592 /* if bit variable */
1593 if (!aop->aopu.aop_dir) {
1594 pic14_emitcode("clr","a");
1595 pic14_emitcode("rlc","a");
1598 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1601 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1604 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1606 lbl = newiTempLabel(NULL);
1608 if (strcmp(s,"a")) {
1611 pic14_emitcode("clr","c");
1612 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1613 pic14_emitcode("cpl","c");
1614 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1615 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1622 if (strcmp(aop->aopu.aop_str[offset],s))
1623 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1628 if (!offset && (strcmp(s,"acc") == 0))
1631 if (strcmp(aop->aopu.aop_str[offset],s))
1632 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1636 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1637 "aopPut got unsupported aop->type");
1643 /*-----------------------------------------------------------------*/
1644 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1645 /*-----------------------------------------------------------------*/
1646 void mov2w (asmop *aop, int offset)
1652 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1654 if ( aop->type == AOP_PCODE ||
1655 aop->type == AOP_LIT ||
1656 aop->type == AOP_IMMD )
1657 emitpcode(POC_MOVLW,popGet(aop,offset));
1659 emitpcode(POC_MOVFW,popGet(aop,offset));
1663 /*-----------------------------------------------------------------*/
1664 /* reAdjustPreg - points a register back to where it should */
1665 /*-----------------------------------------------------------------*/
1666 static void reAdjustPreg (asmop *aop)
1670 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1672 if ((size = aop->size) <= 1)
1675 switch (aop->type) {
1679 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1683 if (aop->type == AOP_DPTR2)
1689 pic14_emitcode("lcall","__decdptr");
1692 if (aop->type == AOP_DPTR2)
1702 /*-----------------------------------------------------------------*/
1703 /* genNotFloat - generates not for float operations */
1704 /*-----------------------------------------------------------------*/
1705 static void genNotFloat (operand *op, operand *res)
1711 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1712 /* we will put 127 in the first byte of
1714 aopPut(AOP(res),"#127",0);
1715 size = AOP_SIZE(op) - 1;
1718 l = aopGet(op->aop,offset++,FALSE,FALSE);
1722 pic14_emitcode("orl","a,%s",
1724 offset++,FALSE,FALSE));
1726 tlbl = newiTempLabel(NULL);
1728 tlbl = newiTempLabel(NULL);
1729 aopPut(res->aop,one,1);
1730 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1731 aopPut(res->aop,zero,1);
1732 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1734 size = res->aop->size - 2;
1736 /* put zeros in the rest */
1738 aopPut(res->aop,zero,offset++);
1742 /*-----------------------------------------------------------------*/
1743 /* opIsGptr: returns non-zero if the passed operand is */
1744 /* a generic pointer type. */
1745 /*-----------------------------------------------------------------*/
1746 static int opIsGptr(operand *op)
1748 sym_link *type = operandType(op);
1750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1751 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1759 /*-----------------------------------------------------------------*/
1760 /* pic14_getDataSize - get the operand data size */
1761 /*-----------------------------------------------------------------*/
1762 int pic14_getDataSize(operand *op)
1764 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1767 return AOP_SIZE(op);
1769 // tsd- in the pic port, the genptr size is 1, so this code here
1770 // fails. ( in the 8051 port, the size was 4).
1773 size = AOP_SIZE(op);
1774 if (size == GPTRSIZE)
1776 sym_link *type = operandType(op);
1777 if (IS_GENPTR(type))
1779 /* generic pointer; arithmetic operations
1780 * should ignore the high byte (pointer type).
1783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1790 /*-----------------------------------------------------------------*/
1791 /* pic14_outAcc - output Acc */
1792 /*-----------------------------------------------------------------*/
1793 void pic14_outAcc(operand *result)
1796 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1797 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1800 size = pic14_getDataSize(result);
1802 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1805 /* unsigned or positive */
1807 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1812 /*-----------------------------------------------------------------*/
1813 /* pic14_outBitC - output a bit C */
1814 /*-----------------------------------------------------------------*/
1815 void pic14_outBitC(operand *result)
1818 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1819 /* if the result is bit */
1820 if (AOP_TYPE(result) == AOP_CRY)
1821 aopPut(AOP(result),"c",0);
1823 pic14_emitcode("clr","a ; %d", __LINE__);
1824 pic14_emitcode("rlc","a");
1825 pic14_outAcc(result);
1829 /*-----------------------------------------------------------------*/
1830 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1831 /*-----------------------------------------------------------------*/
1832 void pic14_toBoolean(operand *oper)
1834 int size = AOP_SIZE(oper) - 1;
1837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1839 if ( AOP_TYPE(oper) != AOP_ACC) {
1840 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1843 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1848 /*-----------------------------------------------------------------*/
1849 /* genNot - generate code for ! operation */
1850 /*-----------------------------------------------------------------*/
1851 static void genNot (iCode *ic)
1854 sym_link *optype = operandType(IC_LEFT(ic));
1857 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1858 /* assign asmOps to operand & result */
1859 aopOp (IC_LEFT(ic),ic,FALSE);
1860 aopOp (IC_RESULT(ic),ic,TRUE);
1862 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1863 /* if in bit space then a special case */
1864 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1865 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1866 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1867 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1869 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1870 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1871 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1876 /* if type float then do float */
1877 if (IS_FLOAT(optype)) {
1878 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1882 size = AOP_SIZE(IC_RESULT(ic));
1884 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1885 emitpcode(POC_ANDLW,popGetLit(1));
1886 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1889 pic14_toBoolean(IC_LEFT(ic));
1891 tlbl = newiTempLabel(NULL);
1892 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1893 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1894 pic14_outBitC(IC_RESULT(ic));
1897 /* release the aops */
1898 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1903 /*-----------------------------------------------------------------*/
1904 /* genCpl - generate code for complement */
1905 /*-----------------------------------------------------------------*/
1906 static void genCpl (iCode *ic)
1908 operand *left, *result;
1912 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1913 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1914 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1916 /* if both are in bit space then
1918 if (AOP_TYPE(result) == AOP_CRY &&
1919 AOP_TYPE(left) == AOP_CRY ) {
1921 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1922 pic14_emitcode("cpl","c");
1923 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1927 size = AOP_SIZE(result);
1930 if(AOP_TYPE(left) == AOP_ACC)
1931 emitpcode(POC_XORLW, popGetLit(0xff));
1933 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1935 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1941 /* release the aops */
1942 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1943 freeAsmop(result,NULL,ic,TRUE);
1946 /*-----------------------------------------------------------------*/
1947 /* genUminusFloat - unary minus for floating points */
1948 /*-----------------------------------------------------------------*/
1949 static void genUminusFloat(operand *op,operand *result)
1951 int size ,offset =0 ;
1954 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1955 /* for this we just need to flip the
1956 first it then copy the rest in place */
1957 size = AOP_SIZE(op) - 1;
1958 l = aopGet(AOP(op),3,FALSE,FALSE);
1962 pic14_emitcode("cpl","acc.7");
1963 aopPut(AOP(result),"a",3);
1967 aopGet(AOP(op),offset,FALSE,FALSE),
1973 /*-----------------------------------------------------------------*/
1974 /* genUminus - unary minus code generation */
1975 /*-----------------------------------------------------------------*/
1976 static void genUminus (iCode *ic)
1979 sym_link *optype, *rtype;
1982 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1984 aopOp(IC_LEFT(ic),ic,FALSE);
1985 aopOp(IC_RESULT(ic),ic,TRUE);
1987 /* if both in bit space then special
1989 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1990 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1992 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1993 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1994 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1999 optype = operandType(IC_LEFT(ic));
2000 rtype = operandType(IC_RESULT(ic));
2002 /* if float then do float stuff */
2003 if (IS_FLOAT(optype)) {
2004 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2008 /* otherwise subtract from zero by taking the 2's complement */
2009 size = AOP_SIZE(IC_LEFT(ic));
2011 for(i=0; i<size; i++) {
2012 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2013 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2015 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2016 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2020 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2021 for(i=1; i<size; i++) {
2023 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2027 /* release the aops */
2028 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2029 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2032 /*-----------------------------------------------------------------*/
2033 /* saveRegisters - will look for a call and save the registers */
2034 /*-----------------------------------------------------------------*/
2035 static void saveRegisters(iCode *lic)
2042 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2044 for (ic = lic ; ic ; ic = ic->next)
2045 if (ic->op == CALL || ic->op == PCALL)
2049 fprintf(stderr,"found parameter push with no function call\n");
2053 /* if the registers have been saved already then
2055 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2058 /* find the registers in use at this time
2059 and push them away to safety */
2060 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2064 if (options.useXstack) {
2065 if (bitVectBitValue(rsave,R0_IDX))
2066 pic14_emitcode("mov","b,r0");
2067 pic14_emitcode("mov","r0,%s",spname);
2068 for (i = 0 ; i < pic14_nRegs ; i++) {
2069 if (bitVectBitValue(rsave,i)) {
2071 pic14_emitcode("mov","a,b");
2073 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2074 pic14_emitcode("movx","@r0,a");
2075 pic14_emitcode("inc","r0");
2078 pic14_emitcode("mov","%s,r0",spname);
2079 if (bitVectBitValue(rsave,R0_IDX))
2080 pic14_emitcode("mov","r0,b");
2082 //for (i = 0 ; i < pic14_nRegs ; i++) {
2083 // if (bitVectBitValue(rsave,i))
2084 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2087 dtype = operandType(IC_LEFT(ic));
2088 if (currFunc && dtype &&
2089 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2090 IFFUNC_ISISR(currFunc->type) &&
2093 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2096 /*-----------------------------------------------------------------*/
2097 /* unsaveRegisters - pop the pushed registers */
2098 /*-----------------------------------------------------------------*/
2099 static void unsaveRegisters (iCode *ic)
2104 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2105 /* find the registers in use at this time
2106 and push them away to safety */
2107 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2110 if (options.useXstack) {
2111 pic14_emitcode("mov","r0,%s",spname);
2112 for (i = pic14_nRegs ; i >= 0 ; i--) {
2113 if (bitVectBitValue(rsave,i)) {
2114 pic14_emitcode("dec","r0");
2115 pic14_emitcode("movx","a,@r0");
2117 pic14_emitcode("mov","b,a");
2119 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2123 pic14_emitcode("mov","%s,r0",spname);
2124 if (bitVectBitValue(rsave,R0_IDX))
2125 pic14_emitcode("mov","r0,b");
2127 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2128 // if (bitVectBitValue(rsave,i))
2129 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2135 /*-----------------------------------------------------------------*/
2137 /*-----------------------------------------------------------------*/
2138 static void pushSide(operand * oper, int size)
2142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2144 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2145 if (AOP_TYPE(oper) != AOP_REG &&
2146 AOP_TYPE(oper) != AOP_DIR &&
2148 pic14_emitcode("mov","a,%s",l);
2149 pic14_emitcode("push","acc");
2151 pic14_emitcode("push","%s",l);
2156 /*-----------------------------------------------------------------*/
2157 /* assignResultValue - */
2158 /*-----------------------------------------------------------------*/
2159 static void assignResultValue(operand * oper)
2161 int size = AOP_SIZE(oper);
2163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2165 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2167 if(!GpsuedoStkPtr) {
2168 /* The last byte in the assignment is in W */
2170 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2172 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2176 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2178 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2183 /*-----------------------------------------------------------------*/
2184 /* genIpush - genrate code for pushing this gets a little complex */
2185 /*-----------------------------------------------------------------*/
2186 static void genIpush (iCode *ic)
2189 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2191 int size, offset = 0 ;
2195 /* if this is not a parm push : ie. it is spill push
2196 and spill push is always done on the local stack */
2197 if (!ic->parmPush) {
2199 /* and the item is spilt then do nothing */
2200 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2203 aopOp(IC_LEFT(ic),ic,FALSE);
2204 size = AOP_SIZE(IC_LEFT(ic));
2205 /* push it on the stack */
2207 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2212 pic14_emitcode("push","%s",l);
2217 /* this is a paramter push: in this case we call
2218 the routine to find the call and save those
2219 registers that need to be saved */
2222 /* then do the push */
2223 aopOp(IC_LEFT(ic),ic,FALSE);
2226 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2227 size = AOP_SIZE(IC_LEFT(ic));
2230 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2231 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2232 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2234 pic14_emitcode("mov","a,%s",l);
2235 pic14_emitcode("push","acc");
2237 pic14_emitcode("push","%s",l);
2240 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2244 /*-----------------------------------------------------------------*/
2245 /* genIpop - recover the registers: can happen only for spilling */
2246 /*-----------------------------------------------------------------*/
2247 static void genIpop (iCode *ic)
2249 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2254 /* if the temp was not pushed then */
2255 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2258 aopOp(IC_LEFT(ic),ic,FALSE);
2259 size = AOP_SIZE(IC_LEFT(ic));
2262 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2265 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2269 /*-----------------------------------------------------------------*/
2270 /* unsaverbank - restores the resgister bank from stack */
2271 /*-----------------------------------------------------------------*/
2272 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2274 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2282 if (options.useXstack) {
2284 r = getFreePtr(ic,&aop,FALSE);
2287 pic14_emitcode("mov","%s,_spx",r->name);
2288 pic14_emitcode("movx","a,@%s",r->name);
2289 pic14_emitcode("mov","psw,a");
2290 pic14_emitcode("dec","%s",r->name);
2293 pic14_emitcode ("pop","psw");
2296 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2297 if (options.useXstack) {
2298 pic14_emitcode("movx","a,@%s",r->name);
2299 //pic14_emitcode("mov","(%s+%d),a",
2300 // regspic14[i].base,8*bank+regspic14[i].offset);
2301 pic14_emitcode("dec","%s",r->name);
2304 pic14_emitcode("pop",""); //"(%s+%d)",
2305 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2308 if (options.useXstack) {
2310 pic14_emitcode("mov","_spx,%s",r->name);
2311 freeAsmop(NULL,aop,ic,TRUE);
2317 /*-----------------------------------------------------------------*/
2318 /* saverbank - saves an entire register bank on the stack */
2319 /*-----------------------------------------------------------------*/
2320 static void saverbank (int bank, iCode *ic, bool pushPsw)
2322 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2329 if (options.useXstack) {
2332 r = getFreePtr(ic,&aop,FALSE);
2333 pic14_emitcode("mov","%s,_spx",r->name);
2337 for (i = 0 ; i < pic14_nRegs ;i++) {
2338 if (options.useXstack) {
2339 pic14_emitcode("inc","%s",r->name);
2340 //pic14_emitcode("mov","a,(%s+%d)",
2341 // regspic14[i].base,8*bank+regspic14[i].offset);
2342 pic14_emitcode("movx","@%s,a",r->name);
2344 pic14_emitcode("push","");// "(%s+%d)",
2345 //regspic14[i].base,8*bank+regspic14[i].offset);
2349 if (options.useXstack) {
2350 pic14_emitcode("mov","a,psw");
2351 pic14_emitcode("movx","@%s,a",r->name);
2352 pic14_emitcode("inc","%s",r->name);
2353 pic14_emitcode("mov","_spx,%s",r->name);
2354 freeAsmop (NULL,aop,ic,TRUE);
2357 pic14_emitcode("push","psw");
2359 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2365 /*-----------------------------------------------------------------*/
2366 /* genCall - generates a call statement */
2367 /*-----------------------------------------------------------------*/
2368 static void genCall (iCode *ic)
2372 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2374 /* if caller saves & we have not saved then */
2378 /* if we are calling a function that is not using
2379 the same register bank then we need to save the
2380 destination registers on the stack */
2381 dtype = operandType(IC_LEFT(ic));
2382 if (currFunc && dtype &&
2383 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2384 IFFUNC_ISISR(currFunc->type) &&
2387 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2389 /* if send set is not empty the assign */
2392 /* For the Pic port, there is no data stack.
2393 * So parameters passed to functions are stored
2394 * in registers. (The pCode optimizer will get
2395 * rid of most of these :).
2397 int psuedoStkPtr=-1;
2398 int firstTimeThruLoop = 1;
2400 _G.sendSet = reverseSet(_G.sendSet);
2402 /* First figure how many parameters are getting passed */
2403 for (sic = setFirstItem(_G.sendSet) ; sic ;
2404 sic = setNextItem(_G.sendSet)) {
2406 aopOp(IC_LEFT(sic),sic,FALSE);
2407 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2408 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2411 for (sic = setFirstItem(_G.sendSet) ; sic ;
2412 sic = setNextItem(_G.sendSet)) {
2413 int size, offset = 0;
2415 aopOp(IC_LEFT(sic),sic,FALSE);
2416 size = AOP_SIZE(IC_LEFT(sic));
2419 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2420 AopType(AOP_TYPE(IC_LEFT(sic))));
2422 if(!firstTimeThruLoop) {
2423 /* If this is not the first time we've been through the loop
2424 * then we need to save the parameter in a temporary
2425 * register. The last byte of the last parameter is
2427 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2430 firstTimeThruLoop=0;
2432 //if (strcmp(l,fReturn[offset])) {
2433 mov2w (AOP(IC_LEFT(sic)), offset);
2435 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2436 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2437 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2439 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2444 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2449 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2450 OP_SYMBOL(IC_LEFT(ic))->rname :
2451 OP_SYMBOL(IC_LEFT(ic))->name));
2454 /* if we need assign a result value */
2455 if ((IS_ITEMP(IC_RESULT(ic)) &&
2456 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2457 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2458 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2461 aopOp(IC_RESULT(ic),ic,FALSE);
2464 assignResultValue(IC_RESULT(ic));
2466 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2467 AopType(AOP_TYPE(IC_RESULT(ic))));
2469 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2472 /* adjust the stack for parameters if
2474 if (ic->parmBytes) {
2476 if (ic->parmBytes > 3) {
2477 pic14_emitcode("mov","a,%s",spname);
2478 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2479 pic14_emitcode("mov","%s,a",spname);
2481 for ( i = 0 ; i < ic->parmBytes ;i++)
2482 pic14_emitcode("dec","%s",spname);
2486 /* if register bank was saved then pop them */
2488 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2490 /* if we hade saved some registers then unsave them */
2491 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2492 unsaveRegisters (ic);
2497 /*-----------------------------------------------------------------*/
2498 /* genPcall - generates a call by pointer statement */
2499 /*-----------------------------------------------------------------*/
2500 static void genPcall (iCode *ic)
2503 symbol *albl = newiTempLabel(NULL);
2504 symbol *blbl = newiTempLabel(NULL);
2508 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2509 /* if caller saves & we have not saved then */
2513 /* if we are calling a function that is not using
2514 the same register bank then we need to save the
2515 destination registers on the stack */
2516 dtype = operandType(IC_LEFT(ic));
2517 if (currFunc && dtype &&
2518 IFFUNC_ISISR(currFunc->type) &&
2519 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2520 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2523 aopOp(left,ic,FALSE);
2524 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2526 pushSide(IC_LEFT(ic), FPTRSIZE);
2528 /* if send set is not empty, assign parameters */
2531 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2532 /* no way to pass args - W always gets used to make the call */
2534 /* first idea - factor out a common helper function and call it.
2535 But don't know how to get it generated only once in its own block
2537 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2540 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2541 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2542 buffer = Safe_calloc(1,strlen(rname)+16);
2543 sprintf(buffer, "%s_goto_helper", rname);
2544 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2548 emitpcode(POC_CALL,popGetLabel(albl->key));
2549 emitpcode(POC_GOTO,popGetLabel(blbl->key));
2550 emitpLabel(albl->key);
2552 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2554 emitpcode(poc,popGet(AOP(left),1));
2555 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2556 emitpcode(poc,popGet(AOP(left),0));
2557 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2559 emitpLabel(blbl->key);
2561 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2563 /* if we need to assign a result value */
2564 if ((IS_ITEMP(IC_RESULT(ic)) &&
2565 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2566 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2567 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2570 aopOp(IC_RESULT(ic),ic,FALSE);
2573 assignResultValue(IC_RESULT(ic));
2575 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2578 /* if register bank was saved then unsave them */
2579 if (currFunc && dtype &&
2580 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2581 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2583 /* if we hade saved some registers then
2586 unsaveRegisters (ic);
2590 /*-----------------------------------------------------------------*/
2591 /* resultRemat - result is rematerializable */
2592 /*-----------------------------------------------------------------*/
2593 static int resultRemat (iCode *ic)
2595 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2596 if (SKIP_IC(ic) || ic->op == IFX)
2599 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2600 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2601 if (sym->remat && !POINTER_SET(ic))
2608 #if defined(__BORLANDC__) || defined(_MSC_VER)
2609 #define STRCASECMP stricmp
2611 #define STRCASECMP strcasecmp
2615 /*-----------------------------------------------------------------*/
2616 /* inExcludeList - return 1 if the string is in exclude Reg list */
2617 /*-----------------------------------------------------------------*/
2618 static bool inExcludeList(char *s)
2620 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2623 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2624 if (options.excludeRegs[i] &&
2625 STRCASECMP(options.excludeRegs[i],"none") == 0)
2628 for ( i = 0 ; options.excludeRegs[i]; i++) {
2629 if (options.excludeRegs[i] &&
2630 STRCASECMP(s,options.excludeRegs[i]) == 0)
2637 /*-----------------------------------------------------------------*/
2638 /* genFunction - generated code for function entry */
2639 /*-----------------------------------------------------------------*/
2640 static void genFunction (iCode *ic)
2645 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2647 labelOffset += (max_key+4);
2651 /* create the function header */
2652 pic14_emitcode(";","-----------------------------------------");
2653 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2654 pic14_emitcode(";","-----------------------------------------");
2656 pic14_emitcode("","%s:",sym->rname);
2657 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2659 ftype = operandType(IC_LEFT(ic));
2661 /* if critical function then turn interrupts off */
2662 if (IFFUNC_ISCRITICAL(ftype))
2663 pic14_emitcode("clr","ea");
2665 /* here we need to generate the equates for the
2666 register bank if required */
2668 if (FUNC_REGBANK(ftype) != rbank) {
2671 rbank = FUNC_REGBANK(ftype);
2672 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2673 if (strcmp(regspic14[i].base,"0") == 0)
2674 pic14_emitcode("","%s = 0x%02x",
2676 8*rbank+regspic14[i].offset);
2678 pic14_emitcode ("","%s = %s + 0x%02x",
2681 8*rbank+regspic14[i].offset);
2686 /* if this is an interrupt service routine then
2687 save acc, b, dpl, dph */
2688 if (IFFUNC_ISISR(sym->type)) {
2689 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2690 emitpcodeNULLop(POC_NOP);
2691 emitpcodeNULLop(POC_NOP);
2692 emitpcodeNULLop(POC_NOP);
2693 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2694 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2695 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2696 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2698 pBlockConvert2ISR(pb);
2700 if (!inExcludeList("acc"))
2701 pic14_emitcode ("push","acc");
2702 if (!inExcludeList("b"))
2703 pic14_emitcode ("push","b");
2704 if (!inExcludeList("dpl"))
2705 pic14_emitcode ("push","dpl");
2706 if (!inExcludeList("dph"))
2707 pic14_emitcode ("push","dph");
2708 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2710 pic14_emitcode ("push", "dpx");
2711 /* Make sure we're using standard DPTR */
2712 pic14_emitcode ("push", "dps");
2713 pic14_emitcode ("mov", "dps, #0x00");
2714 if (options.stack10bit)
2716 /* This ISR could conceivably use DPTR2. Better save it. */
2717 pic14_emitcode ("push", "dpl1");
2718 pic14_emitcode ("push", "dph1");
2719 pic14_emitcode ("push", "dpx1");
2722 /* if this isr has no bank i.e. is going to
2723 run with bank 0 , then we need to save more
2725 if (!FUNC_REGBANK(sym->type)) {
2727 /* if this function does not call any other
2728 function then we can be economical and
2729 save only those registers that are used */
2730 if (! IFFUNC_HASFCALL(sym->type)) {
2733 /* if any registers used */
2734 if (sym->regsUsed) {
2735 /* save the registers used */
2736 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2737 if (bitVectBitValue(sym->regsUsed,i) ||
2738 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2739 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2744 /* this function has a function call cannot
2745 determines register usage so we will have the
2747 saverbank(0,ic,FALSE);
2752 /* if callee-save to be used for this function
2753 then save the registers being used in this function */
2754 if (IFFUNC_CALLEESAVES(sym->type)) {
2757 /* if any registers used */
2758 if (sym->regsUsed) {
2759 /* save the registers used */
2760 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2761 if (bitVectBitValue(sym->regsUsed,i) ||
2762 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2763 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2771 /* set the register bank to the desired value */
2772 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2773 pic14_emitcode("push","psw");
2774 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2777 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2779 if (options.useXstack) {
2780 pic14_emitcode("mov","r0,%s",spname);
2781 pic14_emitcode("mov","a,_bp");
2782 pic14_emitcode("movx","@r0,a");
2783 pic14_emitcode("inc","%s",spname);
2787 /* set up the stack */
2788 pic14_emitcode ("push","_bp"); /* save the callers stack */
2790 pic14_emitcode ("mov","_bp,%s",spname);
2793 /* adjust the stack for the function */
2798 werror(W_STACK_OVERFLOW,sym->name);
2800 if (i > 3 && sym->recvSize < 4) {
2802 pic14_emitcode ("mov","a,sp");
2803 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2804 pic14_emitcode ("mov","sp,a");
2809 pic14_emitcode("inc","sp");
2814 pic14_emitcode ("mov","a,_spx");
2815 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2816 pic14_emitcode ("mov","_spx,a");
2821 /*-----------------------------------------------------------------*/
2822 /* genEndFunction - generates epilogue for functions */
2823 /*-----------------------------------------------------------------*/
2824 static void genEndFunction (iCode *ic)
2826 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2828 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2830 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2832 pic14_emitcode ("mov","%s,_bp",spname);
2835 /* if use external stack but some variables were
2836 added to the local stack then decrement the
2838 if (options.useXstack && sym->stack) {
2839 pic14_emitcode("mov","a,sp");
2840 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2841 pic14_emitcode("mov","sp,a");
2845 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2846 if (options.useXstack) {
2847 pic14_emitcode("mov","r0,%s",spname);
2848 pic14_emitcode("movx","a,@r0");
2849 pic14_emitcode("mov","_bp,a");
2850 pic14_emitcode("dec","%s",spname);
2854 pic14_emitcode ("pop","_bp");
2858 /* restore the register bank */
2859 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2860 pic14_emitcode ("pop","psw");
2862 if (IFFUNC_ISISR(sym->type)) {
2864 /* now we need to restore the registers */
2865 /* if this isr has no bank i.e. is going to
2866 run with bank 0 , then we need to save more
2868 if (!FUNC_REGBANK(sym->type)) {
2870 /* if this function does not call any other
2871 function then we can be economical and
2872 save only those registers that are used */
2873 if (! IFFUNC_HASFCALL(sym->type)) {
2876 /* if any registers used */
2877 if (sym->regsUsed) {
2878 /* save the registers used */
2879 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2880 if (bitVectBitValue(sym->regsUsed,i) ||
2881 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2882 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2887 /* this function has a function call cannot
2888 determines register usage so we will have the
2890 unsaverbank(0,ic,FALSE);
2894 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2896 if (options.stack10bit)
2898 pic14_emitcode ("pop", "dpx1");
2899 pic14_emitcode ("pop", "dph1");
2900 pic14_emitcode ("pop", "dpl1");
2902 pic14_emitcode ("pop", "dps");
2903 pic14_emitcode ("pop", "dpx");
2905 if (!inExcludeList("dph"))
2906 pic14_emitcode ("pop","dph");
2907 if (!inExcludeList("dpl"))
2908 pic14_emitcode ("pop","dpl");
2909 if (!inExcludeList("b"))
2910 pic14_emitcode ("pop","b");
2911 if (!inExcludeList("acc"))
2912 pic14_emitcode ("pop","acc");
2914 if (IFFUNC_ISCRITICAL(sym->type))
2915 pic14_emitcode("setb","ea");
2918 /* if debug then send end of function */
2919 /* if (options.debug && currFunc) { */
2922 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2923 FileBaseName(ic->filename),currFunc->lastLine,
2924 ic->level,ic->block);
2925 if (IS_STATIC(currFunc->etype))
2926 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2928 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2932 pic14_emitcode ("reti","");
2934 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2935 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2936 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2937 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2938 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2939 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2941 emitpcodeNULLop(POC_RETFIE);
2945 if (IFFUNC_ISCRITICAL(sym->type))
2946 pic14_emitcode("setb","ea");
2948 if (IFFUNC_CALLEESAVES(sym->type)) {
2951 /* if any registers used */
2952 if (sym->regsUsed) {
2953 /* save the registers used */
2954 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2955 if (bitVectBitValue(sym->regsUsed,i) ||
2956 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2957 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2963 /* if debug then send end of function */
2966 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2967 FileBaseName(ic->filename),currFunc->lastLine,
2968 ic->level,ic->block);
2969 if (IS_STATIC(currFunc->etype))
2970 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2972 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2976 pic14_emitcode ("return","");
2977 emitpcodeNULLop(POC_RETURN);
2979 /* Mark the end of a function */
2980 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2985 /*-----------------------------------------------------------------*/
2986 /* genRet - generate code for return statement */
2987 /*-----------------------------------------------------------------*/
2988 static void genRet (iCode *ic)
2990 int size,offset = 0 , pushed = 0;
2992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2993 /* if we have no return value then
2994 just generate the "ret" */
2998 /* we have something to return then
2999 move the return value into place */
3000 aopOp(IC_LEFT(ic),ic,FALSE);
3001 size = AOP_SIZE(IC_LEFT(ic));
3005 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3007 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3009 pic14_emitcode("push","%s",l);
3012 l = aopGet(AOP(IC_LEFT(ic)),offset,
3014 if (strcmp(fReturn[offset],l)) {
3015 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
3016 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3017 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3018 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3019 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3021 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3024 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3034 if (strcmp(fReturn[pushed],"a"))
3035 pic14_emitcode("pop",fReturn[pushed]);
3037 pic14_emitcode("pop","acc");
3040 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3043 /* generate a jump to the return label
3044 if the next is not the return statement */
3045 if (!(ic->next && ic->next->op == LABEL &&
3046 IC_LABEL(ic->next) == returnLabel)) {
3048 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3049 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3054 /*-----------------------------------------------------------------*/
3055 /* genLabel - generates a label */
3056 /*-----------------------------------------------------------------*/
3057 static void genLabel (iCode *ic)
3059 /* special case never generate */
3060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3061 if (IC_LABEL(ic) == entryLabel)
3064 emitpLabel(IC_LABEL(ic)->key);
3065 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3068 /*-----------------------------------------------------------------*/
3069 /* genGoto - generates a goto */
3070 /*-----------------------------------------------------------------*/
3072 static void genGoto (iCode *ic)
3074 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3075 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3079 /*-----------------------------------------------------------------*/
3080 /* genMultbits :- multiplication of bits */
3081 /*-----------------------------------------------------------------*/
3082 static void genMultbits (operand *left,
3086 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3088 if(!pic14_sameRegs(AOP(result),AOP(right)))
3089 emitpcode(POC_BSF, popGet(AOP(result),0));
3091 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3092 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3093 emitpcode(POC_BCF, popGet(AOP(result),0));
3098 /*-----------------------------------------------------------------*/
3099 /* genMultOneByte : 8 bit multiplication & division */
3100 /*-----------------------------------------------------------------*/
3101 static void genMultOneByte (operand *left,
3105 sym_link *opetype = operandType(result);
3110 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3111 DEBUGpic14_AopType(__LINE__,left,right,result);
3112 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3114 /* (if two literals, the value is computed before) */
3115 /* if one literal, literal on the right */
3116 if (AOP_TYPE(left) == AOP_LIT){
3122 size = AOP_SIZE(result);
3125 if (AOP_TYPE(right) == AOP_LIT){
3126 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3127 aopGet(AOP(right),0,FALSE,FALSE),
3128 aopGet(AOP(left),0,FALSE,FALSE),
3129 aopGet(AOP(result),0,FALSE,FALSE));
3130 pic14_emitcode("call","genMultLit");
3132 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3133 aopGet(AOP(right),0,FALSE,FALSE),
3134 aopGet(AOP(left),0,FALSE,FALSE),
3135 aopGet(AOP(result),0,FALSE,FALSE));
3136 pic14_emitcode("call","genMult8X8_8");
3139 genMult8X8_8 (left, right,result);
3142 /* signed or unsigned */
3143 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3144 //l = aopGet(AOP(left),0,FALSE,FALSE);
3146 //pic14_emitcode("mul","ab");
3147 /* if result size = 1, mul signed = mul unsigned */
3148 //aopPut(AOP(result),"a",0);
3150 } else { // (size > 1)
3152 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3153 aopGet(AOP(right),0,FALSE,FALSE),
3154 aopGet(AOP(left),0,FALSE,FALSE),
3155 aopGet(AOP(result),0,FALSE,FALSE));
3157 if (SPEC_USIGN(opetype)){
3158 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3159 genUMult8X8_16 (left, right, result, NULL);
3162 /* for filling the MSBs */
3163 emitpcode(POC_CLRF, popGet(AOP(result),2));
3164 emitpcode(POC_CLRF, popGet(AOP(result),3));
3168 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3170 pic14_emitcode("mov","a,b");
3172 /* adjust the MSB if left or right neg */
3174 /* if one literal */
3175 if (AOP_TYPE(right) == AOP_LIT){
3176 pic14_emitcode("multiply ","right is a lit");
3177 /* AND literal negative */
3178 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3179 /* adjust MSB (c==0 after mul) */
3180 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3184 genSMult8X8_16 (left, right, result, NULL);
3188 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3190 pic14_emitcode("rlc","a");
3191 pic14_emitcode("subb","a,acc");
3199 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3200 //aopPut(AOP(result),"a",offset++);
3204 /*-----------------------------------------------------------------*/
3205 /* genMult - generates code for multiplication */
3206 /*-----------------------------------------------------------------*/
3207 static void genMult (iCode *ic)
3209 operand *left = IC_LEFT(ic);
3210 operand *right = IC_RIGHT(ic);
3211 operand *result= IC_RESULT(ic);
3213 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3214 /* assign the amsops */
3215 aopOp (left,ic,FALSE);
3216 aopOp (right,ic,FALSE);
3217 aopOp (result,ic,TRUE);
3219 DEBUGpic14_AopType(__LINE__,left,right,result);
3221 /* special cases first */
3223 if (AOP_TYPE(left) == AOP_CRY &&
3224 AOP_TYPE(right)== AOP_CRY) {
3225 genMultbits(left,right,result);
3229 /* if both are of size == 1 */
3230 if (AOP_SIZE(left) == 1 &&
3231 AOP_SIZE(right) == 1 ) {
3232 genMultOneByte(left,right,result);
3236 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3238 /* should have been converted to function call */
3242 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3243 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3244 freeAsmop(result,NULL,ic,TRUE);
3247 /*-----------------------------------------------------------------*/
3248 /* genDivbits :- division of bits */
3249 /*-----------------------------------------------------------------*/
3250 static void genDivbits (operand *left,
3257 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3258 /* the result must be bit */
3259 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3260 l = aopGet(AOP(left),0,FALSE,FALSE);
3264 pic14_emitcode("div","ab");
3265 pic14_emitcode("rrc","a");
3266 aopPut(AOP(result),"c",0);
3269 /*-----------------------------------------------------------------*/
3270 /* genDivOneByte : 8 bit division */
3271 /*-----------------------------------------------------------------*/
3272 static void genDivOneByte (operand *left,
3276 sym_link *opetype = operandType(result);
3281 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3282 size = AOP_SIZE(result) - 1;
3284 /* signed or unsigned */
3285 if (SPEC_USIGN(opetype)) {
3286 /* unsigned is easy */
3287 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3288 l = aopGet(AOP(left),0,FALSE,FALSE);
3290 pic14_emitcode("div","ab");
3291 aopPut(AOP(result),"a",0);
3293 aopPut(AOP(result),zero,offset++);
3297 /* signed is a little bit more difficult */
3299 /* save the signs of the operands */
3300 l = aopGet(AOP(left),0,FALSE,FALSE);
3302 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3303 pic14_emitcode("push","acc"); /* save it on the stack */
3305 /* now sign adjust for both left & right */
3306 l = aopGet(AOP(right),0,FALSE,FALSE);
3308 lbl = newiTempLabel(NULL);
3309 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3310 pic14_emitcode("cpl","a");
3311 pic14_emitcode("inc","a");
3312 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3313 pic14_emitcode("mov","b,a");
3315 /* sign adjust left side */
3316 l = aopGet(AOP(left),0,FALSE,FALSE);
3319 lbl = newiTempLabel(NULL);
3320 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3321 pic14_emitcode("cpl","a");
3322 pic14_emitcode("inc","a");
3323 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3325 /* now the division */
3326 pic14_emitcode("div","ab");
3327 /* we are interested in the lower order
3329 pic14_emitcode("mov","b,a");
3330 lbl = newiTempLabel(NULL);
3331 pic14_emitcode("pop","acc");
3332 /* if there was an over flow we don't
3333 adjust the sign of the result */
3334 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3335 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3337 pic14_emitcode("clr","a");
3338 pic14_emitcode("subb","a,b");
3339 pic14_emitcode("mov","b,a");
3340 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3342 /* now we are done */
3343 aopPut(AOP(result),"b",0);
3345 pic14_emitcode("mov","c,b.7");
3346 pic14_emitcode("subb","a,acc");
3349 aopPut(AOP(result),"a",offset++);
3353 /*-----------------------------------------------------------------*/
3354 /* genDiv - generates code for division */
3355 /*-----------------------------------------------------------------*/
3356 static void genDiv (iCode *ic)
3358 operand *left = IC_LEFT(ic);
3359 operand *right = IC_RIGHT(ic);
3360 operand *result= IC_RESULT(ic);
3362 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3363 /* assign the amsops */
3364 aopOp (left,ic,FALSE);
3365 aopOp (right,ic,FALSE);
3366 aopOp (result,ic,TRUE);
3368 /* special cases first */
3370 if (AOP_TYPE(left) == AOP_CRY &&
3371 AOP_TYPE(right)== AOP_CRY) {
3372 genDivbits(left,right,result);
3376 /* if both are of size == 1 */
3377 if (AOP_SIZE(left) == 1 &&
3378 AOP_SIZE(right) == 1 ) {
3379 genDivOneByte(left,right,result);
3383 /* should have been converted to function call */
3386 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3387 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3388 freeAsmop(result,NULL,ic,TRUE);
3391 /*-----------------------------------------------------------------*/
3392 /* genModbits :- modulus of bits */
3393 /*-----------------------------------------------------------------*/
3394 static void genModbits (operand *left,
3401 /* the result must be bit */
3402 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3403 l = aopGet(AOP(left),0,FALSE,FALSE);
3407 pic14_emitcode("div","ab");
3408 pic14_emitcode("mov","a,b");
3409 pic14_emitcode("rrc","a");
3410 aopPut(AOP(result),"c",0);
3413 /*-----------------------------------------------------------------*/
3414 /* genModOneByte : 8 bit modulus */
3415 /*-----------------------------------------------------------------*/
3416 static void genModOneByte (operand *left,
3420 sym_link *opetype = operandType(result);
3424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3425 /* signed or unsigned */
3426 if (SPEC_USIGN(opetype)) {
3427 /* unsigned is easy */
3428 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3429 l = aopGet(AOP(left),0,FALSE,FALSE);
3431 pic14_emitcode("div","ab");
3432 aopPut(AOP(result),"b",0);
3436 /* signed is a little bit more difficult */
3438 /* save the signs of the operands */
3439 l = aopGet(AOP(left),0,FALSE,FALSE);
3442 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3443 pic14_emitcode("push","acc"); /* save it on the stack */
3445 /* now sign adjust for both left & right */
3446 l = aopGet(AOP(right),0,FALSE,FALSE);
3449 lbl = newiTempLabel(NULL);
3450 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3451 pic14_emitcode("cpl","a");
3452 pic14_emitcode("inc","a");
3453 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3454 pic14_emitcode("mov","b,a");
3456 /* sign adjust left side */
3457 l = aopGet(AOP(left),0,FALSE,FALSE);
3460 lbl = newiTempLabel(NULL);
3461 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3462 pic14_emitcode("cpl","a");
3463 pic14_emitcode("inc","a");
3464 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3466 /* now the multiplication */
3467 pic14_emitcode("div","ab");
3468 /* we are interested in the lower order
3470 lbl = newiTempLabel(NULL);
3471 pic14_emitcode("pop","acc");
3472 /* if there was an over flow we don't
3473 adjust the sign of the result */
3474 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3475 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3477 pic14_emitcode("clr","a");
3478 pic14_emitcode("subb","a,b");
3479 pic14_emitcode("mov","b,a");
3480 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3482 /* now we are done */
3483 aopPut(AOP(result),"b",0);
3487 /*-----------------------------------------------------------------*/
3488 /* genMod - generates code for division */
3489 /*-----------------------------------------------------------------*/
3490 static void genMod (iCode *ic)
3492 operand *left = IC_LEFT(ic);
3493 operand *right = IC_RIGHT(ic);
3494 operand *result= IC_RESULT(ic);
3496 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3497 /* assign the amsops */
3498 aopOp (left,ic,FALSE);
3499 aopOp (right,ic,FALSE);
3500 aopOp (result,ic,TRUE);
3502 /* special cases first */
3504 if (AOP_TYPE(left) == AOP_CRY &&
3505 AOP_TYPE(right)== AOP_CRY) {
3506 genModbits(left,right,result);
3510 /* if both are of size == 1 */
3511 if (AOP_SIZE(left) == 1 &&
3512 AOP_SIZE(right) == 1 ) {
3513 genModOneByte(left,right,result);
3517 /* should have been converted to function call */
3521 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3522 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3523 freeAsmop(result,NULL,ic,TRUE);
3526 /*-----------------------------------------------------------------*/
3527 /* genIfxJump :- will create a jump depending on the ifx */
3528 /*-----------------------------------------------------------------*/
3530 note: May need to add parameter to indicate when a variable is in bit space.
3532 static void genIfxJump (iCode *ic, char *jval)
3535 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3536 /* if true label then we jump if condition
3538 if ( IC_TRUE(ic) ) {
3540 if(strcmp(jval,"a") == 0)
3542 else if (strcmp(jval,"c") == 0)
3545 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3546 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3549 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3550 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3554 /* false label is present */
3555 if(strcmp(jval,"a") == 0)
3557 else if (strcmp(jval,"c") == 0)
3560 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3561 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3564 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3565 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3570 /* mark the icode as generated */
3574 /*-----------------------------------------------------------------*/
3576 /*-----------------------------------------------------------------*/
3577 static void genSkip(iCode *ifx,int status_bit)
3582 if ( IC_TRUE(ifx) ) {
3583 switch(status_bit) {
3598 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3599 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3603 switch(status_bit) {
3617 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3618 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3624 /*-----------------------------------------------------------------*/
3626 /*-----------------------------------------------------------------*/
3627 static void genSkipc(resolvedIfx *rifx)
3637 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3638 rifx->generated = 1;
3641 /*-----------------------------------------------------------------*/
3643 /*-----------------------------------------------------------------*/
3644 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3649 if( (rifx->condition ^ invert_condition) & 1)
3654 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3655 rifx->generated = 1;
3658 /*-----------------------------------------------------------------*/
3660 /*-----------------------------------------------------------------*/
3661 static void genSkipz(iCode *ifx, int condition)
3672 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3674 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3677 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3679 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3682 /*-----------------------------------------------------------------*/
3684 /*-----------------------------------------------------------------*/
3685 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3691 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3693 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3696 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3697 rifx->generated = 1;
3701 /*-----------------------------------------------------------------*/
3702 /* genChkZeroes :- greater or less than comparison */
3703 /* For each byte in a literal that is zero, inclusive or the */
3704 /* the corresponding byte in the operand with W */
3705 /* returns true if any of the bytes are zero */
3706 /*-----------------------------------------------------------------*/
3707 static int genChkZeroes(operand *op, int lit, int size)
3714 i = (lit >> (size*8)) & 0xff;
3718 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3720 emitpcode(POC_IORFW, popGet(AOP(op),size));
3729 /*-----------------------------------------------------------------*/
3730 /* genCmp :- greater or less than comparison */
3731 /*-----------------------------------------------------------------*/
3732 static void genCmp (operand *left,operand *right,
3733 operand *result, iCode *ifx, int sign)
3735 int size; //, offset = 0 ;
3736 unsigned long lit = 0L,i = 0;
3737 resolvedIfx rFalseIfx;
3738 // resolvedIfx rTrueIfx;
3740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3743 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3744 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3748 resolveIfx(&rFalseIfx,ifx);
3749 truelbl = newiTempLabel(NULL);
3750 size = max(AOP_SIZE(left),AOP_SIZE(right));
3752 DEBUGpic14_AopType(__LINE__,left,right,result);
3756 /* if literal is on the right then swap with left */
3757 if ((AOP_TYPE(right) == AOP_LIT)) {
3758 operand *tmp = right ;
3759 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3760 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3763 lit = (lit - 1) & mask;
3766 rFalseIfx.condition ^= 1;
3769 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3770 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3774 //if(IC_TRUE(ifx) == NULL)
3775 /* if left & right are bit variables */
3776 if (AOP_TYPE(left) == AOP_CRY &&
3777 AOP_TYPE(right) == AOP_CRY ) {
3778 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3779 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3781 /* subtract right from left if at the
3782 end the carry flag is set then we know that
3783 left is greater than right */
3787 symbol *lbl = newiTempLabel(NULL);
3790 if(AOP_TYPE(right) == AOP_LIT) {
3792 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3794 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3801 genSkipCond(&rFalseIfx,left,size-1,7);
3803 /* no need to compare to 0...*/
3804 /* NOTE: this is a de-generate compare that most certainly
3805 * creates some dead code. */
3806 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3808 if(ifx) ifx->generated = 1;
3815 //i = (lit >> (size*8)) & 0xff;
3816 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3818 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3820 i = ((0-lit) & 0xff);
3823 /* lit is 0x7f, all signed chars are less than
3824 * this except for 0x7f itself */
3825 emitpcode(POC_XORLW, popGetLit(0x7f));
3826 genSkipz2(&rFalseIfx,0);
3828 emitpcode(POC_ADDLW, popGetLit(0x80));
3829 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3830 genSkipc(&rFalseIfx);
3835 genSkipz2(&rFalseIfx,1);
3837 emitpcode(POC_ADDLW, popGetLit(i));
3838 genSkipc(&rFalseIfx);
3842 if(ifx) ifx->generated = 1;
3846 /* chars are out of the way. now do ints and longs */
3849 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3856 genSkipCond(&rFalseIfx,left,size,7);
3857 if(ifx) ifx->generated = 1;
3862 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3864 //rFalseIfx.condition ^= 1;
3865 //genSkipCond(&rFalseIfx,left,size,7);
3866 //rFalseIfx.condition ^= 1;
3868 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3869 if(rFalseIfx.condition)
3870 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3872 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3874 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3875 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3876 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3879 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3881 if(rFalseIfx.condition) {
3883 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3889 genSkipc(&rFalseIfx);
3890 emitpLabel(truelbl->key);
3891 if(ifx) ifx->generated = 1;
3898 if( (lit & 0xff) == 0) {
3899 /* lower byte is zero */
3900 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3901 i = ((lit >> 8) & 0xff) ^0x80;
3902 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3903 emitpcode(POC_ADDLW, popGetLit( 0x80));
3904 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3905 genSkipc(&rFalseIfx);
3908 if(ifx) ifx->generated = 1;
3913 /* Special cases for signed longs */
3914 if( (lit & 0xffffff) == 0) {
3915 /* lower byte is zero */
3916 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3917 i = ((lit >> 8*3) & 0xff) ^0x80;
3918 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3919 emitpcode(POC_ADDLW, popGetLit( 0x80));
3920 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3921 genSkipc(&rFalseIfx);
3924 if(ifx) ifx->generated = 1;
3932 if(lit & (0x80 << (size*8))) {
3933 /* lit is negative */
3934 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3936 //genSkipCond(&rFalseIfx,left,size,7);
3938 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3940 if(rFalseIfx.condition)
3941 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3943 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3947 /* lit is positive */
3948 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3949 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3950 if(rFalseIfx.condition)
3951 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3953 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3958 This works, but is only good for ints.
3959 It also requires a "known zero" register.
3960 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3961 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3962 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3963 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3964 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3965 genSkipc(&rFalseIfx);
3967 emitpLabel(truelbl->key);
3968 if(ifx) ifx->generated = 1;
3972 /* There are no more special cases, so perform a general compare */
3974 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3975 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3979 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3981 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3983 //rFalseIfx.condition ^= 1;
3984 genSkipc(&rFalseIfx);
3986 emitpLabel(truelbl->key);
3988 if(ifx) ifx->generated = 1;
3995 /* sign is out of the way. So now do an unsigned compare */
3996 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3999 /* General case - compare to an unsigned literal on the right.*/
4001 i = (lit >> (size*8)) & 0xff;
4002 emitpcode(POC_MOVLW, popGetLit(i));
4003 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4005 i = (lit >> (size*8)) & 0xff;
4008 emitpcode(POC_MOVLW, popGetLit(i));
4010 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4012 /* this byte of the lit is zero,
4013 *if it's not the last then OR in the variable */
4015 emitpcode(POC_IORFW, popGet(AOP(left),size));
4020 emitpLabel(lbl->key);
4021 //if(emitFinalCheck)
4022 genSkipc(&rFalseIfx);
4024 emitpLabel(truelbl->key);
4026 if(ifx) ifx->generated = 1;
4033 if(AOP_TYPE(left) == AOP_LIT) {
4034 //symbol *lbl = newiTempLabel(NULL);
4036 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4039 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4042 if((lit == 0) && (sign == 0)){
4045 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4047 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4049 genSkipz2(&rFalseIfx,0);
4050 if(ifx) ifx->generated = 1;
4057 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4058 /* degenerate compare can never be true */
4059 if(rFalseIfx.condition == 0)
4060 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4062 if(ifx) ifx->generated = 1;
4067 /* signed comparisons to a literal byte */
4069 int lp1 = (lit+1) & 0xff;
4071 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4074 rFalseIfx.condition ^= 1;
4075 genSkipCond(&rFalseIfx,right,0,7);
4078 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4079 emitpcode(POC_XORLW, popGetLit(0x7f));
4080 genSkipz2(&rFalseIfx,1);
4083 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4084 emitpcode(POC_ADDLW, popGetLit(0x80));
4085 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4086 rFalseIfx.condition ^= 1;
4087 genSkipc(&rFalseIfx);
4090 if(ifx) ifx->generated = 1;
4092 /* unsigned comparisons to a literal byte */
4094 switch(lit & 0xff ) {
4096 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4097 genSkipz2(&rFalseIfx,0);
4098 if(ifx) ifx->generated = 1;
4101 rFalseIfx.condition ^= 1;
4102 genSkipCond(&rFalseIfx,right,0,7);
4103 if(ifx) ifx->generated = 1;
4107 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4108 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4109 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4110 rFalseIfx.condition ^= 1;
4111 if (AOP_TYPE(result) == AOP_CRY) {
4112 genSkipc(&rFalseIfx);
4113 if(ifx) ifx->generated = 1;
4115 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4116 emitpcode(POC_CLRF, popGet(AOP(result),0));
4117 emitpcode(POC_RLF, popGet(AOP(result),0));
4118 emitpcode(POC_MOVLW, popGetLit(0x01));
4119 emitpcode(POC_XORWF, popGet(AOP(result),0));
4130 /* Size is greater than 1 */
4138 /* this means lit = 0xffffffff, or -1 */
4141 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4142 rFalseIfx.condition ^= 1;
4143 genSkipCond(&rFalseIfx,right,size,7);
4144 if(ifx) ifx->generated = 1;
4151 if(rFalseIfx.condition) {
4152 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4153 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4156 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4158 emitpcode(POC_IORFW, popGet(AOP(right),size));
4162 if(rFalseIfx.condition) {
4163 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4164 emitpLabel(truelbl->key);
4166 rFalseIfx.condition ^= 1;
4167 genSkipCond(&rFalseIfx,right,s,7);
4170 if(ifx) ifx->generated = 1;
4174 if((size == 1) && (0 == (lp1&0xff))) {
4175 /* lower byte of signed word is zero */
4176 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4177 i = ((lp1 >> 8) & 0xff) ^0x80;
4178 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4179 emitpcode(POC_ADDLW, popGetLit( 0x80));
4180 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4181 rFalseIfx.condition ^= 1;
4182 genSkipc(&rFalseIfx);
4185 if(ifx) ifx->generated = 1;
4189 if(lit & (0x80 << (size*8))) {
4190 /* Lit is less than zero */
4191 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4192 //rFalseIfx.condition ^= 1;
4193 //genSkipCond(&rFalseIfx,left,size,7);
4194 //rFalseIfx.condition ^= 1;
4195 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4196 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4198 if(rFalseIfx.condition)
4199 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4201 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4205 /* Lit is greater than or equal to zero */
4206 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4207 //rFalseIfx.condition ^= 1;
4208 //genSkipCond(&rFalseIfx,right,size,7);
4209 //rFalseIfx.condition ^= 1;
4211 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4212 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4214 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4215 if(rFalseIfx.condition)
4216 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4218 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4223 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4224 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4228 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4230 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4232 rFalseIfx.condition ^= 1;
4233 //rFalseIfx.condition = 1;
4234 genSkipc(&rFalseIfx);
4236 emitpLabel(truelbl->key);
4238 if(ifx) ifx->generated = 1;
4243 /* compare word or long to an unsigned literal on the right.*/
4248 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4251 break; /* handled above */
4254 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4256 emitpcode(POC_IORFW, popGet(AOP(right),size));
4257 genSkipz2(&rFalseIfx,0);
4261 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4263 emitpcode(POC_IORFW, popGet(AOP(right),size));
4266 if(rFalseIfx.condition)
4267 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4269 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4272 emitpcode(POC_MOVLW, popGetLit(lit+1));
4273 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4275 rFalseIfx.condition ^= 1;
4276 genSkipc(&rFalseIfx);
4279 emitpLabel(truelbl->key);
4281 if(ifx) ifx->generated = 1;
4287 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4288 i = (lit >> (size*8)) & 0xff;
4290 emitpcode(POC_MOVLW, popGetLit(i));
4291 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4294 i = (lit >> (size*8)) & 0xff;
4297 emitpcode(POC_MOVLW, popGetLit(i));
4299 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4301 /* this byte of the lit is zero,
4302 *if it's not the last then OR in the variable */
4304 emitpcode(POC_IORFW, popGet(AOP(right),size));
4309 emitpLabel(lbl->key);
4311 rFalseIfx.condition ^= 1;
4312 genSkipc(&rFalseIfx);
4316 emitpLabel(truelbl->key);
4317 if(ifx) ifx->generated = 1;
4321 /* Compare two variables */
4323 DEBUGpic14_emitcode(";sign","%d",sign);
4327 /* Sigh. thus sucks... */
4329 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4330 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4331 emitpcode(POC_MOVLW, popGetLit(0x80));
4332 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4333 emitpcode(POC_XORFW, popGet(AOP(right),size));
4334 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4336 /* Signed char comparison */
4337 /* Special thanks to Nikolai Golovchenko for this snippet */
4338 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4339 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4340 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4341 emitpcode(POC_XORFW, popGet(AOP(left),0));
4342 emitpcode(POC_XORFW, popGet(AOP(right),0));
4343 emitpcode(POC_ADDLW, popGetLit(0x80));
4345 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4346 genSkipc(&rFalseIfx);
4348 if(ifx) ifx->generated = 1;
4354 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4355 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4359 /* The rest of the bytes of a multi-byte compare */
4363 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4366 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4367 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4372 emitpLabel(lbl->key);
4374 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4375 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4376 (AOP_TYPE(result) == AOP_REG)) {
4377 emitpcode(POC_CLRF, popGet(AOP(result),0));
4378 emitpcode(POC_RLF, popGet(AOP(result),0));
4380 genSkipc(&rFalseIfx);
4382 //genSkipc(&rFalseIfx);
4383 if(ifx) ifx->generated = 1;
4390 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4391 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4392 pic14_outBitC(result);
4394 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4395 /* if the result is used in the next
4396 ifx conditional branch then generate
4397 code a little differently */
4399 genIfxJump (ifx,"c");
4401 pic14_outBitC(result);
4402 /* leave the result in acc */
4407 /*-----------------------------------------------------------------*/
4408 /* genCmpGt :- greater than comparison */
4409 /*-----------------------------------------------------------------*/
4410 static void genCmpGt (iCode *ic, iCode *ifx)
4412 operand *left, *right, *result;
4413 sym_link *letype , *retype;
4416 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4418 right= IC_RIGHT(ic);
4419 result = IC_RESULT(ic);
4421 letype = getSpec(operandType(left));
4422 retype =getSpec(operandType(right));
4423 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4424 /* assign the amsops */
4425 aopOp (left,ic,FALSE);
4426 aopOp (right,ic,FALSE);
4427 aopOp (result,ic,TRUE);
4429 genCmp(right, left, result, ifx, sign);
4431 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4432 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4433 freeAsmop(result,NULL,ic,TRUE);
4436 /*-----------------------------------------------------------------*/
4437 /* genCmpLt - less than comparisons */
4438 /*-----------------------------------------------------------------*/
4439 static void genCmpLt (iCode *ic, iCode *ifx)
4441 operand *left, *right, *result;
4442 sym_link *letype , *retype;
4445 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4447 right= IC_RIGHT(ic);
4448 result = IC_RESULT(ic);
4450 letype = getSpec(operandType(left));
4451 retype =getSpec(operandType(right));
4452 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4454 /* assign the amsops */
4455 aopOp (left,ic,FALSE);
4456 aopOp (right,ic,FALSE);
4457 aopOp (result,ic,TRUE);
4459 genCmp(left, right, result, ifx, sign);
4461 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4462 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4463 freeAsmop(result,NULL,ic,TRUE);
4466 /*-----------------------------------------------------------------*/
4467 /* genc16bit2lit - compare a 16 bit value to a literal */
4468 /*-----------------------------------------------------------------*/
4469 static void genc16bit2lit(operand *op, int lit, int offset)
4473 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4474 if( (lit&0xff) == 0)
4479 switch( BYTEofLONG(lit,i)) {
4481 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4484 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4487 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4490 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4491 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4496 switch( BYTEofLONG(lit,i)) {
4498 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4502 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4506 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4509 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4511 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4517 /*-----------------------------------------------------------------*/
4518 /* gencjneshort - compare and jump if not equal */
4519 /*-----------------------------------------------------------------*/
4520 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4522 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4524 int res_offset = 0; /* the result may be a different size then left or right */
4525 int res_size = AOP_SIZE(result);
4529 unsigned long lit = 0L;
4530 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4531 DEBUGpic14_AopType(__LINE__,left,right,result);
4533 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4534 resolveIfx(&rIfx,ifx);
4535 lbl = newiTempLabel(NULL);
4538 /* if the left side is a literal or
4539 if the right is in a pointer register and left
4541 if ((AOP_TYPE(left) == AOP_LIT) ||
4542 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4547 if(AOP_TYPE(right) == AOP_LIT)
4548 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4550 /* if the right side is a literal then anything goes */
4551 if (AOP_TYPE(right) == AOP_LIT &&
4552 AOP_TYPE(left) != AOP_DIR ) {
4555 genc16bit2lit(left, lit, 0);
4557 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4562 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4563 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4565 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4569 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4571 if(res_offset < res_size-1)
4579 /* if the right side is in a register or in direct space or
4580 if the left is a pointer register & right is not */
4581 else if (AOP_TYPE(right) == AOP_REG ||
4582 AOP_TYPE(right) == AOP_DIR ||
4583 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4584 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4585 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4586 int lbl_key = lbl->key;
4589 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4590 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4592 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4593 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4594 __FUNCTION__,__LINE__);
4598 /* switch(size) { */
4600 /* genc16bit2lit(left, lit, 0); */
4602 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4607 if((AOP_TYPE(left) == AOP_DIR) &&
4608 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4610 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4611 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4613 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4615 switch (lit & 0xff) {
4617 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4620 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4621 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4622 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4626 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4627 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4628 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4629 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4633 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4634 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4639 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4642 if(AOP_TYPE(result) == AOP_CRY) {
4643 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4648 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4650 /* fix me. probably need to check result size too */
4651 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4656 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4657 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4664 if(res_offset < res_size-1)
4669 } else if(AOP_TYPE(right) == AOP_REG &&
4670 AOP_TYPE(left) != AOP_DIR){
4673 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4674 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4675 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4680 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4682 if(res_offset < res_size-1)
4687 /* right is a pointer reg need both a & b */
4689 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4691 pic14_emitcode("mov","b,%s",l);
4692 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4693 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4698 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4700 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4702 emitpLabel(lbl->key);
4704 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4711 /*-----------------------------------------------------------------*/
4712 /* gencjne - compare and jump if not equal */
4713 /*-----------------------------------------------------------------*/
4714 static void gencjne(operand *left, operand *right, iCode *ifx)
4716 symbol *tlbl = newiTempLabel(NULL);
4718 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4719 gencjneshort(left, right, lbl);
4721 pic14_emitcode("mov","a,%s",one);
4722 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4723 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4724 pic14_emitcode("clr","a");
4725 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4727 emitpLabel(lbl->key);
4728 emitpLabel(tlbl->key);
4733 /*-----------------------------------------------------------------*/
4734 /* genCmpEq - generates code for equal to */
4735 /*-----------------------------------------------------------------*/
4736 static void genCmpEq (iCode *ic, iCode *ifx)
4738 operand *left, *right, *result;
4739 unsigned long lit = 0L;
4742 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4745 DEBUGpic14_emitcode ("; ifx is non-null","");
4747 DEBUGpic14_emitcode ("; ifx is null","");
4749 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4750 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4751 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4753 size = max(AOP_SIZE(left),AOP_SIZE(right));
4755 DEBUGpic14_AopType(__LINE__,left,right,result);
4757 /* if literal, literal on the right or
4758 if the right is in a pointer register and left
4760 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4761 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4762 operand *tmp = right ;
4768 if(ifx && !AOP_SIZE(result)){
4770 /* if they are both bit variables */
4771 if (AOP_TYPE(left) == AOP_CRY &&
4772 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4773 if(AOP_TYPE(right) == AOP_LIT){
4774 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4776 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4777 pic14_emitcode("cpl","c");
4778 } else if(lit == 1L) {
4779 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4781 pic14_emitcode("clr","c");
4783 /* AOP_TYPE(right) == AOP_CRY */
4785 symbol *lbl = newiTempLabel(NULL);
4786 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4787 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4788 pic14_emitcode("cpl","c");
4789 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4791 /* if true label then we jump if condition
4793 tlbl = newiTempLabel(NULL);
4794 if ( IC_TRUE(ifx) ) {
4795 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4796 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4798 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4799 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4801 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4804 /* left and right are both bit variables, result is carry */
4807 resolveIfx(&rIfx,ifx);
4809 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4810 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4811 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4812 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4817 /* They're not both bit variables. Is the right a literal? */
4818 if(AOP_TYPE(right) == AOP_LIT) {
4819 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4824 switch(lit & 0xff) {
4826 if ( IC_TRUE(ifx) ) {
4827 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4829 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4831 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4832 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4836 if ( IC_TRUE(ifx) ) {
4837 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4839 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4841 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4842 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4846 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4848 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4853 /* end of size == 1 */
4857 genc16bit2lit(left,lit,offset);
4860 /* end of size == 2 */
4865 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4866 emitpcode(POC_IORFW,popGet(AOP(left),1));
4867 emitpcode(POC_IORFW,popGet(AOP(left),2));
4868 emitpcode(POC_IORFW,popGet(AOP(left),3));
4872 /* search for patterns that can be optimized */
4874 genc16bit2lit(left,lit,0);
4877 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4879 genc16bit2lit(left,lit,2);
4881 emitpcode(POC_IORFW,popGet(AOP(left),2));
4882 emitpcode(POC_IORFW,popGet(AOP(left),3));
4895 } else if(AOP_TYPE(right) == AOP_CRY ) {
4896 /* we know the left is not a bit, but that the right is */
4897 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4898 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4899 popGet(AOP(right),offset));
4900 emitpcode(POC_XORLW,popGetLit(1));
4902 /* if the two are equal, then W will be 0 and the Z bit is set
4903 * we could test Z now, or go ahead and check the high order bytes if
4904 * the variable we're comparing is larger than a byte. */
4907 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4909 if ( IC_TRUE(ifx) ) {
4911 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4912 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4915 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4916 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4920 /* They're both variables that are larger than bits */
4923 tlbl = newiTempLabel(NULL);
4926 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4927 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4929 if ( IC_TRUE(ifx) ) {
4932 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4933 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4936 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4937 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4941 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4942 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4946 if(s>1 && IC_TRUE(ifx)) {
4947 emitpLabel(tlbl->key);
4948 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4952 /* mark the icode as generated */
4957 /* if they are both bit variables */
4958 if (AOP_TYPE(left) == AOP_CRY &&
4959 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4960 if(AOP_TYPE(right) == AOP_LIT){
4961 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4963 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4964 pic14_emitcode("cpl","c");
4965 } else if(lit == 1L) {
4966 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4968 pic14_emitcode("clr","c");
4970 /* AOP_TYPE(right) == AOP_CRY */
4972 symbol *lbl = newiTempLabel(NULL);
4973 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4974 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4975 pic14_emitcode("cpl","c");
4976 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4979 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4980 pic14_outBitC(result);
4984 genIfxJump (ifx,"c");
4987 /* if the result is used in an arithmetic operation
4988 then put the result in place */
4989 pic14_outBitC(result);
4992 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4993 gencjne(left,right,result,ifx);
4996 gencjne(left,right,newiTempLabel(NULL));
4998 if(IC_TRUE(ifx)->key)
4999 gencjne(left,right,IC_TRUE(ifx)->key);
5001 gencjne(left,right,IC_FALSE(ifx)->key);
5005 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5006 aopPut(AOP(result),"a",0);
5011 genIfxJump (ifx,"a");
5015 /* if the result is used in an arithmetic operation
5016 then put the result in place */
5018 if (AOP_TYPE(result) != AOP_CRY)
5019 pic14_outAcc(result);
5021 /* leave the result in acc */
5025 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5026 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5027 freeAsmop(result,NULL,ic,TRUE);
5030 /*-----------------------------------------------------------------*/
5031 /* ifxForOp - returns the icode containing the ifx for operand */
5032 /*-----------------------------------------------------------------*/
5033 static iCode *ifxForOp ( operand *op, iCode *ic )
5035 /* if true symbol then needs to be assigned */
5036 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5037 if (IS_TRUE_SYMOP(op))
5040 /* if this has register type condition and
5041 the next instruction is ifx with the same operand
5042 and live to of the operand is upto the ifx only then */
5044 ic->next->op == IFX &&
5045 IC_COND(ic->next)->key == op->key &&
5046 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5050 ic->next->op == IFX &&
5051 IC_COND(ic->next)->key == op->key) {
5052 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5056 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5058 ic->next->op == IFX)
5059 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5062 ic->next->op == IFX &&
5063 IC_COND(ic->next)->key == op->key) {
5064 DEBUGpic14_emitcode ("; "," key is okay");
5065 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5066 OP_SYMBOL(op)->liveTo,
5073 /*-----------------------------------------------------------------*/
5074 /* genAndOp - for && operation */
5075 /*-----------------------------------------------------------------*/
5076 static void genAndOp (iCode *ic)
5078 operand *left,*right, *result;
5081 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5082 /* note here that && operations that are in an
5083 if statement are taken away by backPatchLabels
5084 only those used in arthmetic operations remain */
5085 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5086 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5087 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5089 DEBUGpic14_AopType(__LINE__,left,right,result);
5091 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5092 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5093 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5095 /* if both are bit variables */
5096 /* if (AOP_TYPE(left) == AOP_CRY && */
5097 /* AOP_TYPE(right) == AOP_CRY ) { */
5098 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5099 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5100 /* pic14_outBitC(result); */
5102 /* tlbl = newiTempLabel(NULL); */
5103 /* pic14_toBoolean(left); */
5104 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5105 /* pic14_toBoolean(right); */
5106 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5107 /* pic14_outBitAcc(result); */
5110 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5111 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5112 freeAsmop(result,NULL,ic,TRUE);
5116 /*-----------------------------------------------------------------*/
5117 /* genOrOp - for || operation */
5118 /*-----------------------------------------------------------------*/
5121 modified this code, but it doesn't appear to ever get called
5124 static void genOrOp (iCode *ic)
5126 operand *left,*right, *result;
5129 /* note here that || operations that are in an
5130 if statement are taken away by backPatchLabels
5131 only those used in arthmetic operations remain */
5132 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5133 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5134 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5135 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5137 DEBUGpic14_AopType(__LINE__,left,right,result);
5139 /* if both are bit variables */
5140 if (AOP_TYPE(left) == AOP_CRY &&
5141 AOP_TYPE(right) == AOP_CRY ) {
5142 pic14_emitcode("clrc","");
5143 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5144 AOP(left)->aopu.aop_dir,
5145 AOP(left)->aopu.aop_dir);
5146 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5147 AOP(right)->aopu.aop_dir,
5148 AOP(right)->aopu.aop_dir);
5149 pic14_emitcode("setc","");
5152 tlbl = newiTempLabel(NULL);
5153 pic14_toBoolean(left);
5155 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5156 pic14_toBoolean(right);
5157 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5159 pic14_outBitAcc(result);
5162 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5163 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5164 freeAsmop(result,NULL,ic,TRUE);
5167 /*-----------------------------------------------------------------*/
5168 /* isLiteralBit - test if lit == 2^n */
5169 /*-----------------------------------------------------------------*/
5170 static int isLiteralBit(unsigned long lit)
5172 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5173 0x100L,0x200L,0x400L,0x800L,
5174 0x1000L,0x2000L,0x4000L,0x8000L,
5175 0x10000L,0x20000L,0x40000L,0x80000L,
5176 0x100000L,0x200000L,0x400000L,0x800000L,
5177 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5178 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5182 for(idx = 0; idx < 32; idx++)
5188 /*-----------------------------------------------------------------*/
5189 /* continueIfTrue - */
5190 /*-----------------------------------------------------------------*/
5191 static void continueIfTrue (iCode *ic)
5193 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5195 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5199 /*-----------------------------------------------------------------*/
5201 /*-----------------------------------------------------------------*/
5202 static void jumpIfTrue (iCode *ic)
5204 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5206 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5210 /*-----------------------------------------------------------------*/
5211 /* jmpTrueOrFalse - */
5212 /*-----------------------------------------------------------------*/
5213 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5215 // ugly but optimized by peephole
5216 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5218 symbol *nlbl = newiTempLabel(NULL);
5219 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5220 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5221 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5222 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5225 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5226 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5231 /*-----------------------------------------------------------------*/
5232 /* genAnd - code for and */
5233 /*-----------------------------------------------------------------*/
5234 static void genAnd (iCode *ic, iCode *ifx)
5236 operand *left, *right, *result;
5238 unsigned long lit = 0L;
5243 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5244 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5245 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5246 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5248 resolveIfx(&rIfx,ifx);
5250 /* if left is a literal & right is not then exchange them */
5251 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5252 AOP_NEEDSACC(left)) {
5253 operand *tmp = right ;
5258 /* if result = right then exchange them */
5259 if(pic14_sameRegs(AOP(result),AOP(right))){
5260 operand *tmp = right ;
5265 /* if right is bit then exchange them */
5266 if (AOP_TYPE(right) == AOP_CRY &&
5267 AOP_TYPE(left) != AOP_CRY){
5268 operand *tmp = right ;
5272 if(AOP_TYPE(right) == AOP_LIT)
5273 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5275 size = AOP_SIZE(result);
5277 DEBUGpic14_AopType(__LINE__,left,right,result);
5280 // result = bit & yy;
5281 if (AOP_TYPE(left) == AOP_CRY){
5282 // c = bit & literal;
5283 if(AOP_TYPE(right) == AOP_LIT){
5285 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5288 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5291 if(size && (AOP_TYPE(result) == AOP_CRY)){
5292 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5295 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5299 pic14_emitcode("clr","c");
5302 if (AOP_TYPE(right) == AOP_CRY){
5304 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5305 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5308 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5310 pic14_emitcode("rrc","a");
5311 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5317 pic14_outBitC(result);
5319 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5320 genIfxJump(ifx, "c");
5324 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5325 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5326 if((AOP_TYPE(right) == AOP_LIT) &&
5327 (AOP_TYPE(result) == AOP_CRY) &&
5328 (AOP_TYPE(left) != AOP_CRY)){
5329 int posbit = isLiteralBit(lit);
5333 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5336 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5342 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5343 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5345 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5346 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5349 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5350 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5351 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5358 symbol *tlbl = newiTempLabel(NULL);
5359 int sizel = AOP_SIZE(left);
5361 pic14_emitcode("setb","c");
5363 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5364 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5366 if((posbit = isLiteralBit(bytelit)) != 0)
5367 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5369 if(bytelit != 0x0FFL)
5370 pic14_emitcode("anl","a,%s",
5371 aopGet(AOP(right),offset,FALSE,TRUE));
5372 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5377 // bit = left & literal
5379 pic14_emitcode("clr","c");
5380 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5382 // if(left & literal)
5385 jmpTrueOrFalse(ifx, tlbl);
5389 pic14_outBitC(result);
5393 /* if left is same as result */
5394 if(pic14_sameRegs(AOP(result),AOP(left))){
5396 for(;size--; offset++,lit>>=8) {
5397 if(AOP_TYPE(right) == AOP_LIT){
5398 switch(lit & 0xff) {
5400 /* and'ing with 0 has clears the result */
5401 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5402 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5405 /* and'ing with 0xff is a nop when the result and left are the same */
5410 int p = my_powof2( (~lit) & 0xff );
5412 /* only one bit is set in the literal, so use a bcf instruction */
5413 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5414 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5417 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5418 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5419 if(know_W != (lit&0xff))
5420 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5422 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5427 if (AOP_TYPE(left) == AOP_ACC) {
5428 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5430 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5431 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5438 // left & result in different registers
5439 if(AOP_TYPE(result) == AOP_CRY){
5441 // if(size), result in bit
5442 // if(!size && ifx), conditional oper: if(left & right)
5443 symbol *tlbl = newiTempLabel(NULL);
5444 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5446 pic14_emitcode("setb","c");
5448 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5449 pic14_emitcode("anl","a,%s",
5450 aopGet(AOP(left),offset,FALSE,FALSE));
5451 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5456 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5457 pic14_outBitC(result);
5459 jmpTrueOrFalse(ifx, tlbl);
5461 for(;(size--);offset++) {
5463 // result = left & right
5464 if(AOP_TYPE(right) == AOP_LIT){
5465 int t = (lit >> (offset*8)) & 0x0FFL;
5468 pic14_emitcode("clrf","%s",
5469 aopGet(AOP(result),offset,FALSE,FALSE));
5470 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5473 if(AOP_TYPE(left) != AOP_ACC) {
5474 pic14_emitcode("movf","%s,w",
5475 aopGet(AOP(left),offset,FALSE,FALSE));
5476 pic14_emitcode("movwf","%s",
5477 aopGet(AOP(result),offset,FALSE,FALSE));
5478 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5480 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5483 if(AOP_TYPE(left) == AOP_ACC) {
5484 emitpcode(POC_ANDLW, popGetLit(t));
5486 pic14_emitcode("movlw","0x%x",t);
5487 pic14_emitcode("andwf","%s,w",
5488 aopGet(AOP(left),offset,FALSE,FALSE));
5489 pic14_emitcode("movwf","%s",
5490 aopGet(AOP(result),offset,FALSE,FALSE));
5492 emitpcode(POC_MOVLW, popGetLit(t));
5493 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5495 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5500 if (AOP_TYPE(left) == AOP_ACC) {
5501 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5502 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5504 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5505 pic14_emitcode("andwf","%s,w",
5506 aopGet(AOP(left),offset,FALSE,FALSE));
5507 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5508 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5510 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5511 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5517 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5518 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5519 freeAsmop(result,NULL,ic,TRUE);
5522 /*-----------------------------------------------------------------*/
5523 /* genOr - code for or */
5524 /*-----------------------------------------------------------------*/
5525 static void genOr (iCode *ic, iCode *ifx)
5527 operand *left, *right, *result;
5529 unsigned long lit = 0L;
5531 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5533 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5534 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5535 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5537 DEBUGpic14_AopType(__LINE__,left,right,result);
5539 /* if left is a literal & right is not then exchange them */
5540 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5541 AOP_NEEDSACC(left)) {
5542 operand *tmp = right ;
5547 /* if result = right then exchange them */
5548 if(pic14_sameRegs(AOP(result),AOP(right))){
5549 operand *tmp = right ;
5554 /* if right is bit then exchange them */
5555 if (AOP_TYPE(right) == AOP_CRY &&
5556 AOP_TYPE(left) != AOP_CRY){
5557 operand *tmp = right ;
5562 DEBUGpic14_AopType(__LINE__,left,right,result);
5564 if(AOP_TYPE(right) == AOP_LIT)
5565 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5567 size = AOP_SIZE(result);
5571 if (AOP_TYPE(left) == AOP_CRY){
5572 if(AOP_TYPE(right) == AOP_LIT){
5573 // c = bit & literal;
5575 // lit != 0 => result = 1
5576 if(AOP_TYPE(result) == AOP_CRY){
5578 emitpcode(POC_BSF, popGet(AOP(result),0));
5579 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5580 // AOP(result)->aopu.aop_dir,
5581 // AOP(result)->aopu.aop_dir);
5583 continueIfTrue(ifx);
5587 // lit == 0 => result = left
5588 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5590 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5593 if (AOP_TYPE(right) == AOP_CRY){
5594 if(pic14_sameRegs(AOP(result),AOP(left))){
5596 emitpcode(POC_BCF, popGet(AOP(result),0));
5597 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5598 emitpcode(POC_BSF, popGet(AOP(result),0));
5600 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5601 AOP(result)->aopu.aop_dir,
5602 AOP(result)->aopu.aop_dir);
5603 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5604 AOP(right)->aopu.aop_dir,
5605 AOP(right)->aopu.aop_dir);
5606 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5607 AOP(result)->aopu.aop_dir,
5608 AOP(result)->aopu.aop_dir);
5610 if( AOP_TYPE(result) == AOP_ACC) {
5611 emitpcode(POC_MOVLW, popGetLit(0));
5612 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5613 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5614 emitpcode(POC_MOVLW, popGetLit(1));
5618 emitpcode(POC_BCF, popGet(AOP(result),0));
5619 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5620 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5621 emitpcode(POC_BSF, popGet(AOP(result),0));
5623 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5624 AOP(result)->aopu.aop_dir,
5625 AOP(result)->aopu.aop_dir);
5626 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5627 AOP(right)->aopu.aop_dir,
5628 AOP(right)->aopu.aop_dir);
5629 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5630 AOP(left)->aopu.aop_dir,
5631 AOP(left)->aopu.aop_dir);
5632 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5633 AOP(result)->aopu.aop_dir,
5634 AOP(result)->aopu.aop_dir);
5639 symbol *tlbl = newiTempLabel(NULL);
5640 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5643 emitpcode(POC_BCF, popGet(AOP(result),0));
5644 if( AOP_TYPE(right) == AOP_ACC) {
5645 emitpcode(POC_IORLW, popGetLit(0));
5647 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5648 emitpcode(POC_BSF, popGet(AOP(result),0));
5653 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5654 pic14_emitcode(";XXX setb","c");
5655 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5656 AOP(left)->aopu.aop_dir,tlbl->key+100);
5657 pic14_toBoolean(right);
5658 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5659 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5660 jmpTrueOrFalse(ifx, tlbl);
5664 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5671 pic14_outBitC(result);
5673 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5674 genIfxJump(ifx, "c");
5678 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5679 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5680 if((AOP_TYPE(right) == AOP_LIT) &&
5681 (AOP_TYPE(result) == AOP_CRY) &&
5682 (AOP_TYPE(left) != AOP_CRY)){
5684 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5687 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5689 continueIfTrue(ifx);
5692 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5693 // lit = 0, result = boolean(left)
5695 pic14_emitcode(";XXX setb","c");
5696 pic14_toBoolean(right);
5698 symbol *tlbl = newiTempLabel(NULL);
5699 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5701 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5703 genIfxJump (ifx,"a");
5707 pic14_outBitC(result);
5711 /* if left is same as result */
5712 if(pic14_sameRegs(AOP(result),AOP(left))){
5714 for(;size--; offset++,lit>>=8) {
5715 if(AOP_TYPE(right) == AOP_LIT){
5716 if((lit & 0xff) == 0)
5717 /* or'ing with 0 has no effect */
5720 int p = my_powof2(lit & 0xff);
5722 /* only one bit is set in the literal, so use a bsf instruction */
5724 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5726 if(know_W != (lit & 0xff))
5727 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5728 know_W = lit & 0xff;
5729 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5734 if (AOP_TYPE(left) == AOP_ACC) {
5735 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5736 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5738 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5739 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5741 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5742 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5748 // left & result in different registers
5749 if(AOP_TYPE(result) == AOP_CRY){
5751 // if(size), result in bit
5752 // if(!size && ifx), conditional oper: if(left | right)
5753 symbol *tlbl = newiTempLabel(NULL);
5754 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5755 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5759 pic14_emitcode(";XXX setb","c");
5761 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5762 pic14_emitcode(";XXX orl","a,%s",
5763 aopGet(AOP(left),offset,FALSE,FALSE));
5764 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5769 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5770 pic14_outBitC(result);
5772 jmpTrueOrFalse(ifx, tlbl);
5773 } else for(;(size--);offset++){
5775 // result = left & right
5776 if(AOP_TYPE(right) == AOP_LIT){
5777 int t = (lit >> (offset*8)) & 0x0FFL;
5780 if (AOP_TYPE(left) != AOP_ACC) {
5781 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5783 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5787 if (AOP_TYPE(left) == AOP_ACC) {
5788 emitpcode(POC_IORLW, popGetLit(t));
5790 emitpcode(POC_MOVLW, popGetLit(t));
5791 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5793 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5798 // faster than result <- left, anl result,right
5799 // and better if result is SFR
5800 if (AOP_TYPE(left) == AOP_ACC) {
5801 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5802 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5804 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5805 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5807 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5808 pic14_emitcode("iorwf","%s,w",
5809 aopGet(AOP(left),offset,FALSE,FALSE));
5811 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5812 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5817 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5818 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5819 freeAsmop(result,NULL,ic,TRUE);
5822 /*-----------------------------------------------------------------*/
5823 /* genXor - code for xclusive or */
5824 /*-----------------------------------------------------------------*/
5825 static void genXor (iCode *ic, iCode *ifx)
5827 operand *left, *right, *result;
5829 unsigned long lit = 0L;
5831 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5833 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5834 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5835 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5837 /* if left is a literal & right is not ||
5838 if left needs acc & right does not */
5839 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5840 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5841 operand *tmp = right ;
5846 /* if result = right then exchange them */
5847 if(pic14_sameRegs(AOP(result),AOP(right))){
5848 operand *tmp = right ;
5853 /* if right is bit then exchange them */
5854 if (AOP_TYPE(right) == AOP_CRY &&
5855 AOP_TYPE(left) != AOP_CRY){
5856 operand *tmp = right ;
5860 if(AOP_TYPE(right) == AOP_LIT)
5861 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5863 size = AOP_SIZE(result);
5867 if (AOP_TYPE(left) == AOP_CRY){
5868 if(AOP_TYPE(right) == AOP_LIT){
5869 // c = bit & literal;
5871 // lit>>1 != 0 => result = 1
5872 if(AOP_TYPE(result) == AOP_CRY){
5874 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5875 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5877 continueIfTrue(ifx);
5880 pic14_emitcode("setb","c");
5884 // lit == 0, result = left
5885 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5887 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5889 // lit == 1, result = not(left)
5890 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5891 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5892 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5893 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5896 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5897 pic14_emitcode("cpl","c");
5904 symbol *tlbl = newiTempLabel(NULL);
5905 if (AOP_TYPE(right) == AOP_CRY){
5907 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5910 int sizer = AOP_SIZE(right);
5912 // if val>>1 != 0, result = 1
5913 pic14_emitcode("setb","c");
5915 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5917 // test the msb of the lsb
5918 pic14_emitcode("anl","a,#0xfe");
5919 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5923 pic14_emitcode("rrc","a");
5925 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5926 pic14_emitcode("cpl","c");
5927 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5932 pic14_outBitC(result);
5934 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5935 genIfxJump(ifx, "c");
5939 if(pic14_sameRegs(AOP(result),AOP(left))){
5940 /* if left is same as result */
5941 for(;size--; offset++) {
5942 if(AOP_TYPE(right) == AOP_LIT){
5943 int t = (lit >> (offset*8)) & 0x0FFL;
5947 if (IS_AOP_PREG(left)) {
5948 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5949 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5950 aopPut(AOP(result),"a",offset);
5952 emitpcode(POC_MOVLW, popGetLit(t));
5953 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5954 pic14_emitcode("xrl","%s,%s",
5955 aopGet(AOP(left),offset,FALSE,TRUE),
5956 aopGet(AOP(right),offset,FALSE,FALSE));
5959 if (AOP_TYPE(left) == AOP_ACC)
5960 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5962 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5963 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5965 if (IS_AOP_PREG(left)) {
5966 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5967 aopPut(AOP(result),"a",offset);
5969 pic14_emitcode("xrl","%s,a",
5970 aopGet(AOP(left),offset,FALSE,TRUE));
5976 // left & result in different registers
5977 if(AOP_TYPE(result) == AOP_CRY){
5979 // if(size), result in bit
5980 // if(!size && ifx), conditional oper: if(left ^ right)
5981 symbol *tlbl = newiTempLabel(NULL);
5982 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5984 pic14_emitcode("setb","c");
5986 if((AOP_TYPE(right) == AOP_LIT) &&
5987 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5988 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5990 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5991 pic14_emitcode("xrl","a,%s",
5992 aopGet(AOP(left),offset,FALSE,FALSE));
5994 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5999 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6000 pic14_outBitC(result);
6002 jmpTrueOrFalse(ifx, tlbl);
6003 } else for(;(size--);offset++){
6005 // result = left & right
6006 if(AOP_TYPE(right) == AOP_LIT){
6007 int t = (lit >> (offset*8)) & 0x0FFL;
6010 if (AOP_TYPE(left) != AOP_ACC) {
6011 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6013 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6014 pic14_emitcode("movf","%s,w",
6015 aopGet(AOP(left),offset,FALSE,FALSE));
6016 pic14_emitcode("movwf","%s",
6017 aopGet(AOP(result),offset,FALSE,FALSE));
6020 if (AOP_TYPE(left) == AOP_ACC) {
6021 emitpcode(POC_XORLW, popGetLit(t));
6023 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6025 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6028 if (AOP_TYPE(left) == AOP_ACC) {
6029 emitpcode(POC_XORLW, popGetLit(t));
6031 emitpcode(POC_MOVLW, popGetLit(t));
6032 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6034 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6035 pic14_emitcode("movlw","0x%x",t);
6036 pic14_emitcode("xorwf","%s,w",
6037 aopGet(AOP(left),offset,FALSE,FALSE));
6038 pic14_emitcode("movwf","%s",
6039 aopGet(AOP(result),offset,FALSE,FALSE));
6045 // faster than result <- left, anl result,right
6046 // and better if result is SFR
6047 if (AOP_TYPE(left) == AOP_ACC) {
6048 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6049 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6051 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6052 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6053 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6054 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6056 if ( AOP_TYPE(result) != AOP_ACC){
6057 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6058 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6064 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6065 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6066 freeAsmop(result,NULL,ic,TRUE);
6069 /*-----------------------------------------------------------------*/
6070 /* genInline - write the inline code out */
6071 /*-----------------------------------------------------------------*/
6072 static void genInline (iCode *ic)
6074 char *buffer, *bp, *bp1;
6076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6078 _G.inLine += (!options.asmpeep);
6080 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6081 strcpy(buffer,IC_INLINE(ic));
6083 /* emit each line as a code */
6089 addpCode2pBlock(pb,AssembleLine(bp1));
6096 pic14_emitcode(bp1,"");
6102 if ((bp1 != bp) && *bp1)
6103 addpCode2pBlock(pb,AssembleLine(bp1));
6107 _G.inLine -= (!options.asmpeep);
6110 /*-----------------------------------------------------------------*/
6111 /* genRRC - rotate right with carry */
6112 /*-----------------------------------------------------------------*/
6113 static void genRRC (iCode *ic)
6115 operand *left , *result ;
6116 int size, offset = 0, same;
6118 /* rotate right with carry */
6120 result=IC_RESULT(ic);
6121 aopOp (left,ic,FALSE);
6122 aopOp (result,ic,FALSE);
6124 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6126 same = pic14_sameRegs(AOP(result),AOP(left));
6128 size = AOP_SIZE(result);
6130 /* get the lsb and put it into the carry */
6131 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6138 emitpcode(POC_RRF, popGet(AOP(left),offset));
6140 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6141 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6147 freeAsmop(left,NULL,ic,TRUE);
6148 freeAsmop(result,NULL,ic,TRUE);
6151 /*-----------------------------------------------------------------*/
6152 /* genRLC - generate code for rotate left with carry */
6153 /*-----------------------------------------------------------------*/
6154 static void genRLC (iCode *ic)
6156 operand *left , *result ;
6157 int size, offset = 0;
6160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6161 /* rotate right with carry */
6163 result=IC_RESULT(ic);
6164 aopOp (left,ic,FALSE);
6165 aopOp (result,ic,FALSE);
6167 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6169 same = pic14_sameRegs(AOP(result),AOP(left));
6171 /* move it to the result */
6172 size = AOP_SIZE(result);
6174 /* get the msb and put it into the carry */
6175 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6182 emitpcode(POC_RLF, popGet(AOP(left),offset));
6184 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6185 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6192 freeAsmop(left,NULL,ic,TRUE);
6193 freeAsmop(result,NULL,ic,TRUE);
6196 /*-----------------------------------------------------------------*/
6197 /* genGetHbit - generates code get highest order bit */
6198 /*-----------------------------------------------------------------*/
6199 static void genGetHbit (iCode *ic)
6201 operand *left, *result;
6203 result=IC_RESULT(ic);
6204 aopOp (left,ic,FALSE);
6205 aopOp (result,ic,FALSE);
6207 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6208 /* get the highest order byte into a */
6209 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6210 if(AOP_TYPE(result) == AOP_CRY){
6211 pic14_emitcode("rlc","a");
6212 pic14_outBitC(result);
6215 pic14_emitcode("rl","a");
6216 pic14_emitcode("anl","a,#0x01");
6217 pic14_outAcc(result);
6221 freeAsmop(left,NULL,ic,TRUE);
6222 freeAsmop(result,NULL,ic,TRUE);
6225 /*-----------------------------------------------------------------*/
6226 /* AccRol - rotate left accumulator by known count */
6227 /*-----------------------------------------------------------------*/
6228 static void AccRol (int shCount)
6230 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6231 shCount &= 0x0007; // shCount : 0..7
6236 pic14_emitcode("rl","a");
6239 pic14_emitcode("rl","a");
6240 pic14_emitcode("rl","a");
6243 pic14_emitcode("swap","a");
6244 pic14_emitcode("rr","a");
6247 pic14_emitcode("swap","a");
6250 pic14_emitcode("swap","a");
6251 pic14_emitcode("rl","a");
6254 pic14_emitcode("rr","a");
6255 pic14_emitcode("rr","a");
6258 pic14_emitcode("rr","a");
6263 /*-----------------------------------------------------------------*/
6264 /* AccLsh - left shift accumulator by known count */
6265 /*-----------------------------------------------------------------*/
6266 static void AccLsh (int shCount)
6268 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6271 pic14_emitcode("add","a,acc");
6274 pic14_emitcode("add","a,acc");
6275 pic14_emitcode("add","a,acc");
6277 /* rotate left accumulator */
6279 /* and kill the lower order bits */
6280 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6285 /*-----------------------------------------------------------------*/
6286 /* AccRsh - right shift accumulator by known count */
6287 /*-----------------------------------------------------------------*/
6288 static void AccRsh (int shCount)
6290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6294 pic14_emitcode("rrc","a");
6296 /* rotate right accumulator */
6297 AccRol(8 - shCount);
6298 /* and kill the higher order bits */
6299 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6305 /*-----------------------------------------------------------------*/
6306 /* AccSRsh - signed right shift accumulator by known count */
6307 /*-----------------------------------------------------------------*/
6308 static void AccSRsh (int shCount)
6311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6314 pic14_emitcode("mov","c,acc.7");
6315 pic14_emitcode("rrc","a");
6316 } else if(shCount == 2){
6317 pic14_emitcode("mov","c,acc.7");
6318 pic14_emitcode("rrc","a");
6319 pic14_emitcode("mov","c,acc.7");
6320 pic14_emitcode("rrc","a");
6322 tlbl = newiTempLabel(NULL);
6323 /* rotate right accumulator */
6324 AccRol(8 - shCount);
6325 /* and kill the higher order bits */
6326 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6327 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6328 pic14_emitcode("orl","a,#0x%02x",
6329 (unsigned char)~SRMask[shCount]);
6330 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6335 /*-----------------------------------------------------------------*/
6336 /* shiftR1Left2Result - shift right one byte from left to result */
6337 /*-----------------------------------------------------------------*/
6338 static void shiftR1Left2ResultSigned (operand *left, int offl,
6339 operand *result, int offr,
6344 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6346 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6350 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6352 emitpcode(POC_RRF, popGet(AOP(result),offr));
6354 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6355 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6361 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6363 emitpcode(POC_RRF, popGet(AOP(result),offr));
6365 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6366 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6368 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6369 emitpcode(POC_RRF, popGet(AOP(result),offr));
6375 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6377 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6378 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6381 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6382 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6383 emitpcode(POC_ANDLW, popGetLit(0x1f));
6385 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6386 emitpcode(POC_IORLW, popGetLit(0xe0));
6388 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6392 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6393 emitpcode(POC_ANDLW, popGetLit(0x0f));
6394 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6395 emitpcode(POC_IORLW, popGetLit(0xf0));
6396 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6400 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6402 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6403 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6405 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6406 emitpcode(POC_ANDLW, popGetLit(0x07));
6407 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6408 emitpcode(POC_IORLW, popGetLit(0xf8));
6409 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6414 emitpcode(POC_MOVLW, popGetLit(0x00));
6415 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6416 emitpcode(POC_MOVLW, popGetLit(0xfe));
6417 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6418 emitpcode(POC_IORLW, popGetLit(0x01));
6419 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6421 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6422 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6423 emitpcode(POC_DECF, popGet(AOP(result),offr));
6424 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6425 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6431 emitpcode(POC_MOVLW, popGetLit(0x00));
6432 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6433 emitpcode(POC_MOVLW, popGetLit(0xff));
6434 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6436 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6437 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6438 emitpcode(POC_DECF, popGet(AOP(result),offr));
6446 /*-----------------------------------------------------------------*/
6447 /* shiftR1Left2Result - shift right one byte from left to result */
6448 /*-----------------------------------------------------------------*/
6449 static void shiftR1Left2Result (operand *left, int offl,
6450 operand *result, int offr,
6451 int shCount, int sign)
6455 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6457 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6459 /* Copy the msb into the carry if signed. */
6461 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6471 emitpcode(POC_RRF, popGet(AOP(result),offr));
6473 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6474 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6480 emitpcode(POC_RRF, popGet(AOP(result),offr));
6482 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6483 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6486 emitpcode(POC_RRF, popGet(AOP(result),offr));
6491 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6493 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6494 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6497 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6498 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6499 emitpcode(POC_ANDLW, popGetLit(0x1f));
6500 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6504 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6505 emitpcode(POC_ANDLW, popGetLit(0x0f));
6506 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6510 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6511 emitpcode(POC_ANDLW, popGetLit(0x0f));
6512 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6514 emitpcode(POC_RRF, popGet(AOP(result),offr));
6519 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6520 emitpcode(POC_ANDLW, popGetLit(0x80));
6521 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6522 emitpcode(POC_RLF, popGet(AOP(result),offr));
6523 emitpcode(POC_RLF, popGet(AOP(result),offr));
6528 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6529 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6530 emitpcode(POC_RLF, popGet(AOP(result),offr));
6539 /*-----------------------------------------------------------------*/
6540 /* shiftL1Left2Result - shift left one byte from left to result */
6541 /*-----------------------------------------------------------------*/
6542 static void shiftL1Left2Result (operand *left, int offl,
6543 operand *result, int offr, int shCount)
6548 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6550 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6551 DEBUGpic14_emitcode ("; ***","same = %d",same);
6552 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6554 /* shift left accumulator */
6555 //AccLsh(shCount); // don't comment out just yet...
6556 // aopPut(AOP(result),"a",offr);
6560 /* Shift left 1 bit position */
6561 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6563 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6565 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6566 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6570 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6571 emitpcode(POC_ANDLW,popGetLit(0x7e));
6572 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6573 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6576 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6577 emitpcode(POC_ANDLW,popGetLit(0x3e));
6578 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6579 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6580 emitpcode(POC_RLF, popGet(AOP(result),offr));
6583 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6584 emitpcode(POC_ANDLW, popGetLit(0xf0));
6585 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6588 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6589 emitpcode(POC_ANDLW, popGetLit(0xf0));
6590 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6591 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6594 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6595 emitpcode(POC_ANDLW, popGetLit(0x30));
6596 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6597 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6598 emitpcode(POC_RLF, popGet(AOP(result),offr));
6601 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6602 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6603 emitpcode(POC_RRF, popGet(AOP(result),offr));
6607 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6612 /*-----------------------------------------------------------------*/
6613 /* movLeft2Result - move byte from left to result */
6614 /*-----------------------------------------------------------------*/
6615 static void movLeft2Result (operand *left, int offl,
6616 operand *result, int offr)
6619 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6620 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6621 l = aopGet(AOP(left),offl,FALSE,FALSE);
6623 if (*l == '@' && (IS_AOP_PREG(result))) {
6624 pic14_emitcode("mov","a,%s",l);
6625 aopPut(AOP(result),"a",offr);
6627 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6628 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6633 /*-----------------------------------------------------------------*/
6634 /* shiftL2Left2Result - shift left two bytes from left to result */
6635 /*-----------------------------------------------------------------*/
6636 static void shiftL2Left2Result (operand *left, int offl,
6637 operand *result, int offr, int shCount)
6641 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6643 if(pic14_sameRegs(AOP(result), AOP(left))) {
6651 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6652 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6653 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6657 emitpcode(POC_RLF, popGet(AOP(result),offr));
6658 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_MOVLW, popGetLit(0x0f));
6665 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6666 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6667 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6668 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6669 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6670 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6672 emitpcode(POC_RLF, popGet(AOP(result),offr));
6673 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6677 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6678 emitpcode(POC_RRF, popGet(AOP(result),offr));
6679 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6680 emitpcode(POC_RRF, popGet(AOP(result),offr));
6681 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_ANDLW,popGetLit(0xc0));
6683 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6684 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6685 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6686 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6689 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6690 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6691 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6692 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6693 emitpcode(POC_RRF, popGet(AOP(result),offr));
6703 /* note, use a mov/add for the shift since the mov has a
6704 chance of getting optimized out */
6705 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6706 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6707 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6708 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6709 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6713 emitpcode(POC_RLF, popGet(AOP(result),offr));
6714 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6720 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6721 emitpcode(POC_ANDLW, popGetLit(0xF0));
6722 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6723 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6724 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6725 emitpcode(POC_ANDLW, popGetLit(0xF0));
6726 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6727 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6731 emitpcode(POC_RLF, popGet(AOP(result),offr));
6732 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6737 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6738 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6739 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6741 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6742 emitpcode(POC_RRF, popGet(AOP(result),offr));
6743 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6744 emitpcode(POC_ANDLW,popGetLit(0xc0));
6745 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6746 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6747 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6748 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6751 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6752 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6753 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6754 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6755 emitpcode(POC_RRF, popGet(AOP(result),offr));
6760 /*-----------------------------------------------------------------*/
6761 /* shiftR2Left2Result - shift right two bytes from left to result */
6762 /*-----------------------------------------------------------------*/
6763 static void shiftR2Left2Result (operand *left, int offl,
6764 operand *result, int offr,
6765 int shCount, int sign)
6769 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6770 same = pic14_sameRegs(AOP(result), AOP(left));
6772 if(same && ((offl + MSB16) == offr)){
6774 /* don't crash result[offr] */
6775 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6776 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6779 movLeft2Result(left,offl, result, offr);
6780 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6783 /* a:x >> shCount (x = lsb(result))*/
6786 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6788 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6797 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6802 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6803 emitpcode(POC_RRF,popGet(AOP(result),offr));
6805 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6806 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6807 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6808 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6813 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6816 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6817 emitpcode(POC_RRF,popGet(AOP(result),offr));
6824 emitpcode(POC_MOVLW, popGetLit(0xf0));
6825 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6826 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6828 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6829 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6830 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6831 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6833 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6834 emitpcode(POC_ANDLW, popGetLit(0x0f));
6835 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6837 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6838 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6839 emitpcode(POC_ANDLW, popGetLit(0xf0));
6840 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6841 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6845 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6846 emitpcode(POC_RRF, popGet(AOP(result),offr));
6850 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6851 emitpcode(POC_BTFSC,
6852 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6853 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6861 emitpcode(POC_RLF, popGet(AOP(result),offr));
6862 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6864 emitpcode(POC_RLF, popGet(AOP(result),offr));
6865 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6866 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6867 emitpcode(POC_ANDLW,popGetLit(0x03));
6869 emitpcode(POC_BTFSC,
6870 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6871 emitpcode(POC_IORLW,popGetLit(0xfc));
6873 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6874 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6875 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6876 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6878 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6879 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6880 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6881 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6882 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6883 emitpcode(POC_RLF, popGet(AOP(result),offr));
6884 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6885 emitpcode(POC_ANDLW,popGetLit(0x03));
6887 emitpcode(POC_BTFSC,
6888 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6889 emitpcode(POC_IORLW,popGetLit(0xfc));
6891 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6892 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6899 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6900 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6901 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6902 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6905 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6907 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6912 /*-----------------------------------------------------------------*/
6913 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6914 /*-----------------------------------------------------------------*/
6915 static void shiftLLeftOrResult (operand *left, int offl,
6916 operand *result, int offr, int shCount)
6918 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6919 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6920 /* shift left accumulator */
6922 /* or with result */
6923 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6924 /* back to result */
6925 aopPut(AOP(result),"a",offr);
6928 /*-----------------------------------------------------------------*/
6929 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6930 /*-----------------------------------------------------------------*/
6931 static void shiftRLeftOrResult (operand *left, int offl,
6932 operand *result, int offr, int shCount)
6934 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6935 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6936 /* shift right accumulator */
6938 /* or with result */
6939 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6940 /* back to result */
6941 aopPut(AOP(result),"a",offr);
6944 /*-----------------------------------------------------------------*/
6945 /* genlshOne - left shift a one byte quantity by known count */
6946 /*-----------------------------------------------------------------*/
6947 static void genlshOne (operand *result, operand *left, int shCount)
6949 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6950 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6953 /*-----------------------------------------------------------------*/
6954 /* genlshTwo - left shift two bytes by known amount != 0 */
6955 /*-----------------------------------------------------------------*/
6956 static void genlshTwo (operand *result,operand *left, int shCount)
6960 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6961 size = pic14_getDataSize(result);
6963 /* if shCount >= 8 */
6969 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6971 movLeft2Result(left, LSB, result, MSB16);
6973 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6976 /* 1 <= shCount <= 7 */
6979 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6981 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6985 /*-----------------------------------------------------------------*/
6986 /* shiftLLong - shift left one long from left to result */
6987 /* offl = LSB or MSB16 */
6988 /*-----------------------------------------------------------------*/
6989 static void shiftLLong (operand *left, operand *result, int offr )
6992 int size = AOP_SIZE(result);
6994 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6995 if(size >= LSB+offr){
6996 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6998 pic14_emitcode("add","a,acc");
6999 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7000 size >= MSB16+offr && offr != LSB )
7001 pic14_emitcode("xch","a,%s",
7002 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7004 aopPut(AOP(result),"a",LSB+offr);
7007 if(size >= MSB16+offr){
7008 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7009 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7012 pic14_emitcode("rlc","a");
7013 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7014 size >= MSB24+offr && offr != LSB)
7015 pic14_emitcode("xch","a,%s",
7016 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7018 aopPut(AOP(result),"a",MSB16+offr);
7021 if(size >= MSB24+offr){
7022 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7023 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7026 pic14_emitcode("rlc","a");
7027 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7028 size >= MSB32+offr && offr != LSB )
7029 pic14_emitcode("xch","a,%s",
7030 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7032 aopPut(AOP(result),"a",MSB24+offr);
7035 if(size > MSB32+offr){
7036 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7037 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7040 pic14_emitcode("rlc","a");
7041 aopPut(AOP(result),"a",MSB32+offr);
7044 aopPut(AOP(result),zero,LSB);
7047 /*-----------------------------------------------------------------*/
7048 /* genlshFour - shift four byte by a known amount != 0 */
7049 /*-----------------------------------------------------------------*/
7050 static void genlshFour (operand *result, operand *left, int shCount)
7054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7055 size = AOP_SIZE(result);
7057 /* if shifting more that 3 bytes */
7058 if (shCount >= 24 ) {
7061 /* lowest order of left goes to the highest
7062 order of the destination */
7063 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7065 movLeft2Result(left, LSB, result, MSB32);
7066 aopPut(AOP(result),zero,LSB);
7067 aopPut(AOP(result),zero,MSB16);
7068 aopPut(AOP(result),zero,MSB32);
7072 /* more than two bytes */
7073 else if ( shCount >= 16 ) {
7074 /* lower order two bytes goes to higher order two bytes */
7076 /* if some more remaining */
7078 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7080 movLeft2Result(left, MSB16, result, MSB32);
7081 movLeft2Result(left, LSB, result, MSB24);
7083 aopPut(AOP(result),zero,MSB16);
7084 aopPut(AOP(result),zero,LSB);
7088 /* if more than 1 byte */
7089 else if ( shCount >= 8 ) {
7090 /* lower order three bytes goes to higher order three bytes */
7094 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7096 movLeft2Result(left, LSB, result, MSB16);
7098 else{ /* size = 4 */
7100 movLeft2Result(left, MSB24, result, MSB32);
7101 movLeft2Result(left, MSB16, result, MSB24);
7102 movLeft2Result(left, LSB, result, MSB16);
7103 aopPut(AOP(result),zero,LSB);
7105 else if(shCount == 1)
7106 shiftLLong(left, result, MSB16);
7108 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7109 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7110 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7111 aopPut(AOP(result),zero,LSB);
7116 /* 1 <= shCount <= 7 */
7117 else if(shCount <= 2){
7118 shiftLLong(left, result, LSB);
7120 shiftLLong(result, result, LSB);
7122 /* 3 <= shCount <= 7, optimize */
7124 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7125 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7126 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7130 /*-----------------------------------------------------------------*/
7131 /* genLeftShiftLiteral - left shifting by known count */
7132 /*-----------------------------------------------------------------*/
7133 static void genLeftShiftLiteral (operand *left,
7138 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7142 freeAsmop(right,NULL,ic,TRUE);
7144 aopOp(left,ic,FALSE);
7145 aopOp(result,ic,FALSE);
7147 size = getSize(operandType(result));
7150 pic14_emitcode("; shift left ","result %d, left %d",size,
7154 /* I suppose that the left size >= result size */
7157 movLeft2Result(left, size, result, size);
7161 else if(shCount >= (size * 8))
7163 aopPut(AOP(result),zero,size);
7167 genlshOne (result,left,shCount);
7172 genlshTwo (result,left,shCount);
7176 genlshFour (result,left,shCount);
7180 freeAsmop(left,NULL,ic,TRUE);
7181 freeAsmop(result,NULL,ic,TRUE);
7184 /*-----------------------------------------------------------------*
7185 * genMultiAsm - repeat assembly instruction for size of register.
7186 * if endian == 1, then the high byte (i.e base address + size of
7187 * register) is used first else the low byte is used first;
7188 *-----------------------------------------------------------------*/
7189 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7194 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7207 emitpcode(poc, popGet(AOP(reg),offset));
7212 /*-----------------------------------------------------------------*/
7213 /* genLeftShift - generates code for left shifting */
7214 /*-----------------------------------------------------------------*/
7215 static void genLeftShift (iCode *ic)
7217 operand *left,*right, *result;
7220 symbol *tlbl , *tlbl1;
7223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7225 right = IC_RIGHT(ic);
7227 result = IC_RESULT(ic);
7229 aopOp(right,ic,FALSE);
7231 /* if the shift count is known then do it
7232 as efficiently as possible */
7233 if (AOP_TYPE(right) == AOP_LIT) {
7234 genLeftShiftLiteral (left,right,result,ic);
7238 /* shift count is unknown then we have to form
7239 a loop get the loop count in B : Note: we take
7240 only the lower order byte since shifting
7241 more that 32 bits make no sense anyway, ( the
7242 largest size of an object can be only 32 bits ) */
7245 aopOp(left,ic,FALSE);
7246 aopOp(result,ic,FALSE);
7248 /* now move the left to the result if they are not the
7250 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7251 AOP_SIZE(result) > 1) {
7253 size = AOP_SIZE(result);
7256 l = aopGet(AOP(left),offset,FALSE,TRUE);
7257 if (*l == '@' && (IS_AOP_PREG(result))) {
7259 pic14_emitcode("mov","a,%s",l);
7260 aopPut(AOP(result),"a",offset);
7262 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7263 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7264 //aopPut(AOP(result),l,offset);
7270 size = AOP_SIZE(result);
7272 /* if it is only one byte then */
7274 if(optimized_for_speed) {
7275 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7276 emitpcode(POC_ANDLW, popGetLit(0xf0));
7277 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7278 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7279 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7280 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7281 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7282 emitpcode(POC_RLFW, popGet(AOP(result),0));
7283 emitpcode(POC_ANDLW, popGetLit(0xfe));
7284 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7285 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7286 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7289 tlbl = newiTempLabel(NULL);
7290 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7291 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7292 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7295 emitpcode(POC_COMFW, popGet(AOP(right),0));
7296 emitpcode(POC_RRF, popGet(AOP(result),0));
7297 emitpLabel(tlbl->key);
7298 emitpcode(POC_RLF, popGet(AOP(result),0));
7299 emitpcode(POC_ADDLW, popGetLit(1));
7301 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7306 if (pic14_sameRegs(AOP(left),AOP(result))) {
7308 tlbl = newiTempLabel(NULL);
7309 emitpcode(POC_COMFW, popGet(AOP(right),0));
7310 genMultiAsm(POC_RRF, result, size,1);
7311 emitpLabel(tlbl->key);
7312 genMultiAsm(POC_RLF, result, size,0);
7313 emitpcode(POC_ADDLW, popGetLit(1));
7315 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7319 //tlbl = newiTempLabel(NULL);
7321 //tlbl1 = newiTempLabel(NULL);
7323 //reAdjustPreg(AOP(result));
7325 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7326 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7327 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7329 //pic14_emitcode("add","a,acc");
7330 //aopPut(AOP(result),"a",offset++);
7332 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7334 // pic14_emitcode("rlc","a");
7335 // aopPut(AOP(result),"a",offset++);
7337 //reAdjustPreg(AOP(result));
7339 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7340 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7343 tlbl = newiTempLabel(NULL);
7344 tlbl1= newiTempLabel(NULL);
7346 size = AOP_SIZE(result);
7349 pctemp = popGetTempReg(); /* grab a temporary working register. */
7351 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7353 /* offset should be 0, 1 or 3 */
7354 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7356 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7358 emitpcode(POC_MOVWF, pctemp);
7361 emitpLabel(tlbl->key);
7364 emitpcode(POC_RLF, popGet(AOP(result),0));
7366 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7368 emitpcode(POC_DECFSZ, pctemp);
7369 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7370 emitpLabel(tlbl1->key);
7372 popReleaseTempReg(pctemp);
7376 freeAsmop (right,NULL,ic,TRUE);
7377 freeAsmop(left,NULL,ic,TRUE);
7378 freeAsmop(result,NULL,ic,TRUE);
7381 /*-----------------------------------------------------------------*/
7382 /* genrshOne - right shift a one byte quantity by known count */
7383 /*-----------------------------------------------------------------*/
7384 static void genrshOne (operand *result, operand *left,
7385 int shCount, int sign)
7387 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7388 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7391 /*-----------------------------------------------------------------*/
7392 /* genrshTwo - right shift two bytes by known amount != 0 */
7393 /*-----------------------------------------------------------------*/
7394 static void genrshTwo (operand *result,operand *left,
7395 int shCount, int sign)
7397 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7398 /* if shCount >= 8 */
7402 shiftR1Left2Result(left, MSB16, result, LSB,
7405 movLeft2Result(left, MSB16, result, LSB);
7407 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7410 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7411 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7415 /* 1 <= shCount <= 7 */
7417 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7420 /*-----------------------------------------------------------------*/
7421 /* shiftRLong - shift right one long from left to result */
7422 /* offl = LSB or MSB16 */
7423 /*-----------------------------------------------------------------*/
7424 static void shiftRLong (operand *left, int offl,
7425 operand *result, int sign)
7427 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7429 pic14_emitcode("clr","c");
7430 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7432 pic14_emitcode("mov","c,acc.7");
7433 pic14_emitcode("rrc","a");
7434 aopPut(AOP(result),"a",MSB32-offl);
7436 /* add sign of "a" */
7437 addSign(result, MSB32, sign);
7439 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7440 pic14_emitcode("rrc","a");
7441 aopPut(AOP(result),"a",MSB24-offl);
7443 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7444 pic14_emitcode("rrc","a");
7445 aopPut(AOP(result),"a",MSB16-offl);
7448 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7449 pic14_emitcode("rrc","a");
7450 aopPut(AOP(result),"a",LSB);
7454 /*-----------------------------------------------------------------*/
7455 /* genrshFour - shift four byte by a known amount != 0 */
7456 /*-----------------------------------------------------------------*/
7457 static void genrshFour (operand *result, operand *left,
7458 int shCount, int sign)
7460 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7461 /* if shifting more that 3 bytes */
7462 if(shCount >= 24 ) {
7465 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7467 movLeft2Result(left, MSB32, result, LSB);
7469 addSign(result, MSB16, sign);
7471 else if(shCount >= 16){
7474 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7476 movLeft2Result(left, MSB24, result, LSB);
7477 movLeft2Result(left, MSB32, result, MSB16);
7479 addSign(result, MSB24, sign);
7481 else if(shCount >= 8){
7484 shiftRLong(left, MSB16, result, sign);
7485 else if(shCount == 0){
7486 movLeft2Result(left, MSB16, result, LSB);
7487 movLeft2Result(left, MSB24, result, MSB16);
7488 movLeft2Result(left, MSB32, result, MSB24);
7489 addSign(result, MSB32, sign);
7492 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7493 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7494 /* the last shift is signed */
7495 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7496 addSign(result, MSB32, sign);
7499 else{ /* 1 <= shCount <= 7 */
7501 shiftRLong(left, LSB, result, sign);
7503 shiftRLong(result, LSB, result, sign);
7506 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7507 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7508 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7513 /*-----------------------------------------------------------------*/
7514 /* genRightShiftLiteral - right shifting by known count */
7515 /*-----------------------------------------------------------------*/
7516 static void genRightShiftLiteral (operand *left,
7522 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7525 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7526 freeAsmop(right,NULL,ic,TRUE);
7528 aopOp(left,ic,FALSE);
7529 aopOp(result,ic,FALSE);
7532 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7536 lsize = pic14_getDataSize(left);
7537 res_size = pic14_getDataSize(result);
7538 /* test the LEFT size !!! */
7540 /* I suppose that the left size >= result size */
7543 movLeft2Result(left, lsize, result, res_size);
7546 else if(shCount >= (lsize * 8)){
7549 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7551 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7552 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7557 emitpcode(POC_MOVLW, popGetLit(0));
7558 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7559 emitpcode(POC_MOVLW, popGetLit(0xff));
7561 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7566 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7573 genrshOne (result,left,shCount,sign);
7577 genrshTwo (result,left,shCount,sign);
7581 genrshFour (result,left,shCount,sign);
7589 freeAsmop(left,NULL,ic,TRUE);
7590 freeAsmop(result,NULL,ic,TRUE);
7593 /*-----------------------------------------------------------------*/
7594 /* genSignedRightShift - right shift of signed number */
7595 /*-----------------------------------------------------------------*/
7596 static void genSignedRightShift (iCode *ic)
7598 operand *right, *left, *result;
7601 symbol *tlbl, *tlbl1 ;
7604 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7606 /* we do it the hard way put the shift count in b
7607 and loop thru preserving the sign */
7608 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7610 right = IC_RIGHT(ic);
7612 result = IC_RESULT(ic);
7614 aopOp(right,ic,FALSE);
7615 aopOp(left,ic,FALSE);
7616 aopOp(result,ic,FALSE);
7619 if ( AOP_TYPE(right) == AOP_LIT) {
7620 genRightShiftLiteral (left,right,result,ic,1);
7623 /* shift count is unknown then we have to form
7624 a loop get the loop count in B : Note: we take
7625 only the lower order byte since shifting
7626 more that 32 bits make no sense anyway, ( the
7627 largest size of an object can be only 32 bits ) */
7629 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7630 //pic14_emitcode("inc","b");
7631 //freeAsmop (right,NULL,ic,TRUE);
7632 //aopOp(left,ic,FALSE);
7633 //aopOp(result,ic,FALSE);
7635 /* now move the left to the result if they are not the
7637 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7638 AOP_SIZE(result) > 1) {
7640 size = AOP_SIZE(result);
7644 l = aopGet(AOP(left),offset,FALSE,TRUE);
7645 if (*l == '@' && IS_AOP_PREG(result)) {
7647 pic14_emitcode("mov","a,%s",l);
7648 aopPut(AOP(result),"a",offset);
7650 aopPut(AOP(result),l,offset);
7652 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7653 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7659 /* mov the highest order bit to OVR */
7660 tlbl = newiTempLabel(NULL);
7661 tlbl1= newiTempLabel(NULL);
7663 size = AOP_SIZE(result);
7666 pctemp = popGetTempReg(); /* grab a temporary working register. */
7668 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7670 /* offset should be 0, 1 or 3 */
7671 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7673 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7675 emitpcode(POC_MOVWF, pctemp);
7678 emitpLabel(tlbl->key);
7680 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7681 emitpcode(POC_RRF, popGet(AOP(result),offset));
7684 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7687 emitpcode(POC_DECFSZ, pctemp);
7688 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7689 emitpLabel(tlbl1->key);
7691 popReleaseTempReg(pctemp);
7693 size = AOP_SIZE(result);
7695 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7696 pic14_emitcode("rlc","a");
7697 pic14_emitcode("mov","ov,c");
7698 /* if it is only one byte then */
7700 l = aopGet(AOP(left),0,FALSE,FALSE);
7702 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7703 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7704 pic14_emitcode("mov","c,ov");
7705 pic14_emitcode("rrc","a");
7706 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7707 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7708 aopPut(AOP(result),"a",0);
7712 reAdjustPreg(AOP(result));
7713 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7714 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7715 pic14_emitcode("mov","c,ov");
7717 l = aopGet(AOP(result),offset,FALSE,FALSE);
7719 pic14_emitcode("rrc","a");
7720 aopPut(AOP(result),"a",offset--);
7722 reAdjustPreg(AOP(result));
7723 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7724 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7729 freeAsmop(left,NULL,ic,TRUE);
7730 freeAsmop(result,NULL,ic,TRUE);
7731 freeAsmop(right,NULL,ic,TRUE);
7734 /*-----------------------------------------------------------------*/
7735 /* genRightShift - generate code for right shifting */
7736 /*-----------------------------------------------------------------*/
7737 static void genRightShift (iCode *ic)
7739 operand *right, *left, *result;
7743 symbol *tlbl, *tlbl1 ;
7745 /* if signed then we do it the hard way preserve the
7746 sign bit moving it inwards */
7747 retype = getSpec(operandType(IC_RESULT(ic)));
7748 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7750 if (!SPEC_USIGN(retype)) {
7751 genSignedRightShift (ic);
7755 /* signed & unsigned types are treated the same : i.e. the
7756 signed is NOT propagated inwards : quoting from the
7757 ANSI - standard : "for E1 >> E2, is equivalent to division
7758 by 2**E2 if unsigned or if it has a non-negative value,
7759 otherwise the result is implementation defined ", MY definition
7760 is that the sign does not get propagated */
7762 right = IC_RIGHT(ic);
7764 result = IC_RESULT(ic);
7766 aopOp(right,ic,FALSE);
7768 /* if the shift count is known then do it
7769 as efficiently as possible */
7770 if (AOP_TYPE(right) == AOP_LIT) {
7771 genRightShiftLiteral (left,right,result,ic, 0);
7775 /* shift count is unknown then we have to form
7776 a loop get the loop count in B : Note: we take
7777 only the lower order byte since shifting
7778 more that 32 bits make no sense anyway, ( the
7779 largest size of an object can be only 32 bits ) */
7781 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7782 pic14_emitcode("inc","b");
7783 aopOp(left,ic,FALSE);
7784 aopOp(result,ic,FALSE);
7786 /* now move the left to the result if they are not the
7788 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7789 AOP_SIZE(result) > 1) {
7791 size = AOP_SIZE(result);
7794 l = aopGet(AOP(left),offset,FALSE,TRUE);
7795 if (*l == '@' && IS_AOP_PREG(result)) {
7797 pic14_emitcode("mov","a,%s",l);
7798 aopPut(AOP(result),"a",offset);
7800 aopPut(AOP(result),l,offset);
7805 tlbl = newiTempLabel(NULL);
7806 tlbl1= newiTempLabel(NULL);
7807 size = AOP_SIZE(result);
7810 /* if it is only one byte then */
7813 tlbl = newiTempLabel(NULL);
7814 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7815 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7816 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7819 emitpcode(POC_COMFW, popGet(AOP(right),0));
7820 emitpcode(POC_RLF, popGet(AOP(result),0));
7821 emitpLabel(tlbl->key);
7822 emitpcode(POC_RRF, popGet(AOP(result),0));
7823 emitpcode(POC_ADDLW, popGetLit(1));
7825 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7830 reAdjustPreg(AOP(result));
7831 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7832 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7835 l = aopGet(AOP(result),offset,FALSE,FALSE);
7837 pic14_emitcode("rrc","a");
7838 aopPut(AOP(result),"a",offset--);
7840 reAdjustPreg(AOP(result));
7842 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7843 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7846 freeAsmop(left,NULL,ic,TRUE);
7847 freeAsmop (right,NULL,ic,TRUE);
7848 freeAsmop(result,NULL,ic,TRUE);
7851 /*-----------------------------------------------------------------*/
7852 /* genUnpackBits - generates code for unpacking bits */
7853 /*-----------------------------------------------------------------*/
7854 static void genUnpackBits (operand *result, char *rname, int ptype)
7861 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7862 etype = getSpec(operandType(result));
7864 /* read the first byte */
7869 pic14_emitcode("mov","a,@%s",rname);
7873 pic14_emitcode("movx","a,@%s",rname);
7877 pic14_emitcode("movx","a,@dptr");
7881 pic14_emitcode("clr","a");
7882 pic14_emitcode("movc","a","@a+dptr");
7886 pic14_emitcode("lcall","__gptrget");
7890 /* if we have bitdisplacement then it fits */
7891 /* into this byte completely or if length is */
7892 /* less than a byte */
7893 if ((shCnt = SPEC_BSTR(etype)) ||
7894 (SPEC_BLEN(etype) <= 8)) {
7896 /* shift right acc */
7899 pic14_emitcode("anl","a,#0x%02x",
7900 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7901 aopPut(AOP(result),"a",offset);
7905 /* bit field did not fit in a byte */
7906 rlen = SPEC_BLEN(etype) - 8;
7907 aopPut(AOP(result),"a",offset++);
7914 pic14_emitcode("inc","%s",rname);
7915 pic14_emitcode("mov","a,@%s",rname);
7919 pic14_emitcode("inc","%s",rname);
7920 pic14_emitcode("movx","a,@%s",rname);
7924 pic14_emitcode("inc","dptr");
7925 pic14_emitcode("movx","a,@dptr");
7929 pic14_emitcode("clr","a");
7930 pic14_emitcode("inc","dptr");
7931 pic14_emitcode("movc","a","@a+dptr");
7935 pic14_emitcode("inc","dptr");
7936 pic14_emitcode("lcall","__gptrget");
7941 /* if we are done */
7945 aopPut(AOP(result),"a",offset++);
7950 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7951 aopPut(AOP(result),"a",offset);
7958 /*-----------------------------------------------------------------*/
7959 /* genDataPointerGet - generates code when ptr offset is known */
7960 /*-----------------------------------------------------------------*/
7961 static void genDataPointerGet (operand *left,
7965 int size , offset = 0;
7968 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7971 /* optimization - most of the time, left and result are the same
7972 * address, but different types. for the pic code, we could omit
7976 aopOp(result,ic,TRUE);
7978 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7980 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7982 size = AOP_SIZE(result);
7985 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7989 freeAsmop(left,NULL,ic,TRUE);
7990 freeAsmop(result,NULL,ic,TRUE);
7993 /*-----------------------------------------------------------------*/
7994 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7995 /*-----------------------------------------------------------------*/
7996 static void genNearPointerGet (operand *left,
8001 //regs *preg = NULL ;
8003 sym_link *rtype, *retype;
8004 sym_link *ltype = operandType(left);
8007 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8009 rtype = operandType(result);
8010 retype= getSpec(rtype);
8012 aopOp(left,ic,FALSE);
8014 /* if left is rematerialisable and
8015 result is not bit variable type and
8016 the left is pointer to data space i.e
8017 lower 128 bytes of space */
8018 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8019 !IS_BITVAR(retype) &&
8020 DCL_TYPE(ltype) == POINTER) {
8021 //genDataPointerGet (left,result,ic);
8025 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8027 /* if the value is already in a pointer register
8028 then don't need anything more */
8029 if (!AOP_INPREG(AOP(left))) {
8030 /* otherwise get a free pointer register */
8031 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8034 preg = getFreePtr(ic,&aop,FALSE);
8035 pic14_emitcode("mov","%s,%s",
8037 aopGet(AOP(left),0,FALSE,TRUE));
8038 rname = preg->name ;
8042 rname = aopGet(AOP(left),0,FALSE,FALSE);
8044 aopOp (result,ic,FALSE);
8046 /* if bitfield then unpack the bits */
8047 if (IS_BITVAR(retype))
8048 genUnpackBits (result,rname,POINTER);
8050 /* we have can just get the values */
8051 int size = AOP_SIZE(result);
8054 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8056 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8057 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8059 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8060 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8062 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8066 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8068 pic14_emitcode("mov","a,@%s",rname);
8069 aopPut(AOP(result),"a",offset);
8071 sprintf(buffer,"@%s",rname);
8072 aopPut(AOP(result),buffer,offset);
8076 pic14_emitcode("inc","%s",rname);
8081 /* now some housekeeping stuff */
8083 /* we had to allocate for this iCode */
8084 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8085 freeAsmop(NULL,aop,ic,TRUE);
8087 /* we did not allocate which means left
8088 already in a pointer register, then
8089 if size > 0 && this could be used again
8090 we have to point it back to where it
8092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8093 if (AOP_SIZE(result) > 1 &&
8094 !OP_SYMBOL(left)->remat &&
8095 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8097 int size = AOP_SIZE(result) - 1;
8099 pic14_emitcode("dec","%s",rname);
8104 freeAsmop(left,NULL,ic,TRUE);
8105 freeAsmop(result,NULL,ic,TRUE);
8109 /*-----------------------------------------------------------------*/
8110 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8111 /*-----------------------------------------------------------------*/
8112 static void genPagedPointerGet (operand *left,
8119 sym_link *rtype, *retype;
8121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8123 rtype = operandType(result);
8124 retype= getSpec(rtype);
8126 aopOp(left,ic,FALSE);
8128 /* if the value is already in a pointer register
8129 then don't need anything more */
8130 if (!AOP_INPREG(AOP(left))) {
8131 /* otherwise get a free pointer register */
8133 preg = getFreePtr(ic,&aop,FALSE);
8134 pic14_emitcode("mov","%s,%s",
8136 aopGet(AOP(left),0,FALSE,TRUE));
8137 rname = preg->name ;
8139 rname = aopGet(AOP(left),0,FALSE,FALSE);
8141 freeAsmop(left,NULL,ic,TRUE);
8142 aopOp (result,ic,FALSE);
8144 /* if bitfield then unpack the bits */
8145 if (IS_BITVAR(retype))
8146 genUnpackBits (result,rname,PPOINTER);
8148 /* we have can just get the values */
8149 int size = AOP_SIZE(result);
8154 pic14_emitcode("movx","a,@%s",rname);
8155 aopPut(AOP(result),"a",offset);
8160 pic14_emitcode("inc","%s",rname);
8164 /* now some housekeeping stuff */
8166 /* we had to allocate for this iCode */
8167 freeAsmop(NULL,aop,ic,TRUE);
8169 /* we did not allocate which means left
8170 already in a pointer register, then
8171 if size > 0 && this could be used again
8172 we have to point it back to where it
8174 if (AOP_SIZE(result) > 1 &&
8175 !OP_SYMBOL(left)->remat &&
8176 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8178 int size = AOP_SIZE(result) - 1;
8180 pic14_emitcode("dec","%s",rname);
8185 freeAsmop(result,NULL,ic,TRUE);
8190 /*-----------------------------------------------------------------*/
8191 /* genFarPointerGet - gget value from far space */
8192 /*-----------------------------------------------------------------*/
8193 static void genFarPointerGet (operand *left,
8194 operand *result, iCode *ic)
8197 sym_link *retype = getSpec(operandType(result));
8199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8201 aopOp(left,ic,FALSE);
8203 /* if the operand is already in dptr
8204 then we do nothing else we move the value to dptr */
8205 if (AOP_TYPE(left) != AOP_STR) {
8206 /* if this is remateriazable */
8207 if (AOP_TYPE(left) == AOP_IMMD)
8208 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8209 else { /* we need to get it byte by byte */
8210 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8211 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8212 if (options.model == MODEL_FLAT24)
8214 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8218 /* so dptr know contains the address */
8219 freeAsmop(left,NULL,ic,TRUE);
8220 aopOp(result,ic,FALSE);
8222 /* if bit then unpack */
8223 if (IS_BITVAR(retype))
8224 genUnpackBits(result,"dptr",FPOINTER);
8226 size = AOP_SIZE(result);
8230 pic14_emitcode("movx","a,@dptr");
8231 aopPut(AOP(result),"a",offset++);
8233 pic14_emitcode("inc","dptr");
8237 freeAsmop(result,NULL,ic,TRUE);
8240 /*-----------------------------------------------------------------*/
8241 /* genCodePointerGet - get value from code space */
8242 /*-----------------------------------------------------------------*/
8243 static void genCodePointerGet (operand *left,
8244 operand *result, iCode *ic)
8247 sym_link *retype = getSpec(operandType(result));
8249 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8251 aopOp(left,ic,FALSE);
8253 /* if the operand is already in dptr
8254 then we do nothing else we move the value to dptr */
8255 if (AOP_TYPE(left) != AOP_STR) {
8256 /* if this is remateriazable */
8257 if (AOP_TYPE(left) == AOP_IMMD)
8258 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8259 else { /* we need to get it byte by byte */
8260 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8261 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8262 if (options.model == MODEL_FLAT24)
8264 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8268 /* so dptr know contains the address */
8269 freeAsmop(left,NULL,ic,TRUE);
8270 aopOp(result,ic,FALSE);
8272 /* if bit then unpack */
8273 if (IS_BITVAR(retype))
8274 genUnpackBits(result,"dptr",CPOINTER);
8276 size = AOP_SIZE(result);
8280 pic14_emitcode("clr","a");
8281 pic14_emitcode("movc","a,@a+dptr");
8282 aopPut(AOP(result),"a",offset++);
8284 pic14_emitcode("inc","dptr");
8288 freeAsmop(result,NULL,ic,TRUE);
8291 /*-----------------------------------------------------------------*/
8292 /* genGenPointerGet - gget value from generic pointer space */
8293 /*-----------------------------------------------------------------*/
8294 static void genGenPointerGet (operand *left,
8295 operand *result, iCode *ic)
8298 sym_link *retype = getSpec(operandType(result));
8300 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8301 aopOp(left,ic,FALSE);
8302 aopOp(result,ic,FALSE);
8305 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8307 /* if the operand is already in dptr
8308 then we do nothing else we move the value to dptr */
8309 // if (AOP_TYPE(left) != AOP_STR) {
8310 /* if this is remateriazable */
8311 if (AOP_TYPE(left) == AOP_IMMD) {
8312 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8313 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8315 else { /* we need to get it byte by byte */
8317 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8318 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8320 size = AOP_SIZE(result);
8324 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8325 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8327 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8332 /* so dptr know contains the address */
8334 /* if bit then unpack */
8335 //if (IS_BITVAR(retype))
8336 // genUnpackBits(result,"dptr",GPOINTER);
8339 freeAsmop(left,NULL,ic,TRUE);
8340 freeAsmop(result,NULL,ic,TRUE);
8344 /*-----------------------------------------------------------------*/
8345 /* genConstPointerGet - get value from const generic pointer space */
8346 /*-----------------------------------------------------------------*/
8347 static void genConstPointerGet (operand *left,
8348 operand *result, iCode *ic)
8350 //sym_link *retype = getSpec(operandType(result));
8351 symbol *albl = newiTempLabel(NULL);
8352 symbol *blbl = newiTempLabel(NULL);
8355 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8356 aopOp(left,ic,FALSE);
8357 aopOp(result,ic,FALSE);
8360 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8362 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8364 emitpcode(POC_CALL,popGetLabel(albl->key));
8365 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8366 emitpLabel(albl->key);
8368 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8370 emitpcode(poc,popGet(AOP(left),1));
8371 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8372 emitpcode(poc,popGet(AOP(left),0));
8373 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8375 emitpLabel(blbl->key);
8377 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8380 freeAsmop(left,NULL,ic,TRUE);
8381 freeAsmop(result,NULL,ic,TRUE);
8384 /*-----------------------------------------------------------------*/
8385 /* genPointerGet - generate code for pointer get */
8386 /*-----------------------------------------------------------------*/
8387 static void genPointerGet (iCode *ic)
8389 operand *left, *result ;
8390 sym_link *type, *etype;
8393 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8396 result = IC_RESULT(ic) ;
8398 /* depending on the type of pointer we need to
8399 move it to the correct pointer register */
8400 type = operandType(left);
8401 etype = getSpec(type);
8403 if (IS_PTR_CONST(type))
8404 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8406 /* if left is of type of pointer then it is simple */
8407 if (IS_PTR(type) && !IS_FUNC(type->next))
8408 p_type = DCL_TYPE(type);
8410 /* we have to go by the storage class */
8411 p_type = PTR_TYPE(SPEC_OCLS(etype));
8413 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8415 if (SPEC_OCLS(etype)->codesp ) {
8416 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8417 //p_type = CPOINTER ;
8420 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8421 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8422 /*p_type = FPOINTER ;*/
8424 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8425 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8426 /* p_type = PPOINTER; */
8428 if (SPEC_OCLS(etype) == idata )
8429 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8430 /* p_type = IPOINTER; */
8432 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8433 /* p_type = POINTER ; */
8436 /* now that we have the pointer type we assign
8437 the pointer values */
8442 genNearPointerGet (left,result,ic);
8446 genPagedPointerGet(left,result,ic);
8450 genFarPointerGet (left,result,ic);
8454 genConstPointerGet (left,result,ic);
8455 //pic14_emitcodePointerGet (left,result,ic);
8459 if (IS_PTR_CONST(type))
8460 genConstPointerGet (left,result,ic);
8462 genGenPointerGet (left,result,ic);
8468 /*-----------------------------------------------------------------*/
8469 /* genPackBits - generates code for packed bit storage */
8470 /*-----------------------------------------------------------------*/
8471 static void genPackBits (sym_link *etype ,
8473 char *rname, int p_type)
8481 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8482 blen = SPEC_BLEN(etype);
8483 bstr = SPEC_BSTR(etype);
8485 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8488 /* if the bit lenth is less than or */
8489 /* it exactly fits a byte then */
8490 if (SPEC_BLEN(etype) <= 8 ) {
8491 shCount = SPEC_BSTR(etype) ;
8493 /* shift left acc */
8496 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8501 pic14_emitcode ("mov","b,a");
8502 pic14_emitcode("mov","a,@%s",rname);
8506 pic14_emitcode ("mov","b,a");
8507 pic14_emitcode("movx","a,@dptr");
8511 pic14_emitcode ("push","b");
8512 pic14_emitcode ("push","acc");
8513 pic14_emitcode ("lcall","__gptrget");
8514 pic14_emitcode ("pop","b");
8518 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8519 ((unsigned char)(0xFF << (blen+bstr)) |
8520 (unsigned char)(0xFF >> (8-bstr)) ) );
8521 pic14_emitcode ("orl","a,b");
8522 if (p_type == GPOINTER)
8523 pic14_emitcode("pop","b");
8529 pic14_emitcode("mov","@%s,a",rname);
8533 pic14_emitcode("movx","@dptr,a");
8537 DEBUGpic14_emitcode(";lcall","__gptrput");
8542 if ( SPEC_BLEN(etype) <= 8 )
8545 pic14_emitcode("inc","%s",rname);
8546 rLen = SPEC_BLEN(etype) ;
8548 /* now generate for lengths greater than one byte */
8551 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8561 pic14_emitcode("mov","@%s,a",rname);
8563 pic14_emitcode("mov","@%s,%s",rname,l);
8568 pic14_emitcode("movx","@dptr,a");
8573 DEBUGpic14_emitcode(";lcall","__gptrput");
8576 pic14_emitcode ("inc","%s",rname);
8581 /* last last was not complete */
8583 /* save the byte & read byte */
8586 pic14_emitcode ("mov","b,a");
8587 pic14_emitcode("mov","a,@%s",rname);
8591 pic14_emitcode ("mov","b,a");
8592 pic14_emitcode("movx","a,@dptr");
8596 pic14_emitcode ("push","b");
8597 pic14_emitcode ("push","acc");
8598 pic14_emitcode ("lcall","__gptrget");
8599 pic14_emitcode ("pop","b");
8603 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8604 pic14_emitcode ("orl","a,b");
8607 if (p_type == GPOINTER)
8608 pic14_emitcode("pop","b");
8613 pic14_emitcode("mov","@%s,a",rname);
8617 pic14_emitcode("movx","@dptr,a");
8621 DEBUGpic14_emitcode(";lcall","__gptrput");
8625 /*-----------------------------------------------------------------*/
8626 /* genDataPointerSet - remat pointer to data space */
8627 /*-----------------------------------------------------------------*/
8628 static void genDataPointerSet(operand *right,
8632 int size, offset = 0 ;
8633 char *l, buffer[256];
8635 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8636 aopOp(right,ic,FALSE);
8638 l = aopGet(AOP(result),0,FALSE,TRUE);
8639 size = AOP_SIZE(right);
8641 if ( AOP_TYPE(result) == AOP_PCODE) {
8642 fprintf(stderr,"genDataPointerSet %s, %d\n",
8643 AOP(result)->aopu.pcop->name,
8644 PCOI(AOP(result)->aopu.pcop)->offset);
8648 // tsd, was l+1 - the underline `_' prefix was being stripped
8651 sprintf(buffer,"(%s + %d)",l,offset);
8652 fprintf(stderr,"oops %s\n",buffer);
8654 sprintf(buffer,"%s",l);
8656 if (AOP_TYPE(right) == AOP_LIT) {
8657 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8658 lit = lit >> (8*offset);
8660 pic14_emitcode("movlw","%d",lit);
8661 pic14_emitcode("movwf","%s",buffer);
8663 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8664 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8665 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8668 pic14_emitcode("clrf","%s",buffer);
8669 //emitpcode(POC_CLRF, popRegFromString(buffer));
8670 emitpcode(POC_CLRF, popGet(AOP(result),0));
8673 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8674 pic14_emitcode("movwf","%s",buffer);
8676 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8677 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8678 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8685 freeAsmop(right,NULL,ic,TRUE);
8686 freeAsmop(result,NULL,ic,TRUE);
8689 /*-----------------------------------------------------------------*/
8690 /* genNearPointerSet - pic14_emitcode for near pointer put */
8691 /*-----------------------------------------------------------------*/
8692 static void genNearPointerSet (operand *right,
8699 sym_link *ptype = operandType(result);
8702 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8703 retype= getSpec(operandType(right));
8705 aopOp(result,ic,FALSE);
8708 /* if the result is rematerializable &
8709 in data space & not a bit variable */
8710 //if (AOP_TYPE(result) == AOP_IMMD &&
8711 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8712 DCL_TYPE(ptype) == POINTER &&
8713 !IS_BITVAR(retype)) {
8714 genDataPointerSet (right,result,ic);
8715 freeAsmop(result,NULL,ic,TRUE);
8719 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8720 aopOp(right,ic,FALSE);
8721 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8723 /* if the value is already in a pointer register
8724 then don't need anything more */
8725 if (!AOP_INPREG(AOP(result))) {
8726 /* otherwise get a free pointer register */
8727 //aop = newAsmop(0);
8728 //preg = getFreePtr(ic,&aop,FALSE);
8729 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8730 //pic14_emitcode("mov","%s,%s",
8732 // aopGet(AOP(result),0,FALSE,TRUE));
8733 //rname = preg->name ;
8734 //pic14_emitcode("movwf","fsr");
8735 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8736 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8737 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8738 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8742 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8745 /* if bitfield then unpack the bits */
8746 if (IS_BITVAR(retype)) {
8747 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8748 "The programmer is obviously confused");
8749 //genPackBits (retype,right,rname,POINTER);
8753 /* we have can just get the values */
8754 int size = AOP_SIZE(right);
8757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8759 l = aopGet(AOP(right),offset,FALSE,TRUE);
8762 //pic14_emitcode("mov","@%s,a",rname);
8763 pic14_emitcode("movf","indf,w ;1");
8766 if (AOP_TYPE(right) == AOP_LIT) {
8767 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8769 pic14_emitcode("movlw","%s",l);
8770 pic14_emitcode("movwf","indf ;2");
8772 pic14_emitcode("clrf","indf");
8774 pic14_emitcode("movf","%s,w",l);
8775 pic14_emitcode("movwf","indf ;2");
8777 //pic14_emitcode("mov","@%s,%s",rname,l);
8780 pic14_emitcode("incf","fsr,f ;3");
8781 //pic14_emitcode("inc","%s",rname);
8786 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8787 /* now some housekeeping stuff */
8789 /* we had to allocate for this iCode */
8790 freeAsmop(NULL,aop,ic,TRUE);
8792 /* we did not allocate which means left
8793 already in a pointer register, then
8794 if size > 0 && this could be used again
8795 we have to point it back to where it
8797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8798 if (AOP_SIZE(right) > 1 &&
8799 !OP_SYMBOL(result)->remat &&
8800 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8802 int size = AOP_SIZE(right) - 1;
8804 pic14_emitcode("decf","fsr,f");
8805 //pic14_emitcode("dec","%s",rname);
8809 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8812 freeAsmop(right,NULL,ic,TRUE);
8813 freeAsmop(result,NULL,ic,TRUE);
8816 /*-----------------------------------------------------------------*/
8817 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8818 /*-----------------------------------------------------------------*/
8819 static void genPagedPointerSet (operand *right,
8828 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8830 retype= getSpec(operandType(right));
8832 aopOp(result,ic,FALSE);
8834 /* if the value is already in a pointer register
8835 then don't need anything more */
8836 if (!AOP_INPREG(AOP(result))) {
8837 /* otherwise get a free pointer register */
8839 preg = getFreePtr(ic,&aop,FALSE);
8840 pic14_emitcode("mov","%s,%s",
8842 aopGet(AOP(result),0,FALSE,TRUE));
8843 rname = preg->name ;
8845 rname = aopGet(AOP(result),0,FALSE,FALSE);
8847 freeAsmop(result,NULL,ic,TRUE);
8848 aopOp (right,ic,FALSE);
8850 /* if bitfield then unpack the bits */
8851 if (IS_BITVAR(retype))
8852 genPackBits (retype,right,rname,PPOINTER);
8854 /* we have can just get the values */
8855 int size = AOP_SIZE(right);
8859 l = aopGet(AOP(right),offset,FALSE,TRUE);
8862 pic14_emitcode("movx","@%s,a",rname);
8865 pic14_emitcode("inc","%s",rname);
8871 /* now some housekeeping stuff */
8873 /* we had to allocate for this iCode */
8874 freeAsmop(NULL,aop,ic,TRUE);
8876 /* we did not allocate which means left
8877 already in a pointer register, then
8878 if size > 0 && this could be used again
8879 we have to point it back to where it
8881 if (AOP_SIZE(right) > 1 &&
8882 !OP_SYMBOL(result)->remat &&
8883 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8885 int size = AOP_SIZE(right) - 1;
8887 pic14_emitcode("dec","%s",rname);
8892 freeAsmop(right,NULL,ic,TRUE);
8897 /*-----------------------------------------------------------------*/
8898 /* genFarPointerSet - set value from far space */
8899 /*-----------------------------------------------------------------*/
8900 static void genFarPointerSet (operand *right,
8901 operand *result, iCode *ic)
8904 sym_link *retype = getSpec(operandType(right));
8906 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8907 aopOp(result,ic,FALSE);
8909 /* if the operand is already in dptr
8910 then we do nothing else we move the value to dptr */
8911 if (AOP_TYPE(result) != AOP_STR) {
8912 /* if this is remateriazable */
8913 if (AOP_TYPE(result) == AOP_IMMD)
8914 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8915 else { /* we need to get it byte by byte */
8916 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8917 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8918 if (options.model == MODEL_FLAT24)
8920 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8924 /* so dptr know contains the address */
8925 freeAsmop(result,NULL,ic,TRUE);
8926 aopOp(right,ic,FALSE);
8928 /* if bit then unpack */
8929 if (IS_BITVAR(retype))
8930 genPackBits(retype,right,"dptr",FPOINTER);
8932 size = AOP_SIZE(right);
8936 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8938 pic14_emitcode("movx","@dptr,a");
8940 pic14_emitcode("inc","dptr");
8944 freeAsmop(right,NULL,ic,TRUE);
8947 /*-----------------------------------------------------------------*/
8948 /* genGenPointerSet - set value from generic pointer space */
8949 /*-----------------------------------------------------------------*/
8950 static void genGenPointerSet (operand *right,
8951 operand *result, iCode *ic)
8954 sym_link *retype = getSpec(operandType(right));
8956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8958 aopOp(result,ic,FALSE);
8959 aopOp(right,ic,FALSE);
8960 size = AOP_SIZE(right);
8962 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8964 /* if the operand is already in dptr
8965 then we do nothing else we move the value to dptr */
8966 if (AOP_TYPE(result) != AOP_STR) {
8967 /* if this is remateriazable */
8968 if (AOP_TYPE(result) == AOP_IMMD) {
8969 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8970 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8972 else { /* we need to get it byte by byte */
8973 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8974 size = AOP_SIZE(right);
8977 /* hack hack! see if this the FSR. If so don't load W */
8978 if(AOP_TYPE(right) != AOP_ACC) {
8981 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8982 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8984 if(AOP_SIZE(result) > 1) {
8985 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8986 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8987 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8992 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8994 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8995 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8999 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9000 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9003 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9010 if(aopIdx(AOP(result),0) != 4) {
9012 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9016 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9021 /* so dptr know contains the address */
9024 /* if bit then unpack */
9025 if (IS_BITVAR(retype))
9026 genPackBits(retype,right,"dptr",GPOINTER);
9028 size = AOP_SIZE(right);
9031 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9035 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9036 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9038 if (AOP_TYPE(right) == AOP_LIT)
9039 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9041 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9043 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9050 freeAsmop(right,NULL,ic,TRUE);
9051 freeAsmop(result,NULL,ic,TRUE);
9054 /*-----------------------------------------------------------------*/
9055 /* genPointerSet - stores the value into a pointer location */
9056 /*-----------------------------------------------------------------*/
9057 static void genPointerSet (iCode *ic)
9059 operand *right, *result ;
9060 sym_link *type, *etype;
9063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9065 right = IC_RIGHT(ic);
9066 result = IC_RESULT(ic) ;
9068 /* depending on the type of pointer we need to
9069 move it to the correct pointer register */
9070 type = operandType(result);
9071 etype = getSpec(type);
9072 /* if left is of type of pointer then it is simple */
9073 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9074 p_type = DCL_TYPE(type);
9077 /* we have to go by the storage class */
9078 p_type = PTR_TYPE(SPEC_OCLS(etype));
9080 /* if (SPEC_OCLS(etype)->codesp ) { */
9081 /* p_type = CPOINTER ; */
9084 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9085 /* p_type = FPOINTER ; */
9087 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9088 /* p_type = PPOINTER ; */
9090 /* if (SPEC_OCLS(etype) == idata ) */
9091 /* p_type = IPOINTER ; */
9093 /* p_type = POINTER ; */
9096 /* now that we have the pointer type we assign
9097 the pointer values */
9102 genNearPointerSet (right,result,ic);
9106 genPagedPointerSet (right,result,ic);
9110 genFarPointerSet (right,result,ic);
9114 genGenPointerSet (right,result,ic);
9118 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9119 "genPointerSet: illegal pointer type");
9123 /*-----------------------------------------------------------------*/
9124 /* genIfx - generate code for Ifx statement */
9125 /*-----------------------------------------------------------------*/
9126 static void genIfx (iCode *ic, iCode *popIc)
9128 operand *cond = IC_COND(ic);
9131 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9133 aopOp(cond,ic,FALSE);
9135 /* get the value into acc */
9136 if (AOP_TYPE(cond) != AOP_CRY)
9137 pic14_toBoolean(cond);
9140 /* the result is now in the accumulator */
9141 freeAsmop(cond,NULL,ic,TRUE);
9143 /* if there was something to be popped then do it */
9147 /* if the condition is a bit variable */
9148 if (isbit && IS_ITEMP(cond) &&
9150 genIfxJump(ic,SPIL_LOC(cond)->rname);
9151 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9154 if (isbit && !IS_ITEMP(cond))
9155 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9163 /*-----------------------------------------------------------------*/
9164 /* genAddrOf - generates code for address of */
9165 /*-----------------------------------------------------------------*/
9166 static void genAddrOf (iCode *ic)
9168 operand *right, *result, *left;
9171 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9174 //aopOp(IC_RESULT(ic),ic,FALSE);
9176 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9177 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9178 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9180 DEBUGpic14_AopType(__LINE__,left,right,result);
9182 size = AOP_SIZE(IC_RESULT(ic));
9186 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9187 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9191 freeAsmop(left,NULL,ic,FALSE);
9192 freeAsmop(result,NULL,ic,TRUE);
9197 /*-----------------------------------------------------------------*/
9198 /* genFarFarAssign - assignment when both are in far space */
9199 /*-----------------------------------------------------------------*/
9200 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9202 int size = AOP_SIZE(right);
9205 /* first push the right side on to the stack */
9207 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9209 pic14_emitcode ("push","acc");
9212 freeAsmop(right,NULL,ic,FALSE);
9213 /* now assign DPTR to result */
9214 aopOp(result,ic,FALSE);
9215 size = AOP_SIZE(result);
9217 pic14_emitcode ("pop","acc");
9218 aopPut(AOP(result),"a",--offset);
9220 freeAsmop(result,NULL,ic,FALSE);
9225 /*-----------------------------------------------------------------*/
9226 /* genAssign - generate code for assignment */
9227 /*-----------------------------------------------------------------*/
9228 static void genAssign (iCode *ic)
9230 operand *result, *right;
9231 int size, offset,know_W;
9232 unsigned long lit = 0L;
9234 result = IC_RESULT(ic);
9235 right = IC_RIGHT(ic) ;
9237 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9239 /* if they are the same */
9240 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9243 aopOp(right,ic,FALSE);
9244 aopOp(result,ic,TRUE);
9246 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9248 /* if they are the same registers */
9249 if (pic14_sameRegs(AOP(right),AOP(result)))
9252 /* if the result is a bit */
9253 if (AOP_TYPE(result) == AOP_CRY) {
9255 /* if the right size is a literal then
9256 we know what the value is */
9257 if (AOP_TYPE(right) == AOP_LIT) {
9259 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9260 popGet(AOP(result),0));
9262 if (((int) operandLitValue(right)))
9263 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9264 AOP(result)->aopu.aop_dir,
9265 AOP(result)->aopu.aop_dir);
9267 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9268 AOP(result)->aopu.aop_dir,
9269 AOP(result)->aopu.aop_dir);
9273 /* the right is also a bit variable */
9274 if (AOP_TYPE(right) == AOP_CRY) {
9275 emitpcode(POC_BCF, popGet(AOP(result),0));
9276 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9277 emitpcode(POC_BSF, popGet(AOP(result),0));
9279 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9280 AOP(result)->aopu.aop_dir,
9281 AOP(result)->aopu.aop_dir);
9282 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9283 AOP(right)->aopu.aop_dir,
9284 AOP(right)->aopu.aop_dir);
9285 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9286 AOP(result)->aopu.aop_dir,
9287 AOP(result)->aopu.aop_dir);
9292 emitpcode(POC_BCF, popGet(AOP(result),0));
9293 pic14_toBoolean(right);
9295 emitpcode(POC_BSF, popGet(AOP(result),0));
9296 //aopPut(AOP(result),"a",0);
9300 /* bit variables done */
9302 size = AOP_SIZE(result);
9304 if(AOP_TYPE(right) == AOP_LIT)
9305 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9307 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9308 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9309 if(aopIdx(AOP(result),0) == 4) {
9310 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9311 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9312 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9315 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9320 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9321 if(AOP_TYPE(right) == AOP_LIT) {
9323 if(know_W != (lit&0xff))
9324 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9326 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9328 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9332 } else if (AOP_TYPE(right) == AOP_CRY) {
9333 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9335 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9336 emitpcode(POC_INCF, popGet(AOP(result),0));
9338 } else if (AOP_TYPE(right) == AOP_IMMD) {
9339 DEBUGpic14_emitcode ("; ***","%s %d AOP_IMMD",__FUNCTION__,__LINE__);
9340 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9341 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9343 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9344 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9345 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9353 freeAsmop (right,NULL,ic,FALSE);
9354 freeAsmop (result,NULL,ic,TRUE);
9357 /*-----------------------------------------------------------------*/
9358 /* genJumpTab - genrates code for jump table */
9359 /*-----------------------------------------------------------------*/
9360 static void genJumpTab (iCode *ic)
9365 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9367 aopOp(IC_JTCOND(ic),ic,FALSE);
9368 /* get the condition into accumulator */
9369 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9371 /* multiply by three */
9372 pic14_emitcode("add","a,acc");
9373 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9375 jtab = newiTempLabel(NULL);
9376 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9377 pic14_emitcode("jmp","@a+dptr");
9378 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9380 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9381 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9383 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9384 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9385 emitpLabel(jtab->key);
9387 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9389 /* now generate the jump labels */
9390 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9391 jtab = setNextItem(IC_JTLABELS(ic))) {
9392 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9393 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9399 /*-----------------------------------------------------------------*/
9400 /* genMixedOperation - gen code for operators between mixed types */
9401 /*-----------------------------------------------------------------*/
9403 TSD - Written for the PIC port - but this unfortunately is buggy.
9404 This routine is good in that it is able to efficiently promote
9405 types to different (larger) sizes. Unfortunately, the temporary
9406 variables that are optimized out by this routine are sometimes
9407 used in other places. So until I know how to really parse the
9408 iCode tree, I'm going to not be using this routine :(.
9410 static int genMixedOperation (iCode *ic)
9413 operand *result = IC_RESULT(ic);
9414 sym_link *ctype = operandType(IC_LEFT(ic));
9415 operand *right = IC_RIGHT(ic);
9421 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9423 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9429 nextright = IC_RIGHT(nextic);
9430 nextleft = IC_LEFT(nextic);
9431 nextresult = IC_RESULT(nextic);
9433 aopOp(right,ic,FALSE);
9434 aopOp(result,ic,FALSE);
9435 aopOp(nextright, nextic, FALSE);
9436 aopOp(nextleft, nextic, FALSE);
9437 aopOp(nextresult, nextic, FALSE);
9439 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9445 pic14_emitcode(";remove right +","");
9447 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9453 pic14_emitcode(";remove left +","");
9457 big = AOP_SIZE(nextleft);
9458 small = AOP_SIZE(nextright);
9460 switch(nextic->op) {
9463 pic14_emitcode(";optimize a +","");
9464 /* if unsigned or not an integral type */
9465 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9466 pic14_emitcode(";add a bit to something","");
9469 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9471 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9472 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9473 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9475 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9483 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9484 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9485 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9488 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9490 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9491 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9492 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9493 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9494 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9497 pic14_emitcode("rlf","known_zero,w");
9504 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9505 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9506 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9508 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9518 freeAsmop(right,NULL,ic,TRUE);
9519 freeAsmop(result,NULL,ic,TRUE);
9520 freeAsmop(nextright,NULL,ic,TRUE);
9521 freeAsmop(nextleft,NULL,ic,TRUE);
9523 nextic->generated = 1;
9530 /*-----------------------------------------------------------------*/
9531 /* genCast - gen code for casting */
9532 /*-----------------------------------------------------------------*/
9533 static void genCast (iCode *ic)
9535 operand *result = IC_RESULT(ic);
9536 sym_link *ctype = operandType(IC_LEFT(ic));
9537 sym_link *rtype = operandType(IC_RIGHT(ic));
9538 operand *right = IC_RIGHT(ic);
9541 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9542 /* if they are equivalent then do nothing */
9543 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9546 aopOp(right,ic,FALSE) ;
9547 aopOp(result,ic,FALSE);
9549 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9551 /* if the result is a bit */
9552 if (AOP_TYPE(result) == AOP_CRY) {
9553 /* if the right size is a literal then
9554 we know what the value is */
9555 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9556 if (AOP_TYPE(right) == AOP_LIT) {
9558 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9559 popGet(AOP(result),0));
9561 if (((int) operandLitValue(right)))
9562 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9563 AOP(result)->aopu.aop_dir,
9564 AOP(result)->aopu.aop_dir);
9566 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9567 AOP(result)->aopu.aop_dir,
9568 AOP(result)->aopu.aop_dir);
9573 /* the right is also a bit variable */
9574 if (AOP_TYPE(right) == AOP_CRY) {
9577 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9579 pic14_emitcode("clrc","");
9580 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9581 AOP(right)->aopu.aop_dir,
9582 AOP(right)->aopu.aop_dir);
9583 aopPut(AOP(result),"c",0);
9588 if (AOP_TYPE(right) == AOP_REG) {
9589 emitpcode(POC_BCF, popGet(AOP(result),0));
9590 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9591 emitpcode(POC_BSF, popGet(AOP(result),0));
9593 pic14_toBoolean(right);
9594 aopPut(AOP(result),"a",0);
9598 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9600 size = AOP_SIZE(result);
9602 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9604 emitpcode(POC_CLRF, popGet(AOP(result),0));
9605 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9606 emitpcode(POC_INCF, popGet(AOP(result),0));
9609 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9614 /* if they are the same size : or less */
9615 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9617 /* if they are in the same place */
9618 if (pic14_sameRegs(AOP(right),AOP(result)))
9621 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9622 if (IS_PTR_CONST(rtype))
9623 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9624 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9625 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9627 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9628 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9629 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9630 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9631 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9632 if(AOP_SIZE(result) <2)
9633 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9637 /* if they in different places then copy */
9638 size = AOP_SIZE(result);
9641 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9642 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9644 //aopPut(AOP(result),
9645 // aopGet(AOP(right),offset,FALSE,FALSE),
9655 /* if the result is of type pointer */
9656 if (IS_PTR(ctype)) {
9659 sym_link *type = operandType(right);
9660 sym_link *etype = getSpec(type);
9661 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9663 /* pointer to generic pointer */
9664 if (IS_GENPTR(ctype)) {
9668 p_type = DCL_TYPE(type);
9670 /* we have to go by the storage class */
9671 p_type = PTR_TYPE(SPEC_OCLS(etype));
9673 /* if (SPEC_OCLS(etype)->codesp ) */
9674 /* p_type = CPOINTER ; */
9676 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9677 /* p_type = FPOINTER ; */
9679 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9680 /* p_type = PPOINTER; */
9682 /* if (SPEC_OCLS(etype) == idata ) */
9683 /* p_type = IPOINTER ; */
9685 /* p_type = POINTER ; */
9688 /* the first two bytes are known */
9689 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9690 size = GPTRSIZE - 1;
9693 if(offset < AOP_SIZE(right)) {
9694 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9695 if ((AOP_TYPE(right) == AOP_PCODE) &&
9696 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9697 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9698 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9701 aopGet(AOP(right),offset,FALSE,FALSE),
9705 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9708 /* the last byte depending on type */
9712 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9715 pic14_emitcode(";BUG!? ","%d",__LINE__);
9719 pic14_emitcode(";BUG!? ","%d",__LINE__);
9723 pic14_emitcode(";BUG!? ","%d",__LINE__);
9728 /* this should never happen */
9729 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9730 "got unknown pointer type");
9733 //aopPut(AOP(result),l, GPTRSIZE - 1);
9737 /* just copy the pointers */
9738 size = AOP_SIZE(result);
9742 aopGet(AOP(right),offset,FALSE,FALSE),
9751 /* so we now know that the size of destination is greater
9752 than the size of the source.
9753 Now, if the next iCode is an operator then we might be
9754 able to optimize the operation without performing a cast.
9756 if(genMixedOperation(ic))
9759 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9761 /* we move to result for the size of source */
9762 size = AOP_SIZE(right);
9765 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9766 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9770 /* now depending on the sign of the destination */
9771 size = AOP_SIZE(result) - AOP_SIZE(right);
9772 /* if unsigned or not an integral type */
9773 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9775 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9777 /* we need to extend the sign :{ */
9780 /* Save one instruction of casting char to int */
9781 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9782 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9783 emitpcode(POC_DECF, popGet(AOP(result),offset));
9785 emitpcodeNULLop(POC_CLRW);
9788 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9790 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9792 emitpcode(POC_MOVLW, popGetLit(0xff));
9795 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9800 freeAsmop(right,NULL,ic,TRUE);
9801 freeAsmop(result,NULL,ic,TRUE);
9805 /*-----------------------------------------------------------------*/
9806 /* genDjnz - generate decrement & jump if not zero instrucion */
9807 /*-----------------------------------------------------------------*/
9808 static int genDjnz (iCode *ic, iCode *ifx)
9811 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9816 /* if the if condition has a false label
9817 then we cannot save */
9821 /* if the minus is not of the form
9823 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9824 !IS_OP_LITERAL(IC_RIGHT(ic)))
9827 if (operandLitValue(IC_RIGHT(ic)) != 1)
9830 /* if the size of this greater than one then no
9832 if (getSize(operandType(IC_RESULT(ic))) > 1)
9835 /* otherwise we can save BIG */
9836 lbl = newiTempLabel(NULL);
9837 lbl1= newiTempLabel(NULL);
9839 aopOp(IC_RESULT(ic),ic,FALSE);
9841 if (IS_AOP_PREG(IC_RESULT(ic))) {
9842 pic14_emitcode("dec","%s",
9843 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9844 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9845 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9849 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9850 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9852 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9853 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9856 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9857 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9858 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9859 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9862 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9867 /*-----------------------------------------------------------------*/
9868 /* genReceive - generate code for a receive iCode */
9869 /*-----------------------------------------------------------------*/
9870 static void genReceive (iCode *ic)
9872 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9874 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9875 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9876 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9878 int size = getSize(operandType(IC_RESULT(ic)));
9879 int offset = fReturnSizePic - size;
9881 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9882 fReturn[fReturnSizePic - offset - 1] : "acc"));
9885 aopOp(IC_RESULT(ic),ic,FALSE);
9886 size = AOP_SIZE(IC_RESULT(ic));
9889 pic14_emitcode ("pop","acc");
9890 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9895 aopOp(IC_RESULT(ic),ic,FALSE);
9897 assignResultValue(IC_RESULT(ic));
9900 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9903 /*-----------------------------------------------------------------*/
9904 /* genpic14Code - generate code for pic14 based controllers */
9905 /*-----------------------------------------------------------------*/
9907 * At this point, ralloc.c has gone through the iCode and attempted
9908 * to optimize in a way suitable for a PIC. Now we've got to generate
9909 * PIC instructions that correspond to the iCode.
9911 * Once the instructions are generated, we'll pass through both the
9912 * peep hole optimizer and the pCode optimizer.
9913 *-----------------------------------------------------------------*/
9915 void genpic14Code (iCode *lic)
9920 lineHead = lineCurr = NULL;
9922 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9925 /* if debug information required */
9926 if (options.debug && currFunc) {
9928 debugFile->writeFunction(currFunc);
9930 if (IS_STATIC(currFunc->etype)) {
9931 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9932 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9934 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9935 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9942 for (ic = lic ; ic ; ic = ic->next ) {
9944 DEBUGpic14_emitcode(";ic","");
9945 if ( cln != ic->lineno ) {
9946 if ( options.debug ) {
9948 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9949 FileBaseName(ic->filename),ic->lineno,
9950 ic->level,ic->block);
9954 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9955 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9956 printCLine(ic->filename, ic->lineno));
9958 if (!options.noCcodeInAsm) {
9960 newpCodeCSource(ic->lineno,
9962 printCLine(ic->filename, ic->lineno)));
9968 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9970 /* if the result is marked as
9971 spilt and rematerializable or code for
9972 this has already been generated then
9974 if (resultRemat(ic) || ic->generated )
9977 /* depending on the operation */
9996 /* IPOP happens only when trying to restore a
9997 spilt live range, if there is an ifx statement
9998 following this pop then the if statement might
9999 be using some of the registers being popped which
10000 would destory the contents of the register so
10001 we need to check for this condition and handle it */
10003 ic->next->op == IFX &&
10004 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10005 genIfx (ic->next,ic);
10023 genEndFunction (ic);
10043 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10060 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10064 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10071 /* note these two are xlated by algebraic equivalence
10072 during parsing SDCC.y */
10073 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10074 "got '>=' or '<=' shouldn't have come here");
10078 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10090 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10094 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10098 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10122 genRightShift (ic);
10125 case GET_VALUE_AT_ADDRESS:
10130 if (POINTER_SET(ic))
10157 addSet(&_G.sendSet,ic);
10166 /* now we are ready to call the
10167 peep hole optimizer */
10168 if (!options.nopeep) {
10169 peepHole (&lineHead);
10171 /* now do the actual printing */
10172 printLine (lineHead,codeOutFile);
10175 DFPRINTF((stderr,"printing pBlock\n\n"));
10176 printpBlock(stdout,pb);