1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic
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,int is_func);
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)
220 addpCode2pBlock(pb,newpCode(poc,pcop));
222 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
225 void emitpcodeNULLop(PIC_OPCODE poc)
228 addpCode2pBlock(pb,newpCode(poc,NULL));
232 void emitpcodePagesel(const char *label)
236 strcpy(code,"\tpagesel ");
238 addpCode2pBlock(pb,newpCodeInlineP(code));
242 /*-----------------------------------------------------------------*/
243 /* pic14_emitcode - writes the code into a file : for now it is simple */
244 /*-----------------------------------------------------------------*/
245 void pic14_emitcode (char *inst,char *fmt, ...)
248 char lb[INITIAL_INLINEASM];
255 sprintf(lb,"%s\t",inst);
257 sprintf(lb,"%s",inst);
258 vsprintf(lb+(strlen(lb)),fmt,ap);
262 while (isspace(*lbp)) lbp++;
265 lineCurr = (lineCurr ?
266 connectLine(lineCurr,newLineNode(lb)) :
267 (lineHead = newLineNode(lb)));
268 lineCurr->isInline = _G.inLine;
269 lineCurr->isDebug = _G.debugLine;
272 addpCode2pBlock(pb,newpCodeCharP(lb));
278 /*-----------------------------------------------------------------*/
279 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
280 /*-----------------------------------------------------------------*/
281 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
283 bool r0iu = FALSE , r1iu = FALSE;
284 bool r0ou = FALSE , r1ou = FALSE;
286 /* the logic: if r0 & r1 used in the instruction
287 then we are in trouble otherwise */
289 /* first check if r0 & r1 are used by this
290 instruction, in which case we are in trouble */
291 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
292 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
297 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
298 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
300 /* if no usage of r0 then return it */
301 if (!r0iu && !r0ou) {
302 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
303 (*aopp)->type = AOP_R0;
305 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
308 /* if no usage of r1 then return it */
309 if (!r1iu && !r1ou) {
310 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
311 (*aopp)->type = AOP_R1;
313 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
316 /* now we know they both have usage */
317 /* if r0 not used in this instruction */
319 /* push it if not already pushed */
321 //pic14_emitcode ("push","%s",
322 // pic14_regWithIdx(R0_IDX)->dname);
326 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
327 (*aopp)->type = AOP_R0;
329 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
332 /* if r1 not used then */
335 /* push it if not already pushed */
337 //pic14_emitcode ("push","%s",
338 // pic14_regWithIdx(R1_IDX)->dname);
342 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
343 (*aopp)->type = AOP_R1;
344 return pic14_regWithIdx(R1_IDX);
348 /* I said end of world but not quite end of world yet */
349 /* if this is a result then we can push it on the stack*/
351 (*aopp)->type = AOP_STK;
355 /* other wise this is true end of the world */
356 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
357 "getFreePtr should never reach here");
361 /*-----------------------------------------------------------------*/
362 /* newAsmop - creates a new asmOp */
363 /*-----------------------------------------------------------------*/
364 asmop *newAsmop (short type)
368 aop = Safe_calloc(1,sizeof(asmop));
373 static void genSetDPTR(int n)
377 pic14_emitcode(";", "Select standard DPTR");
378 pic14_emitcode("mov", "dps, #0x00");
382 pic14_emitcode(";", "Select alternate DPTR");
383 pic14_emitcode("mov", "dps, #0x01");
387 /*-----------------------------------------------------------------*/
388 /* resolveIfx - converts an iCode ifx into a form more useful for */
389 /* generating code */
390 /*-----------------------------------------------------------------*/
391 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
396 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
398 resIfx->condition = 1; /* assume that the ifx is true */
399 resIfx->generated = 0; /* indicate that the ifx has not been used */
402 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
404 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
405 __FUNCTION__,__LINE__,resIfx->lbl->key);
409 resIfx->lbl = IC_TRUE(ifx);
411 resIfx->lbl = IC_FALSE(ifx);
412 resIfx->condition = 0;
416 DEBUGpic14_emitcode("; ***","ifx true is non-null");
418 DEBUGpic14_emitcode("; ***","ifx false is non-null");
422 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
425 /*-----------------------------------------------------------------*/
426 /* pointerCode - returns the code for a pointer type */
427 /*-----------------------------------------------------------------*/
428 static int pointerCode (sym_link *etype)
431 return PTR_TYPE(SPEC_OCLS(etype));
435 /*-----------------------------------------------------------------*/
436 /* aopForSym - for a true symbol */
437 /*-----------------------------------------------------------------*/
438 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
441 memmap *space= SPEC_OCLS(sym->etype);
443 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
444 /* if already has one */
448 /* assign depending on the storage class */
449 /* if it is on the stack or indirectly addressable */
450 /* space we need to assign either r0 or r1 to it */
451 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
452 sym->aop = aop = newAsmop(0);
453 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
454 aop->size = getSize(sym->type);
456 /* now assign the address of the variable to
457 the pointer register */
458 if (aop->type != AOP_STK) {
462 pic14_emitcode("push","acc");
464 pic14_emitcode("mov","a,_bp");
465 pic14_emitcode("add","a,#0x%02x",
467 ((char)(sym->stack - _G.nRegsSaved )) :
468 ((char)sym->stack)) & 0xff);
469 pic14_emitcode("mov","%s,a",
470 aop->aopu.aop_ptr->name);
473 pic14_emitcode("pop","acc");
475 pic14_emitcode("mov","%s,#%s",
476 aop->aopu.aop_ptr->name,
478 aop->paged = space->paged;
480 aop->aopu.aop_stk = sym->stack;
484 if (sym->onStack && options.stack10bit)
486 /* It's on the 10 bit stack, which is located in
490 //DEBUGpic14_emitcode(";","%d",__LINE__);
493 pic14_emitcode("push","acc");
495 pic14_emitcode("mov","a,_bp");
496 pic14_emitcode("add","a,#0x%02x",
498 ((char)(sym->stack - _G.nRegsSaved )) :
499 ((char)sym->stack)) & 0xff);
502 pic14_emitcode ("mov","dpx1,#0x40");
503 pic14_emitcode ("mov","dph1,#0x00");
504 pic14_emitcode ("mov","dpl1, a");
508 pic14_emitcode("pop","acc");
510 sym->aop = aop = newAsmop(AOP_DPTR2);
511 aop->size = getSize(sym->type);
515 //DEBUGpic14_emitcode(";","%d",__LINE__);
516 /* if in bit space */
517 if (IN_BITSPACE(space)) {
518 sym->aop = aop = newAsmop (AOP_CRY);
519 aop->aopu.aop_dir = sym->rname ;
520 aop->size = getSize(sym->type);
521 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
524 /* if it is in direct space */
525 if (IN_DIRSPACE(space)) {
526 sym->aop = aop = newAsmop (AOP_DIR);
527 aop->aopu.aop_dir = sym->rname ;
528 aop->size = getSize(sym->type);
529 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
533 /* special case for a function */
534 if (IS_FUNC(sym->type)) {
536 sym->aop = aop = newAsmop(AOP_PCODE);
537 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
538 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
539 PCOI(aop->aopu.pcop)->_function = 1;
540 PCOI(aop->aopu.pcop)->index = 0;
541 aop->size = FPTRSIZE;
543 sym->aop = aop = newAsmop(AOP_IMMD);
544 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
545 strcpy(aop->aopu.aop_immd,sym->rname);
546 aop->size = FPTRSIZE;
548 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
553 /* only remaining is far space */
554 /* in which case DPTR gets the address */
555 sym->aop = aop = newAsmop(AOP_PCODE);
557 aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
558 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
559 PCOI(aop->aopu.pcop)->index = 0;
561 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
562 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
564 allocDirReg (IC_LEFT(ic));
566 aop->size = FPTRSIZE;
568 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
569 sym->aop = aop = newAsmop(AOP_DPTR);
570 pic14_emitcode ("mov","dptr,#%s", sym->rname);
571 aop->size = getSize(sym->type);
573 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
576 /* if it is in code space */
577 if (IN_CODESPACE(space))
583 /*-----------------------------------------------------------------*/
584 /* aopForRemat - rematerialzes an object */
585 /*-----------------------------------------------------------------*/
586 static asmop *aopForRemat (operand *op) // x symbol *sym)
588 symbol *sym = OP_SYMBOL(op);
590 asmop *aop = newAsmop(AOP_PCODE);
594 ic = sym->rematiCode;
596 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
597 if(IS_OP_POINTER(op)) {
598 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
602 val += (int) operandLitValue(IC_RIGHT(ic));
603 } else if (ic->op == '-') {
604 val -= (int) operandLitValue(IC_RIGHT(ic));
608 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
611 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
612 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
614 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
616 PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
618 PCOI(aop->aopu.pcop)->index = val;
620 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
621 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
622 val, IS_PTR_CONST(operandType(op)));
624 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
626 allocDirReg (IC_LEFT(ic));
631 int aopIdx (asmop *aop, int offset)
636 if(aop->type != AOP_REG)
639 return aop->aopu.aop_reg[offset]->rIdx;
642 /*-----------------------------------------------------------------*/
643 /* regsInCommon - two operands have some registers in common */
644 /*-----------------------------------------------------------------*/
645 static bool regsInCommon (operand *op1, operand *op2)
650 /* if they have registers in common */
651 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
654 sym1 = OP_SYMBOL(op1);
655 sym2 = OP_SYMBOL(op2);
657 if (sym1->nRegs == 0 || sym2->nRegs == 0)
660 for (i = 0 ; i < sym1->nRegs ; i++) {
665 for (j = 0 ; j < sym2->nRegs ;j++ ) {
669 if (sym2->regs[j] == sym1->regs[i])
677 /*-----------------------------------------------------------------*/
678 /* operandsEqu - equivalent */
679 /*-----------------------------------------------------------------*/
680 static bool operandsEqu ( operand *op1, operand *op2)
684 /* if they not symbols */
685 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
688 sym1 = OP_SYMBOL(op1);
689 sym2 = OP_SYMBOL(op2);
691 /* if both are itemps & one is spilt
692 and the other is not then false */
693 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
694 sym1->isspilt != sym2->isspilt )
697 /* if they are the same */
701 if (strcmp(sym1->rname,sym2->rname) == 0)
705 /* if left is a tmp & right is not */
709 (sym1->usl.spillLoc == sym2))
716 (sym2->usl.spillLoc == sym1))
722 /*-----------------------------------------------------------------*/
723 /* pic14_sameRegs - two asmops have the same registers */
724 /*-----------------------------------------------------------------*/
725 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
732 if (aop1->type != AOP_REG ||
733 aop2->type != AOP_REG )
736 if (aop1->size != aop2->size )
739 for (i = 0 ; i < aop1->size ; i++ )
740 if (aop1->aopu.aop_reg[i] !=
741 aop2->aopu.aop_reg[i] )
747 /*-----------------------------------------------------------------*/
748 /* aopOp - allocates an asmop for an operand : */
749 /*-----------------------------------------------------------------*/
750 void aopOp (operand *op, iCode *ic, bool result)
759 // DEBUGpic14_emitcode(";","%d",__LINE__);
760 /* if this a literal */
761 if (IS_OP_LITERAL(op)) {
762 op->aop = aop = newAsmop(AOP_LIT);
763 aop->aopu.aop_lit = op->operand.valOperand;
764 aop->size = getSize(operandType(op));
769 sym_link *type = operandType(op);
771 if(IS_PTR_CONST(type))
775 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
778 /* if already has a asmop then continue */
782 /* if the underlying symbol has a aop */
783 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
784 DEBUGpic14_emitcode(";","%d",__LINE__);
785 op->aop = OP_SYMBOL(op)->aop;
789 /* if this is a true symbol */
790 if (IS_TRUE_SYMOP(op)) {
791 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
792 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
796 /* this is a temporary : this has
802 e) can be a return use only */
807 /* if the type is a conditional */
808 if (sym->regType == REG_CND) {
809 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
814 /* if it is spilt then two situations
816 b) has a spill location */
817 if (sym->isspilt || sym->nRegs == 0) {
819 DEBUGpic14_emitcode(";","%d",__LINE__);
820 /* rematerialize it NOW */
823 sym->aop = op->aop = aop =
825 aop->size = getSize(sym->type);
826 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
832 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
833 aop->size = getSize(sym->type);
834 for ( i = 0 ; i < 2 ; i++ )
835 aop->aopu.aop_str[i] = accUse[i];
836 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
841 if(sym->isptr) { // && sym->uptr
842 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
843 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
845 //PCOI(aop->aopu.pcop)->_const = 0;
846 //PCOI(aop->aopu.pcop)->index = 0;
848 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
849 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
851 //allocDirReg (IC_LEFT(ic));
853 aop->size = getSize(sym->type);
854 DEBUGpic14_emitcode(";","%d",__LINE__);
861 aop = op->aop = sym->aop = newAsmop(AOP_STR);
862 aop->size = getSize(sym->type);
863 for ( i = 0 ; i < fReturnSizePic ; i++ )
864 aop->aopu.aop_str[i] = fReturn[i];
866 DEBUGpic14_emitcode(";","%d",__LINE__);
871 /* else spill location */
872 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
873 /* force a new aop if sizes differ */
874 sym->usl.spillLoc->aop = NULL;
876 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
877 __FUNCTION__,__LINE__,
878 sym->usl.spillLoc->rname,
879 sym->rname, sym->usl.spillLoc->offset);
881 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
882 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
883 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
885 sym->usl.spillLoc->offset);
886 aop->size = getSize(sym->type);
892 sym_link *type = operandType(op);
894 if(IS_PTR_CONST(type))
898 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
901 /* must be in a register */
902 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
903 sym->aop = op->aop = aop = newAsmop(AOP_REG);
904 aop->size = sym->nRegs;
905 for ( i = 0 ; i < sym->nRegs ;i++)
906 aop->aopu.aop_reg[i] = sym->regs[i];
909 /*-----------------------------------------------------------------*/
910 /* freeAsmop - free up the asmop given to an operand */
911 /*----------------------------------------------------------------*/
912 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
929 /* depending on the asmop type only three cases need work AOP_RO
930 , AOP_R1 && AOP_STK */
936 pic14_emitcode ("pop","ar0");
940 bitVectUnSetBit(ic->rUsed,R0_IDX);
946 pic14_emitcode ("pop","ar1");
950 bitVectUnSetBit(ic->rUsed,R1_IDX);
956 int stk = aop->aopu.aop_stk + aop->size;
957 bitVectUnSetBit(ic->rUsed,R0_IDX);
958 bitVectUnSetBit(ic->rUsed,R1_IDX);
960 getFreePtr(ic,&aop,FALSE);
962 if (options.stack10bit)
964 /* I'm not sure what to do here yet... */
967 "*** Warning: probably generating bad code for "
968 "10 bit stack mode.\n");
972 pic14_emitcode ("mov","a,_bp");
973 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
974 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
976 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
980 pic14_emitcode("pop","acc");
981 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
983 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
986 freeAsmop(op,NULL,ic,TRUE);
988 pic14_emitcode("pop","ar0");
993 pic14_emitcode("pop","ar1");
1001 /* all other cases just dealloc */
1005 OP_SYMBOL(op)->aop = NULL;
1006 /* if the symbol has a spill */
1008 SPIL_LOC(op)->aop = NULL;
1013 /*-----------------------------------------------------------------*/
1014 /* aopGet - for fetching value of the aop */
1015 /*-----------------------------------------------------------------*/
1016 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1021 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1022 /* offset is greater than
1024 if (offset > (aop->size - 1) &&
1025 aop->type != AOP_LIT)
1028 /* depending on type */
1029 switch (aop->type) {
1033 DEBUGpic14_emitcode(";","%d",__LINE__);
1034 /* if we need to increment it */
1035 while (offset > aop->coff) {
1036 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1040 while (offset < aop->coff) {
1041 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1045 aop->coff = offset ;
1047 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1048 return (dname ? "acc" : "a");
1050 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1051 rs = Safe_calloc(1,strlen(s)+1);
1057 DEBUGpic14_emitcode(";","%d",__LINE__);
1058 if (aop->type == AOP_DPTR2)
1063 while (offset > aop->coff) {
1064 pic14_emitcode ("inc","dptr");
1068 while (offset < aop->coff) {
1069 pic14_emitcode("lcall","__decdptr");
1075 pic14_emitcode("clr","a");
1076 pic14_emitcode("movc","a,@a+dptr");
1079 pic14_emitcode("movx","a,@dptr");
1082 if (aop->type == AOP_DPTR2)
1087 return (dname ? "acc" : "a");
1092 sprintf (s,"%s",aop->aopu.aop_immd);
1095 sprintf(s,"(%s >> %d)",
1100 aop->aopu.aop_immd);
1101 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1102 rs = Safe_calloc(1,strlen(s)+1);
1108 sprintf(s,"(%s + %d)",
1111 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1113 sprintf(s,"%s",aop->aopu.aop_dir);
1114 rs = Safe_calloc(1,strlen(s)+1);
1120 // return aop->aopu.aop_reg[offset]->dname;
1122 return aop->aopu.aop_reg[offset]->name;
1125 //pic14_emitcode(";","%d",__LINE__);
1126 return aop->aopu.aop_dir;
1129 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1130 return "AOP_accumulator_bug";
1133 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1134 rs = Safe_calloc(1,strlen(s)+1);
1139 aop->coff = offset ;
1140 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1143 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1145 return aop->aopu.aop_str[offset];
1149 pCodeOp *pcop = aop->aopu.pcop;
1150 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1152 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1153 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1154 sprintf(s,"%s", pcop->name);
1156 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1159 rs = Safe_calloc(1,strlen(s)+1);
1165 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1166 "aopget got unsupported aop->type");
1171 /*-----------------------------------------------------------------*/
1172 /* popGetTempReg - create a new temporary pCodeOp */
1173 /*-----------------------------------------------------------------*/
1174 pCodeOp *popGetTempReg(void)
1179 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1180 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1181 PCOR(pcop)->r->wasUsed=1;
1182 PCOR(pcop)->r->isFree=0;
1188 /*-----------------------------------------------------------------*/
1189 /* popGetTempReg - create a new temporary pCodeOp */
1190 /*-----------------------------------------------------------------*/
1191 void popReleaseTempReg(pCodeOp *pcop)
1194 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1195 PCOR(pcop)->r->isFree = 1;
1198 /*-----------------------------------------------------------------*/
1199 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1200 /*-----------------------------------------------------------------*/
1201 pCodeOp *popGetLabel(unsigned int key)
1204 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1206 if(key>(unsigned int)max_key)
1209 return newpCodeOpLabel(NULL,key+100+labelOffset);
1212 /*-------------------------------------------------------------------*/
1213 /* popGetLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1214 /*-------------------------------------------------------------------*/
1215 pCodeOp *popGetHighLabel(unsigned int key)
1218 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1220 if(key>(unsigned int)max_key)
1223 pcop = newpCodeOpLabel(NULL,key+100+labelOffset);
1224 PCOLAB(pcop)->offset = 1;
1228 /*-----------------------------------------------------------------*/
1229 /* popCopyReg - copy a pcode operator */
1230 /*-----------------------------------------------------------------*/
1231 pCodeOp *popCopyReg(pCodeOpReg *pc)
1235 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1236 pcor->pcop.type = pc->pcop.type;
1238 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1239 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1241 pcor->pcop.name = NULL;
1244 pcor->rIdx = pc->rIdx;
1247 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1251 /*-----------------------------------------------------------------*/
1252 /* popGet - asm operator to pcode operator conversion */
1253 /*-----------------------------------------------------------------*/
1254 pCodeOp *popGetLit(unsigned int lit)
1257 return newpCodeOpLit(lit);
1261 /*-----------------------------------------------------------------*/
1262 /* popGetImmd - asm operator to pcode immediate conversion */
1263 /*-----------------------------------------------------------------*/
1264 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1267 return newpCodeOpImmd(name, offset,index, 0, is_func);
1271 /*-----------------------------------------------------------------*/
1272 /* popGet - asm operator to pcode operator conversion */
1273 /*-----------------------------------------------------------------*/
1274 pCodeOp *popGetWithString(char *str)
1280 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1284 pcop = newpCodeOp(str,PO_STR);
1289 /*-----------------------------------------------------------------*/
1290 /* popRegFromString - */
1291 /*-----------------------------------------------------------------*/
1292 pCodeOp *popRegFromString(char *str, int size, int offset)
1295 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1296 pcop->type = PO_DIR;
1298 DEBUGpic14_emitcode(";","%d",__LINE__);
1303 pcop->name = Safe_calloc(1,strlen(str)+1);
1304 strcpy(pcop->name,str);
1306 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1308 PCOR(pcop)->r = dirregWithName(pcop->name);
1309 if(PCOR(pcop)->r == NULL) {
1310 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1311 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1312 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1314 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1316 PCOR(pcop)->instance = offset;
1321 pCodeOp *popRegFromIdx(int rIdx)
1325 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1326 __FUNCTION__,__LINE__,rIdx);
1328 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1330 PCOR(pcop)->rIdx = rIdx;
1331 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1332 PCOR(pcop)->r->isFree = 0;
1333 PCOR(pcop)->r->wasUsed = 1;
1335 pcop->type = PCOR(pcop)->r->pc_type;
1340 /*-----------------------------------------------------------------*/
1341 /* popGet - asm operator to pcode operator conversion */
1342 /*-----------------------------------------------------------------*/
1343 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1345 //char *s = buffer ;
1350 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1351 /* offset is greater than
1354 if (offset > (aop->size - 1) &&
1355 aop->type != AOP_LIT)
1356 return NULL; //zero;
1358 /* depending on type */
1359 switch (aop->type) {
1366 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1370 DEBUGpic14_emitcode(";","%d",__LINE__);
1371 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1374 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1376 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1377 pcop->type = PO_DIR;
1381 sprintf(s,"(%s + %d)",
1385 sprintf(s,"%s",aop->aopu.aop_dir);
1386 pcop->name = Safe_calloc(1,strlen(s)+1);
1387 strcpy(pcop->name,s);
1389 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1390 strcpy(pcop->name,aop->aopu.aop_dir);
1391 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1392 if(PCOR(pcop)->r == NULL) {
1393 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1394 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1395 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1397 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1399 PCOR(pcop)->instance = offset;
1406 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1408 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1409 PCOR(pcop)->rIdx = rIdx;
1410 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1411 PCOR(pcop)->r->wasUsed=1;
1412 PCOR(pcop)->r->isFree=0;
1414 PCOR(pcop)->instance = offset;
1415 pcop->type = PCOR(pcop)->r->pc_type;
1416 //rs = aop->aopu.aop_reg[offset]->name;
1417 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1422 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1423 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1424 //if(PCOR(pcop)->r == NULL)
1425 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1429 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1432 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1433 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1435 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1436 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1437 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1438 pcop->type = PCOR(pcop)->r->pc_type;
1439 pcop->name = PCOR(pcop)->r->name;
1445 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1447 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1448 pcop = pCodeOpCopy(aop->aopu.pcop);
1449 PCOI(pcop)->offset = offset;
1453 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1454 "popGet got unsupported aop->type");
1457 /*-----------------------------------------------------------------*/
1458 /* aopPut - puts a string for a aop */
1459 /*-----------------------------------------------------------------*/
1460 void aopPut (asmop *aop, char *s, int offset)
1465 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1467 if (aop->size && offset > ( aop->size - 1)) {
1468 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1469 "aopPut got offset > aop->size");
1473 /* will assign value to value */
1474 /* depending on where it is ofcourse */
1475 switch (aop->type) {
1478 sprintf(d,"(%s + %d)",
1479 aop->aopu.aop_dir,offset);
1480 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1483 sprintf(d,"%s",aop->aopu.aop_dir);
1486 DEBUGpic14_emitcode(";","%d",__LINE__);
1488 pic14_emitcode("movf","%s,w",s);
1489 pic14_emitcode("movwf","%s",d);
1492 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1493 if(offset >= aop->size) {
1494 emitpcode(POC_CLRF,popGet(aop,offset));
1497 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1500 emitpcode(POC_MOVWF,popGet(aop,offset));
1507 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1508 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1511 strcmp(s,"r0") == 0 ||
1512 strcmp(s,"r1") == 0 ||
1513 strcmp(s,"r2") == 0 ||
1514 strcmp(s,"r3") == 0 ||
1515 strcmp(s,"r4") == 0 ||
1516 strcmp(s,"r5") == 0 ||
1517 strcmp(s,"r6") == 0 ||
1518 strcmp(s,"r7") == 0 )
1519 pic14_emitcode("mov","%s,%s ; %d",
1520 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1524 if(strcmp(s,"W")==0 )
1525 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1527 pic14_emitcode("movwf","%s",
1528 aop->aopu.aop_reg[offset]->name);
1530 if(strcmp(s,zero)==0) {
1531 emitpcode(POC_CLRF,popGet(aop,offset));
1533 } else if(strcmp(s,"W")==0) {
1534 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1535 pcop->type = PO_GPR_REGISTER;
1537 PCOR(pcop)->rIdx = -1;
1538 PCOR(pcop)->r = NULL;
1540 DEBUGpic14_emitcode(";","%d",__LINE__);
1541 pcop->name = Safe_strdup(s);
1542 emitpcode(POC_MOVFW,pcop);
1543 emitpcode(POC_MOVWF,popGet(aop,offset));
1544 } else if(strcmp(s,one)==0) {
1545 emitpcode(POC_CLRF,popGet(aop,offset));
1546 emitpcode(POC_INCF,popGet(aop,offset));
1548 emitpcode(POC_MOVWF,popGet(aop,offset));
1556 if (aop->type == AOP_DPTR2)
1562 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1563 "aopPut writting to code space");
1567 while (offset > aop->coff) {
1569 pic14_emitcode ("inc","dptr");
1572 while (offset < aop->coff) {
1574 pic14_emitcode("lcall","__decdptr");
1579 /* if not in accumulater */
1582 pic14_emitcode ("movx","@dptr,a");
1584 if (aop->type == AOP_DPTR2)
1592 while (offset > aop->coff) {
1594 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1596 while (offset < aop->coff) {
1598 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1604 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1609 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1611 if (strcmp(s,"r0") == 0 ||
1612 strcmp(s,"r1") == 0 ||
1613 strcmp(s,"r2") == 0 ||
1614 strcmp(s,"r3") == 0 ||
1615 strcmp(s,"r4") == 0 ||
1616 strcmp(s,"r5") == 0 ||
1617 strcmp(s,"r6") == 0 ||
1618 strcmp(s,"r7") == 0 ) {
1620 sprintf(buffer,"a%s",s);
1621 pic14_emitcode("mov","@%s,%s",
1622 aop->aopu.aop_ptr->name,buffer);
1624 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1629 if (strcmp(s,"a") == 0)
1630 pic14_emitcode("push","acc");
1632 pic14_emitcode("push","%s",s);
1637 /* if bit variable */
1638 if (!aop->aopu.aop_dir) {
1639 pic14_emitcode("clr","a");
1640 pic14_emitcode("rlc","a");
1643 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1646 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1649 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1651 lbl = newiTempLabel(NULL);
1653 if (strcmp(s,"a")) {
1656 pic14_emitcode("clr","c");
1657 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1658 pic14_emitcode("cpl","c");
1659 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1660 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1667 if (strcmp(aop->aopu.aop_str[offset],s))
1668 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1673 if (!offset && (strcmp(s,"acc") == 0))
1676 if (strcmp(aop->aopu.aop_str[offset],s))
1677 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1681 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1682 "aopPut got unsupported aop->type");
1688 /*-----------------------------------------------------------------*/
1689 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1690 /*-----------------------------------------------------------------*/
1691 void mov2w (asmop *aop, int offset)
1697 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1699 if ( aop->type == AOP_PCODE ||
1700 aop->type == AOP_LIT ||
1701 aop->type == AOP_IMMD )
1702 emitpcode(POC_MOVLW,popGet(aop,offset));
1704 emitpcode(POC_MOVFW,popGet(aop,offset));
1708 /*-----------------------------------------------------------------*/
1709 /* reAdjustPreg - points a register back to where it should */
1710 /*-----------------------------------------------------------------*/
1711 static void reAdjustPreg (asmop *aop)
1715 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1717 if ((size = aop->size) <= 1)
1720 switch (aop->type) {
1724 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1728 if (aop->type == AOP_DPTR2)
1734 pic14_emitcode("lcall","__decdptr");
1737 if (aop->type == AOP_DPTR2)
1749 /*-----------------------------------------------------------------*/
1750 /* opIsGptr: returns non-zero if the passed operand is */
1751 /* a generic pointer type. */
1752 /*-----------------------------------------------------------------*/
1753 static int opIsGptr(operand *op)
1755 sym_link *type = operandType(op);
1757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1758 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1766 /*-----------------------------------------------------------------*/
1767 /* pic14_getDataSize - get the operand data size */
1768 /*-----------------------------------------------------------------*/
1769 int pic14_getDataSize(operand *op)
1771 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1774 return AOP_SIZE(op);
1776 // tsd- in the pic port, the genptr size is 1, so this code here
1777 // fails. ( in the 8051 port, the size was 4).
1780 size = AOP_SIZE(op);
1781 if (size == GPTRSIZE)
1783 sym_link *type = operandType(op);
1784 if (IS_GENPTR(type))
1786 /* generic pointer; arithmetic operations
1787 * should ignore the high byte (pointer type).
1790 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1797 /*-----------------------------------------------------------------*/
1798 /* pic14_outAcc - output Acc */
1799 /*-----------------------------------------------------------------*/
1800 void pic14_outAcc(operand *result)
1803 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1804 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1807 size = pic14_getDataSize(result);
1809 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1812 /* unsigned or positive */
1814 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1819 /*-----------------------------------------------------------------*/
1820 /* pic14_outBitC - output a bit C */
1821 /*-----------------------------------------------------------------*/
1822 void pic14_outBitC(operand *result)
1825 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1826 /* if the result is bit */
1827 if (AOP_TYPE(result) == AOP_CRY)
1828 aopPut(AOP(result),"c",0);
1830 pic14_emitcode("clr","a ; %d", __LINE__);
1831 pic14_emitcode("rlc","a");
1832 pic14_outAcc(result);
1836 /*-----------------------------------------------------------------*/
1837 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1838 /*-----------------------------------------------------------------*/
1839 void pic14_toBoolean(operand *oper)
1841 int size = AOP_SIZE(oper) - 1;
1844 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1846 if ( AOP_TYPE(oper) != AOP_ACC) {
1847 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1850 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1855 /*-----------------------------------------------------------------*/
1856 /* genNot - generate code for ! operation */
1857 /*-----------------------------------------------------------------*/
1858 static void genNot (iCode *ic)
1863 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1864 /* assign asmOps to operand & result */
1865 aopOp (IC_LEFT(ic),ic,FALSE);
1866 aopOp (IC_RESULT(ic),ic,TRUE);
1868 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1869 /* if in bit space then a special case */
1870 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1871 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1872 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1873 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1875 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1876 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1877 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1882 size = AOP_SIZE(IC_LEFT(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 emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
2550 emitpcode(POC_GOTO,popGetLabel(blbl->key));
2551 emitpLabel(albl->key);
2553 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2555 emitpcode(poc,popGet(AOP(left),1));
2556 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2557 emitpcode(poc,popGet(AOP(left),0));
2558 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2560 emitpLabel(blbl->key);
2562 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2564 /* if we need to assign a result value */
2565 if ((IS_ITEMP(IC_RESULT(ic)) &&
2566 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2567 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2568 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2571 aopOp(IC_RESULT(ic),ic,FALSE);
2574 assignResultValue(IC_RESULT(ic));
2576 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2579 /* if register bank was saved then unsave them */
2580 if (currFunc && dtype &&
2581 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2582 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2584 /* if we hade saved some registers then
2587 unsaveRegisters (ic);
2591 /*-----------------------------------------------------------------*/
2592 /* resultRemat - result is rematerializable */
2593 /*-----------------------------------------------------------------*/
2594 static int resultRemat (iCode *ic)
2596 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2597 if (SKIP_IC(ic) || ic->op == IFX)
2600 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2601 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2602 if (sym->remat && !POINTER_SET(ic))
2609 #if defined(__BORLANDC__) || defined(_MSC_VER)
2610 #define STRCASECMP stricmp
2612 #define STRCASECMP strcasecmp
2616 /*-----------------------------------------------------------------*/
2617 /* inExcludeList - return 1 if the string is in exclude Reg list */
2618 /*-----------------------------------------------------------------*/
2619 static bool inExcludeList(char *s)
2621 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2625 if (options.excludeRegs[i] &&
2626 STRCASECMP(options.excludeRegs[i],"none") == 0)
2629 for ( i = 0 ; options.excludeRegs[i]; i++) {
2630 if (options.excludeRegs[i] &&
2631 STRCASECMP(s,options.excludeRegs[i]) == 0)
2638 /*-----------------------------------------------------------------*/
2639 /* genFunction - generated code for function entry */
2640 /*-----------------------------------------------------------------*/
2641 static void genFunction (iCode *ic)
2646 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2648 labelOffset += (max_key+4);
2652 /* create the function header */
2653 pic14_emitcode(";","-----------------------------------------");
2654 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2655 pic14_emitcode(";","-----------------------------------------");
2657 pic14_emitcode("","%s:",sym->rname);
2658 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2660 ftype = operandType(IC_LEFT(ic));
2662 /* if critical function then turn interrupts off */
2663 if (IFFUNC_ISCRITICAL(ftype))
2664 pic14_emitcode("clr","ea");
2666 /* here we need to generate the equates for the
2667 register bank if required */
2669 if (FUNC_REGBANK(ftype) != rbank) {
2672 rbank = FUNC_REGBANK(ftype);
2673 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2674 if (strcmp(regspic14[i].base,"0") == 0)
2675 pic14_emitcode("","%s = 0x%02x",
2677 8*rbank+regspic14[i].offset);
2679 pic14_emitcode ("","%s = %s + 0x%02x",
2682 8*rbank+regspic14[i].offset);
2687 /* if this is an interrupt service routine */
2688 if (IFFUNC_ISISR(sym->type)) {
2689 /* already done in pic14createInterruptVect() - delete me
2690 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2691 emitpcodeNULLop(POC_NOP);
2692 emitpcodeNULLop(POC_NOP);
2693 emitpcodeNULLop(POC_NOP);
2695 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2696 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2697 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2698 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2699 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2700 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2701 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* durring an interrupt PCLATH must be cleared before a goto or call statement */
2703 pBlockConvert2ISR(pb);
2705 if (!inExcludeList("acc"))
2706 pic14_emitcode ("push","acc");
2707 if (!inExcludeList("b"))
2708 pic14_emitcode ("push","b");
2709 if (!inExcludeList("dpl"))
2710 pic14_emitcode ("push","dpl");
2711 if (!inExcludeList("dph"))
2712 pic14_emitcode ("push","dph");
2713 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2715 pic14_emitcode ("push", "dpx");
2716 /* Make sure we're using standard DPTR */
2717 pic14_emitcode ("push", "dps");
2718 pic14_emitcode ("mov", "dps, #0x00");
2719 if (options.stack10bit)
2721 /* This ISR could conceivably use DPTR2. Better save it. */
2722 pic14_emitcode ("push", "dpl1");
2723 pic14_emitcode ("push", "dph1");
2724 pic14_emitcode ("push", "dpx1");
2727 /* if this isr has no bank i.e. is going to
2728 run with bank 0 , then we need to save more
2730 if (!FUNC_REGBANK(sym->type)) {
2732 /* if this function does not call any other
2733 function then we can be economical and
2734 save only those registers that are used */
2735 if (! IFFUNC_HASFCALL(sym->type)) {
2738 /* if any registers used */
2739 if (sym->regsUsed) {
2740 /* save the registers used */
2741 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2742 if (bitVectBitValue(sym->regsUsed,i) ||
2743 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2744 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2749 /* this function has a function call cannot
2750 determines register usage so we will have the
2752 saverbank(0,ic,FALSE);
2757 /* if callee-save to be used for this function
2758 then save the registers being used in this function */
2759 if (IFFUNC_CALLEESAVES(sym->type)) {
2762 /* if any registers used */
2763 if (sym->regsUsed) {
2764 /* save the registers used */
2765 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2766 if (bitVectBitValue(sym->regsUsed,i) ||
2767 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2768 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2776 /* set the register bank to the desired value */
2777 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2778 pic14_emitcode("push","psw");
2779 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2782 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2784 if (options.useXstack) {
2785 pic14_emitcode("mov","r0,%s",spname);
2786 pic14_emitcode("mov","a,_bp");
2787 pic14_emitcode("movx","@r0,a");
2788 pic14_emitcode("inc","%s",spname);
2792 /* set up the stack */
2793 pic14_emitcode ("push","_bp"); /* save the callers stack */
2795 pic14_emitcode ("mov","_bp,%s",spname);
2798 /* adjust the stack for the function */
2803 werror(W_STACK_OVERFLOW,sym->name);
2805 if (i > 3 && sym->recvSize < 4) {
2807 pic14_emitcode ("mov","a,sp");
2808 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2809 pic14_emitcode ("mov","sp,a");
2814 pic14_emitcode("inc","sp");
2819 pic14_emitcode ("mov","a,_spx");
2820 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2821 pic14_emitcode ("mov","_spx,a");
2826 /*-----------------------------------------------------------------*/
2827 /* genEndFunction - generates epilogue for functions */
2828 /*-----------------------------------------------------------------*/
2829 static void genEndFunction (iCode *ic)
2831 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2833 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2835 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2837 pic14_emitcode ("mov","%s,_bp",spname);
2840 /* if use external stack but some variables were
2841 added to the local stack then decrement the
2843 if (options.useXstack && sym->stack) {
2844 pic14_emitcode("mov","a,sp");
2845 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2846 pic14_emitcode("mov","sp,a");
2850 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2851 if (options.useXstack) {
2852 pic14_emitcode("mov","r0,%s",spname);
2853 pic14_emitcode("movx","a,@r0");
2854 pic14_emitcode("mov","_bp,a");
2855 pic14_emitcode("dec","%s",spname);
2859 pic14_emitcode ("pop","_bp");
2863 /* restore the register bank */
2864 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2865 pic14_emitcode ("pop","psw");
2867 if (IFFUNC_ISISR(sym->type)) {
2869 /* now we need to restore the registers */
2870 /* if this isr has no bank i.e. is going to
2871 run with bank 0 , then we need to save more
2873 if (!FUNC_REGBANK(sym->type)) {
2875 /* if this function does not call any other
2876 function then we can be economical and
2877 save only those registers that are used */
2878 if (! IFFUNC_HASFCALL(sym->type)) {
2881 /* if any registers used */
2882 if (sym->regsUsed) {
2883 /* save the registers used */
2884 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2885 if (bitVectBitValue(sym->regsUsed,i) ||
2886 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2887 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2892 /* this function has a function call cannot
2893 determines register usage so we will have the
2895 unsaverbank(0,ic,FALSE);
2899 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2901 if (options.stack10bit)
2903 pic14_emitcode ("pop", "dpx1");
2904 pic14_emitcode ("pop", "dph1");
2905 pic14_emitcode ("pop", "dpl1");
2907 pic14_emitcode ("pop", "dps");
2908 pic14_emitcode ("pop", "dpx");
2910 if (!inExcludeList("dph"))
2911 pic14_emitcode ("pop","dph");
2912 if (!inExcludeList("dpl"))
2913 pic14_emitcode ("pop","dpl");
2914 if (!inExcludeList("b"))
2915 pic14_emitcode ("pop","b");
2916 if (!inExcludeList("acc"))
2917 pic14_emitcode ("pop","acc");
2919 if (IFFUNC_ISCRITICAL(sym->type))
2920 pic14_emitcode("setb","ea");
2923 /* if debug then send end of function */
2924 /* if (options.debug && currFunc) { */
2927 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2928 FileBaseName(ic->filename),currFunc->lastLine,
2929 ic->level,ic->block);
2930 if (IS_STATIC(currFunc->etype))
2931 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2933 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2937 pic14_emitcode ("reti","");
2938 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2939 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2940 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2941 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2942 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2943 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2944 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2945 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2946 emitpcodeNULLop(POC_RETFIE);
2949 if (IFFUNC_ISCRITICAL(sym->type))
2950 pic14_emitcode("setb","ea");
2952 if (IFFUNC_CALLEESAVES(sym->type)) {
2955 /* if any registers used */
2956 if (sym->regsUsed) {
2957 /* save the registers used */
2958 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2959 if (bitVectBitValue(sym->regsUsed,i) ||
2960 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2961 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2967 /* if debug then send end of function */
2970 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2971 FileBaseName(ic->filename),currFunc->lastLine,
2972 ic->level,ic->block);
2973 if (IS_STATIC(currFunc->etype))
2974 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2976 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2980 pic14_emitcode ("return","");
2981 emitpcodeNULLop(POC_RETURN);
2983 /* Mark the end of a function */
2984 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2989 /*-----------------------------------------------------------------*/
2990 /* genRet - generate code for return statement */
2991 /*-----------------------------------------------------------------*/
2992 static void genRet (iCode *ic)
2994 int size,offset = 0 , pushed = 0;
2996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2997 /* if we have no return value then
2998 just generate the "ret" */
3002 /* we have something to return then
3003 move the return value into place */
3004 aopOp(IC_LEFT(ic),ic,FALSE);
3005 size = AOP_SIZE(IC_LEFT(ic));
3009 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3011 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3013 pic14_emitcode("push","%s",l);
3016 l = aopGet(AOP(IC_LEFT(ic)),offset,
3018 if (strcmp(fReturn[offset],l)) {
3019 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
3020 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3021 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3022 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3023 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3025 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3028 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3038 if (strcmp(fReturn[pushed],"a"))
3039 pic14_emitcode("pop",fReturn[pushed]);
3041 pic14_emitcode("pop","acc");
3044 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3047 /* generate a jump to the return label
3048 if the next is not the return statement */
3049 if (!(ic->next && ic->next->op == LABEL &&
3050 IC_LABEL(ic->next) == returnLabel)) {
3052 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3053 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3058 /*-----------------------------------------------------------------*/
3059 /* genLabel - generates a label */
3060 /*-----------------------------------------------------------------*/
3061 static void genLabel (iCode *ic)
3063 /* special case never generate */
3064 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3065 if (IC_LABEL(ic) == entryLabel)
3068 emitpLabel(IC_LABEL(ic)->key);
3069 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3072 /*-----------------------------------------------------------------*/
3073 /* genGoto - generates a goto */
3074 /*-----------------------------------------------------------------*/
3076 static void genGoto (iCode *ic)
3078 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3079 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3083 /*-----------------------------------------------------------------*/
3084 /* genMultbits :- multiplication of bits */
3085 /*-----------------------------------------------------------------*/
3086 static void genMultbits (operand *left,
3090 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3092 if(!pic14_sameRegs(AOP(result),AOP(right)))
3093 emitpcode(POC_BSF, popGet(AOP(result),0));
3095 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3096 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3097 emitpcode(POC_BCF, popGet(AOP(result),0));
3102 /*-----------------------------------------------------------------*/
3103 /* genMultOneByte : 8 bit multiplication & division */
3104 /*-----------------------------------------------------------------*/
3105 static void genMultOneByte (operand *left,
3109 sym_link *opetype = operandType(result);
3114 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3115 DEBUGpic14_AopType(__LINE__,left,right,result);
3116 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3118 /* (if two literals, the value is computed before) */
3119 /* if one literal, literal on the right */
3120 if (AOP_TYPE(left) == AOP_LIT){
3126 size = AOP_SIZE(result);
3129 if (AOP_TYPE(right) == AOP_LIT){
3130 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3131 aopGet(AOP(right),0,FALSE,FALSE),
3132 aopGet(AOP(left),0,FALSE,FALSE),
3133 aopGet(AOP(result),0,FALSE,FALSE));
3134 pic14_emitcode("call","genMultLit");
3136 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3137 aopGet(AOP(right),0,FALSE,FALSE),
3138 aopGet(AOP(left),0,FALSE,FALSE),
3139 aopGet(AOP(result),0,FALSE,FALSE));
3140 pic14_emitcode("call","genMult8X8_8");
3143 genMult8X8_8 (left, right,result);
3146 /* signed or unsigned */
3147 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3148 //l = aopGet(AOP(left),0,FALSE,FALSE);
3150 //pic14_emitcode("mul","ab");
3151 /* if result size = 1, mul signed = mul unsigned */
3152 //aopPut(AOP(result),"a",0);
3154 } else { // (size > 1)
3156 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3157 aopGet(AOP(right),0,FALSE,FALSE),
3158 aopGet(AOP(left),0,FALSE,FALSE),
3159 aopGet(AOP(result),0,FALSE,FALSE));
3161 if (SPEC_USIGN(opetype)){
3162 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3163 genUMult8X8_16 (left, right, result, NULL);
3166 /* for filling the MSBs */
3167 emitpcode(POC_CLRF, popGet(AOP(result),2));
3168 emitpcode(POC_CLRF, popGet(AOP(result),3));
3172 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3174 pic14_emitcode("mov","a,b");
3176 /* adjust the MSB if left or right neg */
3178 /* if one literal */
3179 if (AOP_TYPE(right) == AOP_LIT){
3180 pic14_emitcode("multiply ","right is a lit");
3181 /* AND literal negative */
3182 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3183 /* adjust MSB (c==0 after mul) */
3184 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3188 genSMult8X8_16 (left, right, result, NULL);
3192 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3194 pic14_emitcode("rlc","a");
3195 pic14_emitcode("subb","a,acc");
3203 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3204 //aopPut(AOP(result),"a",offset++);
3208 /*-----------------------------------------------------------------*/
3209 /* genMult - generates code for multiplication */
3210 /*-----------------------------------------------------------------*/
3211 static void genMult (iCode *ic)
3213 operand *left = IC_LEFT(ic);
3214 operand *right = IC_RIGHT(ic);
3215 operand *result= IC_RESULT(ic);
3217 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3218 /* assign the amsops */
3219 aopOp (left,ic,FALSE);
3220 aopOp (right,ic,FALSE);
3221 aopOp (result,ic,TRUE);
3223 DEBUGpic14_AopType(__LINE__,left,right,result);
3225 /* special cases first */
3227 if (AOP_TYPE(left) == AOP_CRY &&
3228 AOP_TYPE(right)== AOP_CRY) {
3229 genMultbits(left,right,result);
3233 /* if both are of size == 1 */
3234 if (AOP_SIZE(left) == 1 &&
3235 AOP_SIZE(right) == 1 ) {
3236 genMultOneByte(left,right,result);
3240 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3242 /* should have been converted to function call */
3246 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3247 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3248 freeAsmop(result,NULL,ic,TRUE);
3251 /*-----------------------------------------------------------------*/
3252 /* genDivbits :- division of bits */
3253 /*-----------------------------------------------------------------*/
3254 static void genDivbits (operand *left,
3261 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3262 /* the result must be bit */
3263 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3264 l = aopGet(AOP(left),0,FALSE,FALSE);
3268 pic14_emitcode("div","ab");
3269 pic14_emitcode("rrc","a");
3270 aopPut(AOP(result),"c",0);
3273 /*-----------------------------------------------------------------*/
3274 /* genDivOneByte : 8 bit division */
3275 /*-----------------------------------------------------------------*/
3276 static void genDivOneByte (operand *left,
3280 sym_link *opetype = operandType(result);
3285 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3286 size = AOP_SIZE(result) - 1;
3288 /* signed or unsigned */
3289 if (SPEC_USIGN(opetype)) {
3290 /* unsigned is easy */
3291 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3292 l = aopGet(AOP(left),0,FALSE,FALSE);
3294 pic14_emitcode("div","ab");
3295 aopPut(AOP(result),"a",0);
3297 aopPut(AOP(result),zero,offset++);
3301 /* signed is a little bit more difficult */
3303 /* save the signs of the operands */
3304 l = aopGet(AOP(left),0,FALSE,FALSE);
3306 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3307 pic14_emitcode("push","acc"); /* save it on the stack */
3309 /* now sign adjust for both left & right */
3310 l = aopGet(AOP(right),0,FALSE,FALSE);
3312 lbl = newiTempLabel(NULL);
3313 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3314 pic14_emitcode("cpl","a");
3315 pic14_emitcode("inc","a");
3316 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3317 pic14_emitcode("mov","b,a");
3319 /* sign adjust left side */
3320 l = aopGet(AOP(left),0,FALSE,FALSE);
3323 lbl = newiTempLabel(NULL);
3324 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3325 pic14_emitcode("cpl","a");
3326 pic14_emitcode("inc","a");
3327 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3329 /* now the division */
3330 pic14_emitcode("div","ab");
3331 /* we are interested in the lower order
3333 pic14_emitcode("mov","b,a");
3334 lbl = newiTempLabel(NULL);
3335 pic14_emitcode("pop","acc");
3336 /* if there was an over flow we don't
3337 adjust the sign of the result */
3338 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3339 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3341 pic14_emitcode("clr","a");
3342 pic14_emitcode("subb","a,b");
3343 pic14_emitcode("mov","b,a");
3344 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3346 /* now we are done */
3347 aopPut(AOP(result),"b",0);
3349 pic14_emitcode("mov","c,b.7");
3350 pic14_emitcode("subb","a,acc");
3353 aopPut(AOP(result),"a",offset++);
3357 /*-----------------------------------------------------------------*/
3358 /* genDiv - generates code for division */
3359 /*-----------------------------------------------------------------*/
3360 static void genDiv (iCode *ic)
3362 operand *left = IC_LEFT(ic);
3363 operand *right = IC_RIGHT(ic);
3364 operand *result= IC_RESULT(ic);
3366 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3367 /* assign the amsops */
3368 aopOp (left,ic,FALSE);
3369 aopOp (right,ic,FALSE);
3370 aopOp (result,ic,TRUE);
3372 /* special cases first */
3374 if (AOP_TYPE(left) == AOP_CRY &&
3375 AOP_TYPE(right)== AOP_CRY) {
3376 genDivbits(left,right,result);
3380 /* if both are of size == 1 */
3381 if (AOP_SIZE(left) == 1 &&
3382 AOP_SIZE(right) == 1 ) {
3383 genDivOneByte(left,right,result);
3387 /* should have been converted to function call */
3390 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3391 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3392 freeAsmop(result,NULL,ic,TRUE);
3395 /*-----------------------------------------------------------------*/
3396 /* genModbits :- modulus of bits */
3397 /*-----------------------------------------------------------------*/
3398 static void genModbits (operand *left,
3405 /* the result must be bit */
3406 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3407 l = aopGet(AOP(left),0,FALSE,FALSE);
3411 pic14_emitcode("div","ab");
3412 pic14_emitcode("mov","a,b");
3413 pic14_emitcode("rrc","a");
3414 aopPut(AOP(result),"c",0);
3417 /*-----------------------------------------------------------------*/
3418 /* genModOneByte : 8 bit modulus */
3419 /*-----------------------------------------------------------------*/
3420 static void genModOneByte (operand *left,
3424 sym_link *opetype = operandType(result);
3428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3429 /* signed or unsigned */
3430 if (SPEC_USIGN(opetype)) {
3431 /* unsigned is easy */
3432 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3433 l = aopGet(AOP(left),0,FALSE,FALSE);
3435 pic14_emitcode("div","ab");
3436 aopPut(AOP(result),"b",0);
3440 /* signed is a little bit more difficult */
3442 /* save the signs of the operands */
3443 l = aopGet(AOP(left),0,FALSE,FALSE);
3446 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3447 pic14_emitcode("push","acc"); /* save it on the stack */
3449 /* now sign adjust for both left & right */
3450 l = aopGet(AOP(right),0,FALSE,FALSE);
3453 lbl = newiTempLabel(NULL);
3454 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3455 pic14_emitcode("cpl","a");
3456 pic14_emitcode("inc","a");
3457 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3458 pic14_emitcode("mov","b,a");
3460 /* sign adjust left side */
3461 l = aopGet(AOP(left),0,FALSE,FALSE);
3464 lbl = newiTempLabel(NULL);
3465 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3466 pic14_emitcode("cpl","a");
3467 pic14_emitcode("inc","a");
3468 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3470 /* now the multiplication */
3471 pic14_emitcode("div","ab");
3472 /* we are interested in the lower order
3474 lbl = newiTempLabel(NULL);
3475 pic14_emitcode("pop","acc");
3476 /* if there was an over flow we don't
3477 adjust the sign of the result */
3478 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3479 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3481 pic14_emitcode("clr","a");
3482 pic14_emitcode("subb","a,b");
3483 pic14_emitcode("mov","b,a");
3484 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3486 /* now we are done */
3487 aopPut(AOP(result),"b",0);
3491 /*-----------------------------------------------------------------*/
3492 /* genMod - generates code for division */
3493 /*-----------------------------------------------------------------*/
3494 static void genMod (iCode *ic)
3496 operand *left = IC_LEFT(ic);
3497 operand *right = IC_RIGHT(ic);
3498 operand *result= IC_RESULT(ic);
3500 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3501 /* assign the amsops */
3502 aopOp (left,ic,FALSE);
3503 aopOp (right,ic,FALSE);
3504 aopOp (result,ic,TRUE);
3506 /* special cases first */
3508 if (AOP_TYPE(left) == AOP_CRY &&
3509 AOP_TYPE(right)== AOP_CRY) {
3510 genModbits(left,right,result);
3514 /* if both are of size == 1 */
3515 if (AOP_SIZE(left) == 1 &&
3516 AOP_SIZE(right) == 1 ) {
3517 genModOneByte(left,right,result);
3521 /* should have been converted to function call */
3525 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3526 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3527 freeAsmop(result,NULL,ic,TRUE);
3530 /*-----------------------------------------------------------------*/
3531 /* genIfxJump :- will create a jump depending on the ifx */
3532 /*-----------------------------------------------------------------*/
3534 note: May need to add parameter to indicate when a variable is in bit space.
3536 static void genIfxJump (iCode *ic, char *jval)
3539 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3540 /* if true label then we jump if condition
3542 if ( IC_TRUE(ic) ) {
3544 if(strcmp(jval,"a") == 0)
3546 else if (strcmp(jval,"c") == 0)
3549 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3550 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3553 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3554 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3558 /* false label is present */
3559 if(strcmp(jval,"a") == 0)
3561 else if (strcmp(jval,"c") == 0)
3564 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3565 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3568 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3569 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3574 /* mark the icode as generated */
3578 /*-----------------------------------------------------------------*/
3580 /*-----------------------------------------------------------------*/
3581 static void genSkip(iCode *ifx,int status_bit)
3586 if ( IC_TRUE(ifx) ) {
3587 switch(status_bit) {
3602 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3603 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3607 switch(status_bit) {
3621 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3622 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3628 /*-----------------------------------------------------------------*/
3630 /*-----------------------------------------------------------------*/
3631 static void genSkipc(resolvedIfx *rifx)
3641 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3642 rifx->generated = 1;
3645 /*-----------------------------------------------------------------*/
3647 /*-----------------------------------------------------------------*/
3648 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3653 if( (rifx->condition ^ invert_condition) & 1)
3658 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3659 rifx->generated = 1;
3662 /*-----------------------------------------------------------------*/
3664 /*-----------------------------------------------------------------*/
3665 static void genSkipz(iCode *ifx, int condition)
3676 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3678 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3681 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3683 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3686 /*-----------------------------------------------------------------*/
3688 /*-----------------------------------------------------------------*/
3689 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3695 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3697 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3700 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3701 rifx->generated = 1;
3705 /*-----------------------------------------------------------------*/
3706 /* genChkZeroes :- greater or less than comparison */
3707 /* For each byte in a literal that is zero, inclusive or the */
3708 /* the corresponding byte in the operand with W */
3709 /* returns true if any of the bytes are zero */
3710 /*-----------------------------------------------------------------*/
3711 static int genChkZeroes(operand *op, int lit, int size)
3718 i = (lit >> (size*8)) & 0xff;
3722 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3724 emitpcode(POC_IORFW, popGet(AOP(op),size));
3733 /*-----------------------------------------------------------------*/
3734 /* genCmp :- greater or less than comparison */
3735 /*-----------------------------------------------------------------*/
3736 static void genCmp (operand *left,operand *right,
3737 operand *result, iCode *ifx, int sign)
3739 int size; //, offset = 0 ;
3740 unsigned long lit = 0L,i = 0;
3741 resolvedIfx rFalseIfx;
3742 // resolvedIfx rTrueIfx;
3744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3747 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3748 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3752 resolveIfx(&rFalseIfx,ifx);
3753 truelbl = newiTempLabel(NULL);
3754 size = max(AOP_SIZE(left),AOP_SIZE(right));
3756 DEBUGpic14_AopType(__LINE__,left,right,result);
3760 /* if literal is on the right then swap with left */
3761 if ((AOP_TYPE(right) == AOP_LIT)) {
3762 operand *tmp = right ;
3763 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3764 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3767 lit = (lit - 1) & mask;
3770 rFalseIfx.condition ^= 1;
3773 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3774 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3778 //if(IC_TRUE(ifx) == NULL)
3779 /* if left & right are bit variables */
3780 if (AOP_TYPE(left) == AOP_CRY &&
3781 AOP_TYPE(right) == AOP_CRY ) {
3782 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3783 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3785 /* subtract right from left if at the
3786 end the carry flag is set then we know that
3787 left is greater than right */
3791 symbol *lbl = newiTempLabel(NULL);
3794 if(AOP_TYPE(right) == AOP_LIT) {
3796 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3798 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3805 genSkipCond(&rFalseIfx,left,size-1,7);
3807 /* no need to compare to 0...*/
3808 /* NOTE: this is a de-generate compare that most certainly
3809 * creates some dead code. */
3810 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3812 if(ifx) ifx->generated = 1;
3819 //i = (lit >> (size*8)) & 0xff;
3820 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3822 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3824 i = ((0-lit) & 0xff);
3827 /* lit is 0x7f, all signed chars are less than
3828 * this except for 0x7f itself */
3829 emitpcode(POC_XORLW, popGetLit(0x7f));
3830 genSkipz2(&rFalseIfx,0);
3832 emitpcode(POC_ADDLW, popGetLit(0x80));
3833 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3834 genSkipc(&rFalseIfx);
3839 genSkipz2(&rFalseIfx,1);
3841 emitpcode(POC_ADDLW, popGetLit(i));
3842 genSkipc(&rFalseIfx);
3846 if(ifx) ifx->generated = 1;
3850 /* chars are out of the way. now do ints and longs */
3853 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3860 genSkipCond(&rFalseIfx,left,size,7);
3861 if(ifx) ifx->generated = 1;
3866 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3868 //rFalseIfx.condition ^= 1;
3869 //genSkipCond(&rFalseIfx,left,size,7);
3870 //rFalseIfx.condition ^= 1;
3872 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3873 if(rFalseIfx.condition)
3874 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3876 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3878 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3879 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3880 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3883 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3885 if(rFalseIfx.condition) {
3887 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3893 genSkipc(&rFalseIfx);
3894 emitpLabel(truelbl->key);
3895 if(ifx) ifx->generated = 1;
3902 if( (lit & 0xff) == 0) {
3903 /* lower byte is zero */
3904 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3905 i = ((lit >> 8) & 0xff) ^0x80;
3906 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3907 emitpcode(POC_ADDLW, popGetLit( 0x80));
3908 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3909 genSkipc(&rFalseIfx);
3912 if(ifx) ifx->generated = 1;
3917 /* Special cases for signed longs */
3918 if( (lit & 0xffffff) == 0) {
3919 /* lower byte is zero */
3920 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3921 i = ((lit >> 8*3) & 0xff) ^0x80;
3922 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3923 emitpcode(POC_ADDLW, popGetLit( 0x80));
3924 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3925 genSkipc(&rFalseIfx);
3928 if(ifx) ifx->generated = 1;
3936 if(lit & (0x80 << (size*8))) {
3937 /* lit is negative */
3938 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3940 //genSkipCond(&rFalseIfx,left,size,7);
3942 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3944 if(rFalseIfx.condition)
3945 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3947 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3951 /* lit is positive */
3952 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3953 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3954 if(rFalseIfx.condition)
3955 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3957 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3962 This works, but is only good for ints.
3963 It also requires a "known zero" register.
3964 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3965 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3966 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3967 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3968 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3969 genSkipc(&rFalseIfx);
3971 emitpLabel(truelbl->key);
3972 if(ifx) ifx->generated = 1;
3976 /* There are no more special cases, so perform a general compare */
3978 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3979 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3983 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3985 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3987 //rFalseIfx.condition ^= 1;
3988 genSkipc(&rFalseIfx);
3990 emitpLabel(truelbl->key);
3992 if(ifx) ifx->generated = 1;
3999 /* sign is out of the way. So now do an unsigned compare */
4000 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4003 /* General case - compare to an unsigned literal on the right.*/
4005 i = (lit >> (size*8)) & 0xff;
4006 emitpcode(POC_MOVLW, popGetLit(i));
4007 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4009 i = (lit >> (size*8)) & 0xff;
4012 emitpcode(POC_MOVLW, popGetLit(i));
4014 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4016 /* this byte of the lit is zero,
4017 *if it's not the last then OR in the variable */
4019 emitpcode(POC_IORFW, popGet(AOP(left),size));
4024 emitpLabel(lbl->key);
4025 //if(emitFinalCheck)
4026 genSkipc(&rFalseIfx);
4028 emitpLabel(truelbl->key);
4030 if(ifx) ifx->generated = 1;
4037 if(AOP_TYPE(left) == AOP_LIT) {
4038 //symbol *lbl = newiTempLabel(NULL);
4040 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4043 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4046 if((lit == 0) && (sign == 0)){
4049 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4051 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4053 genSkipz2(&rFalseIfx,0);
4054 if(ifx) ifx->generated = 1;
4061 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4062 /* degenerate compare can never be true */
4063 if(rFalseIfx.condition == 0)
4064 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4066 if(ifx) ifx->generated = 1;
4071 /* signed comparisons to a literal byte */
4073 int lp1 = (lit+1) & 0xff;
4075 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4078 rFalseIfx.condition ^= 1;
4079 genSkipCond(&rFalseIfx,right,0,7);
4082 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4083 emitpcode(POC_XORLW, popGetLit(0x7f));
4084 genSkipz2(&rFalseIfx,1);
4087 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4088 emitpcode(POC_ADDLW, popGetLit(0x80));
4089 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4090 rFalseIfx.condition ^= 1;
4091 genSkipc(&rFalseIfx);
4094 if(ifx) ifx->generated = 1;
4096 /* unsigned comparisons to a literal byte */
4098 switch(lit & 0xff ) {
4100 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4101 genSkipz2(&rFalseIfx,0);
4102 if(ifx) ifx->generated = 1;
4105 rFalseIfx.condition ^= 1;
4106 genSkipCond(&rFalseIfx,right,0,7);
4107 if(ifx) ifx->generated = 1;
4111 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4112 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4114 rFalseIfx.condition ^= 1;
4115 if (AOP_TYPE(result) == AOP_CRY) {
4116 genSkipc(&rFalseIfx);
4117 if(ifx) ifx->generated = 1;
4119 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4120 emitpcode(POC_CLRF, popGet(AOP(result),0));
4121 emitpcode(POC_RLF, popGet(AOP(result),0));
4122 emitpcode(POC_MOVLW, popGetLit(0x01));
4123 emitpcode(POC_XORWF, popGet(AOP(result),0));
4134 /* Size is greater than 1 */
4142 /* this means lit = 0xffffffff, or -1 */
4145 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4146 rFalseIfx.condition ^= 1;
4147 genSkipCond(&rFalseIfx,right,size,7);
4148 if(ifx) ifx->generated = 1;
4155 if(rFalseIfx.condition) {
4156 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4157 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4160 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4162 emitpcode(POC_IORFW, popGet(AOP(right),size));
4166 if(rFalseIfx.condition) {
4167 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4168 emitpLabel(truelbl->key);
4170 rFalseIfx.condition ^= 1;
4171 genSkipCond(&rFalseIfx,right,s,7);
4174 if(ifx) ifx->generated = 1;
4178 if((size == 1) && (0 == (lp1&0xff))) {
4179 /* lower byte of signed word is zero */
4180 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4181 i = ((lp1 >> 8) & 0xff) ^0x80;
4182 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4183 emitpcode(POC_ADDLW, popGetLit( 0x80));
4184 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4185 rFalseIfx.condition ^= 1;
4186 genSkipc(&rFalseIfx);
4189 if(ifx) ifx->generated = 1;
4193 if(lit & (0x80 << (size*8))) {
4194 /* Lit is less than zero */
4195 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4196 //rFalseIfx.condition ^= 1;
4197 //genSkipCond(&rFalseIfx,left,size,7);
4198 //rFalseIfx.condition ^= 1;
4199 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4200 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4202 if(rFalseIfx.condition)
4203 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4205 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4209 /* Lit is greater than or equal to zero */
4210 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4211 //rFalseIfx.condition ^= 1;
4212 //genSkipCond(&rFalseIfx,right,size,7);
4213 //rFalseIfx.condition ^= 1;
4215 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4216 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4218 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4219 if(rFalseIfx.condition)
4220 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4222 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4227 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4228 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4232 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4234 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4236 rFalseIfx.condition ^= 1;
4237 //rFalseIfx.condition = 1;
4238 genSkipc(&rFalseIfx);
4240 emitpLabel(truelbl->key);
4242 if(ifx) ifx->generated = 1;
4247 /* compare word or long to an unsigned literal on the right.*/
4252 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4255 break; /* handled above */
4258 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4260 emitpcode(POC_IORFW, popGet(AOP(right),size));
4261 genSkipz2(&rFalseIfx,0);
4265 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4267 emitpcode(POC_IORFW, popGet(AOP(right),size));
4270 if(rFalseIfx.condition)
4271 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4273 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4276 emitpcode(POC_MOVLW, popGetLit(lit+1));
4277 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4279 rFalseIfx.condition ^= 1;
4280 genSkipc(&rFalseIfx);
4283 emitpLabel(truelbl->key);
4285 if(ifx) ifx->generated = 1;
4291 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4292 i = (lit >> (size*8)) & 0xff;
4294 emitpcode(POC_MOVLW, popGetLit(i));
4295 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4298 i = (lit >> (size*8)) & 0xff;
4301 emitpcode(POC_MOVLW, popGetLit(i));
4303 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4305 /* this byte of the lit is zero,
4306 *if it's not the last then OR in the variable */
4308 emitpcode(POC_IORFW, popGet(AOP(right),size));
4313 emitpLabel(lbl->key);
4315 rFalseIfx.condition ^= 1;
4316 genSkipc(&rFalseIfx);
4320 emitpLabel(truelbl->key);
4321 if(ifx) ifx->generated = 1;
4325 /* Compare two variables */
4327 DEBUGpic14_emitcode(";sign","%d",sign);
4331 /* Sigh. thus sucks... */
4333 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4334 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4335 emitpcode(POC_MOVLW, popGetLit(0x80));
4336 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4337 emitpcode(POC_XORFW, popGet(AOP(right),size));
4338 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4340 /* Signed char comparison */
4341 /* Special thanks to Nikolai Golovchenko for this snippet */
4342 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4343 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4344 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4345 emitpcode(POC_XORFW, popGet(AOP(left),0));
4346 emitpcode(POC_XORFW, popGet(AOP(right),0));
4347 emitpcode(POC_ADDLW, popGetLit(0x80));
4349 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4350 genSkipc(&rFalseIfx);
4352 if(ifx) ifx->generated = 1;
4358 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4359 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4363 /* The rest of the bytes of a multi-byte compare */
4367 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4370 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4371 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4376 emitpLabel(lbl->key);
4378 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4379 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4380 (AOP_TYPE(result) == AOP_REG)) {
4381 emitpcode(POC_CLRF, popGet(AOP(result),0));
4382 emitpcode(POC_RLF, popGet(AOP(result),0));
4384 genSkipc(&rFalseIfx);
4386 //genSkipc(&rFalseIfx);
4387 if(ifx) ifx->generated = 1;
4394 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4395 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4396 pic14_outBitC(result);
4398 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4399 /* if the result is used in the next
4400 ifx conditional branch then generate
4401 code a little differently */
4403 genIfxJump (ifx,"c");
4405 pic14_outBitC(result);
4406 /* leave the result in acc */
4411 /*-----------------------------------------------------------------*/
4412 /* genCmpGt :- greater than comparison */
4413 /*-----------------------------------------------------------------*/
4414 static void genCmpGt (iCode *ic, iCode *ifx)
4416 operand *left, *right, *result;
4417 sym_link *letype , *retype;
4420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4422 right= IC_RIGHT(ic);
4423 result = IC_RESULT(ic);
4425 letype = getSpec(operandType(left));
4426 retype =getSpec(operandType(right));
4427 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4428 /* assign the amsops */
4429 aopOp (left,ic,FALSE);
4430 aopOp (right,ic,FALSE);
4431 aopOp (result,ic,TRUE);
4433 genCmp(right, left, result, ifx, sign);
4435 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4436 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4437 freeAsmop(result,NULL,ic,TRUE);
4440 /*-----------------------------------------------------------------*/
4441 /* genCmpLt - less than comparisons */
4442 /*-----------------------------------------------------------------*/
4443 static void genCmpLt (iCode *ic, iCode *ifx)
4445 operand *left, *right, *result;
4446 sym_link *letype , *retype;
4449 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4451 right= IC_RIGHT(ic);
4452 result = IC_RESULT(ic);
4454 letype = getSpec(operandType(left));
4455 retype =getSpec(operandType(right));
4456 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4458 /* assign the amsops */
4459 aopOp (left,ic,FALSE);
4460 aopOp (right,ic,FALSE);
4461 aopOp (result,ic,TRUE);
4463 genCmp(left, right, result, ifx, sign);
4465 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4466 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4467 freeAsmop(result,NULL,ic,TRUE);
4470 /*-----------------------------------------------------------------*/
4471 /* genc16bit2lit - compare a 16 bit value to a literal */
4472 /*-----------------------------------------------------------------*/
4473 static void genc16bit2lit(operand *op, int lit, int offset)
4477 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4478 if( (lit&0xff) == 0)
4483 switch( BYTEofLONG(lit,i)) {
4485 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4488 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4491 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4494 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4495 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4500 switch( BYTEofLONG(lit,i)) {
4502 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4506 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4510 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4513 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4515 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4521 /*-----------------------------------------------------------------*/
4522 /* gencjneshort - compare and jump if not equal */
4523 /*-----------------------------------------------------------------*/
4524 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4526 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4528 int res_offset = 0; /* the result may be a different size then left or right */
4529 int res_size = AOP_SIZE(result);
4533 unsigned long lit = 0L;
4534 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4535 DEBUGpic14_AopType(__LINE__,left,right,result);
4537 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4538 resolveIfx(&rIfx,ifx);
4539 lbl = newiTempLabel(NULL);
4542 /* if the left side is a literal or
4543 if the right is in a pointer register and left
4545 if ((AOP_TYPE(left) == AOP_LIT) ||
4546 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4551 if(AOP_TYPE(right) == AOP_LIT)
4552 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4554 /* if the right side is a literal then anything goes */
4555 if (AOP_TYPE(right) == AOP_LIT &&
4556 AOP_TYPE(left) != AOP_DIR ) {
4559 genc16bit2lit(left, lit, 0);
4561 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4566 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4567 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4569 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4573 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4575 if(res_offset < res_size-1)
4583 /* if the right side is in a register or in direct space or
4584 if the left is a pointer register & right is not */
4585 else if (AOP_TYPE(right) == AOP_REG ||
4586 AOP_TYPE(right) == AOP_DIR ||
4587 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4588 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4589 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4590 int lbl_key = lbl->key;
4593 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4594 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4596 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4597 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4598 __FUNCTION__,__LINE__);
4602 /* switch(size) { */
4604 /* genc16bit2lit(left, lit, 0); */
4606 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4611 if((AOP_TYPE(left) == AOP_DIR) &&
4612 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4614 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4615 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4617 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4619 switch (lit & 0xff) {
4621 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4624 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4625 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4626 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4630 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4631 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4632 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4633 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4637 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4638 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4643 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4646 if(AOP_TYPE(result) == AOP_CRY) {
4647 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4652 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4654 /* fix me. probably need to check result size too */
4655 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4660 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4661 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4668 if(res_offset < res_size-1)
4673 } else if(AOP_TYPE(right) == AOP_REG &&
4674 AOP_TYPE(left) != AOP_DIR){
4677 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4678 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4679 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4684 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4686 if(res_offset < res_size-1)
4691 /* right is a pointer reg need both a & b */
4693 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4695 pic14_emitcode("mov","b,%s",l);
4696 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4697 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4702 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4704 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4706 emitpLabel(lbl->key);
4708 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4715 /*-----------------------------------------------------------------*/
4716 /* gencjne - compare and jump if not equal */
4717 /*-----------------------------------------------------------------*/
4718 static void gencjne(operand *left, operand *right, iCode *ifx)
4720 symbol *tlbl = newiTempLabel(NULL);
4722 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4723 gencjneshort(left, right, lbl);
4725 pic14_emitcode("mov","a,%s",one);
4726 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4727 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4728 pic14_emitcode("clr","a");
4729 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4731 emitpLabel(lbl->key);
4732 emitpLabel(tlbl->key);
4737 /*-----------------------------------------------------------------*/
4738 /* genCmpEq - generates code for equal to */
4739 /*-----------------------------------------------------------------*/
4740 static void genCmpEq (iCode *ic, iCode *ifx)
4742 operand *left, *right, *result;
4743 unsigned long lit = 0L;
4746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4749 DEBUGpic14_emitcode ("; ifx is non-null","");
4751 DEBUGpic14_emitcode ("; ifx is null","");
4753 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4754 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4755 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4757 size = max(AOP_SIZE(left),AOP_SIZE(right));
4759 DEBUGpic14_AopType(__LINE__,left,right,result);
4761 /* if literal, literal on the right or
4762 if the right is in a pointer register and left
4764 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4765 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4766 operand *tmp = right ;
4772 if(ifx && !AOP_SIZE(result)){
4774 /* if they are both bit variables */
4775 if (AOP_TYPE(left) == AOP_CRY &&
4776 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4777 if(AOP_TYPE(right) == AOP_LIT){
4778 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4780 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4781 pic14_emitcode("cpl","c");
4782 } else if(lit == 1L) {
4783 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4785 pic14_emitcode("clr","c");
4787 /* AOP_TYPE(right) == AOP_CRY */
4789 symbol *lbl = newiTempLabel(NULL);
4790 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4791 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4792 pic14_emitcode("cpl","c");
4793 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4795 /* if true label then we jump if condition
4797 tlbl = newiTempLabel(NULL);
4798 if ( IC_TRUE(ifx) ) {
4799 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4800 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4802 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4803 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4805 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4808 /* left and right are both bit variables, result is carry */
4811 resolveIfx(&rIfx,ifx);
4813 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4814 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4815 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4816 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4821 /* They're not both bit variables. Is the right a literal? */
4822 if(AOP_TYPE(right) == AOP_LIT) {
4823 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4828 switch(lit & 0xff) {
4830 if ( IC_TRUE(ifx) ) {
4831 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4833 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4835 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4836 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4840 if ( IC_TRUE(ifx) ) {
4841 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4843 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4845 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4846 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4850 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4852 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4857 /* end of size == 1 */
4861 genc16bit2lit(left,lit,offset);
4864 /* end of size == 2 */
4869 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4870 emitpcode(POC_IORFW,popGet(AOP(left),1));
4871 emitpcode(POC_IORFW,popGet(AOP(left),2));
4872 emitpcode(POC_IORFW,popGet(AOP(left),3));
4876 /* search for patterns that can be optimized */
4878 genc16bit2lit(left,lit,0);
4881 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4883 genc16bit2lit(left,lit,2);
4885 emitpcode(POC_IORFW,popGet(AOP(left),2));
4886 emitpcode(POC_IORFW,popGet(AOP(left),3));
4899 } else if(AOP_TYPE(right) == AOP_CRY ) {
4900 /* we know the left is not a bit, but that the right is */
4901 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4902 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4903 popGet(AOP(right),offset));
4904 emitpcode(POC_XORLW,popGetLit(1));
4906 /* if the two are equal, then W will be 0 and the Z bit is set
4907 * we could test Z now, or go ahead and check the high order bytes if
4908 * the variable we're comparing is larger than a byte. */
4911 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4913 if ( IC_TRUE(ifx) ) {
4915 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4916 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4919 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4920 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4924 /* They're both variables that are larger than bits */
4927 tlbl = newiTempLabel(NULL);
4930 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4931 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4933 if ( IC_TRUE(ifx) ) {
4936 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4937 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4940 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4941 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4945 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4946 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4950 if(s>1 && IC_TRUE(ifx)) {
4951 emitpLabel(tlbl->key);
4952 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4956 /* mark the icode as generated */
4961 /* if they are both bit variables */
4962 if (AOP_TYPE(left) == AOP_CRY &&
4963 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4964 if(AOP_TYPE(right) == AOP_LIT){
4965 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4967 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4968 pic14_emitcode("cpl","c");
4969 } else if(lit == 1L) {
4970 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4972 pic14_emitcode("clr","c");
4974 /* AOP_TYPE(right) == AOP_CRY */
4976 symbol *lbl = newiTempLabel(NULL);
4977 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4978 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4979 pic14_emitcode("cpl","c");
4980 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4983 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4984 pic14_outBitC(result);
4988 genIfxJump (ifx,"c");
4991 /* if the result is used in an arithmetic operation
4992 then put the result in place */
4993 pic14_outBitC(result);
4996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4997 gencjne(left,right,result,ifx);
5000 gencjne(left,right,newiTempLabel(NULL));
5002 if(IC_TRUE(ifx)->key)
5003 gencjne(left,right,IC_TRUE(ifx)->key);
5005 gencjne(left,right,IC_FALSE(ifx)->key);
5009 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5010 aopPut(AOP(result),"a",0);
5015 genIfxJump (ifx,"a");
5019 /* if the result is used in an arithmetic operation
5020 then put the result in place */
5022 if (AOP_TYPE(result) != AOP_CRY)
5023 pic14_outAcc(result);
5025 /* leave the result in acc */
5029 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5030 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5031 freeAsmop(result,NULL,ic,TRUE);
5034 /*-----------------------------------------------------------------*/
5035 /* ifxForOp - returns the icode containing the ifx for operand */
5036 /*-----------------------------------------------------------------*/
5037 static iCode *ifxForOp ( operand *op, iCode *ic )
5039 /* if true symbol then needs to be assigned */
5040 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5041 if (IS_TRUE_SYMOP(op))
5044 /* if this has register type condition and
5045 the next instruction is ifx with the same operand
5046 and live to of the operand is upto the ifx only then */
5048 ic->next->op == IFX &&
5049 IC_COND(ic->next)->key == op->key &&
5050 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5054 ic->next->op == IFX &&
5055 IC_COND(ic->next)->key == op->key) {
5056 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5060 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5062 ic->next->op == IFX)
5063 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5066 ic->next->op == IFX &&
5067 IC_COND(ic->next)->key == op->key) {
5068 DEBUGpic14_emitcode ("; "," key is okay");
5069 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5070 OP_SYMBOL(op)->liveTo,
5077 /*-----------------------------------------------------------------*/
5078 /* genAndOp - for && operation */
5079 /*-----------------------------------------------------------------*/
5080 static void genAndOp (iCode *ic)
5082 operand *left,*right, *result;
5085 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5086 /* note here that && operations that are in an
5087 if statement are taken away by backPatchLabels
5088 only those used in arthmetic operations remain */
5089 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5090 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5091 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5093 DEBUGpic14_AopType(__LINE__,left,right,result);
5095 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5096 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5097 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5099 /* if both are bit variables */
5100 /* if (AOP_TYPE(left) == AOP_CRY && */
5101 /* AOP_TYPE(right) == AOP_CRY ) { */
5102 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5103 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5104 /* pic14_outBitC(result); */
5106 /* tlbl = newiTempLabel(NULL); */
5107 /* pic14_toBoolean(left); */
5108 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5109 /* pic14_toBoolean(right); */
5110 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5111 /* pic14_outBitAcc(result); */
5114 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5115 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5116 freeAsmop(result,NULL,ic,TRUE);
5120 /*-----------------------------------------------------------------*/
5121 /* genOrOp - for || operation */
5122 /*-----------------------------------------------------------------*/
5125 modified this code, but it doesn't appear to ever get called
5128 static void genOrOp (iCode *ic)
5130 operand *left,*right, *result;
5133 /* note here that || operations that are in an
5134 if statement are taken away by backPatchLabels
5135 only those used in arthmetic operations remain */
5136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5137 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5138 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5139 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5141 DEBUGpic14_AopType(__LINE__,left,right,result);
5143 /* if both are bit variables */
5144 if (AOP_TYPE(left) == AOP_CRY &&
5145 AOP_TYPE(right) == AOP_CRY ) {
5146 pic14_emitcode("clrc","");
5147 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5148 AOP(left)->aopu.aop_dir,
5149 AOP(left)->aopu.aop_dir);
5150 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5151 AOP(right)->aopu.aop_dir,
5152 AOP(right)->aopu.aop_dir);
5153 pic14_emitcode("setc","");
5156 tlbl = newiTempLabel(NULL);
5157 pic14_toBoolean(left);
5159 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5160 pic14_toBoolean(right);
5161 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5163 pic14_outBitAcc(result);
5166 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5167 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5168 freeAsmop(result,NULL,ic,TRUE);
5171 /*-----------------------------------------------------------------*/
5172 /* isLiteralBit - test if lit == 2^n */
5173 /*-----------------------------------------------------------------*/
5174 static int isLiteralBit(unsigned long lit)
5176 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5177 0x100L,0x200L,0x400L,0x800L,
5178 0x1000L,0x2000L,0x4000L,0x8000L,
5179 0x10000L,0x20000L,0x40000L,0x80000L,
5180 0x100000L,0x200000L,0x400000L,0x800000L,
5181 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5182 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5186 for(idx = 0; idx < 32; idx++)
5192 /*-----------------------------------------------------------------*/
5193 /* continueIfTrue - */
5194 /*-----------------------------------------------------------------*/
5195 static void continueIfTrue (iCode *ic)
5197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5199 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5203 /*-----------------------------------------------------------------*/
5205 /*-----------------------------------------------------------------*/
5206 static void jumpIfTrue (iCode *ic)
5208 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5210 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5214 /*-----------------------------------------------------------------*/
5215 /* jmpTrueOrFalse - */
5216 /*-----------------------------------------------------------------*/
5217 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5219 // ugly but optimized by peephole
5220 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5222 symbol *nlbl = newiTempLabel(NULL);
5223 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5224 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5225 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5226 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5229 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5230 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5235 /*-----------------------------------------------------------------*/
5236 /* genAnd - code for and */
5237 /*-----------------------------------------------------------------*/
5238 static void genAnd (iCode *ic, iCode *ifx)
5240 operand *left, *right, *result;
5242 unsigned long lit = 0L;
5247 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5248 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5249 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5250 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5252 resolveIfx(&rIfx,ifx);
5254 /* if left is a literal & right is not then exchange them */
5255 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5256 AOP_NEEDSACC(left)) {
5257 operand *tmp = right ;
5262 /* if result = right then exchange them */
5263 if(pic14_sameRegs(AOP(result),AOP(right))){
5264 operand *tmp = right ;
5269 /* if right is bit then exchange them */
5270 if (AOP_TYPE(right) == AOP_CRY &&
5271 AOP_TYPE(left) != AOP_CRY){
5272 operand *tmp = right ;
5276 if(AOP_TYPE(right) == AOP_LIT)
5277 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5279 size = AOP_SIZE(result);
5281 DEBUGpic14_AopType(__LINE__,left,right,result);
5284 // result = bit & yy;
5285 if (AOP_TYPE(left) == AOP_CRY){
5286 // c = bit & literal;
5287 if(AOP_TYPE(right) == AOP_LIT){
5289 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5292 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5295 if(size && (AOP_TYPE(result) == AOP_CRY)){
5296 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5299 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5303 pic14_emitcode("clr","c");
5306 if (AOP_TYPE(right) == AOP_CRY){
5308 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5309 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5312 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5314 pic14_emitcode("rrc","a");
5315 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5321 pic14_outBitC(result);
5323 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5324 genIfxJump(ifx, "c");
5328 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5329 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5330 if((AOP_TYPE(right) == AOP_LIT) &&
5331 (AOP_TYPE(result) == AOP_CRY) &&
5332 (AOP_TYPE(left) != AOP_CRY)){
5333 int posbit = isLiteralBit(lit);
5337 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5340 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5346 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5347 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5349 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5350 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5353 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5354 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5355 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5362 symbol *tlbl = newiTempLabel(NULL);
5363 int sizel = AOP_SIZE(left);
5365 pic14_emitcode("setb","c");
5367 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5368 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5370 if((posbit = isLiteralBit(bytelit)) != 0)
5371 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5373 if(bytelit != 0x0FFL)
5374 pic14_emitcode("anl","a,%s",
5375 aopGet(AOP(right),offset,FALSE,TRUE));
5376 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5381 // bit = left & literal
5383 pic14_emitcode("clr","c");
5384 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5386 // if(left & literal)
5389 jmpTrueOrFalse(ifx, tlbl);
5393 pic14_outBitC(result);
5397 /* if left is same as result */
5398 if(pic14_sameRegs(AOP(result),AOP(left))){
5400 for(;size--; offset++,lit>>=8) {
5401 if(AOP_TYPE(right) == AOP_LIT){
5402 switch(lit & 0xff) {
5404 /* and'ing with 0 has clears the result */
5405 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5406 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5409 /* and'ing with 0xff is a nop when the result and left are the same */
5414 int p = my_powof2( (~lit) & 0xff );
5416 /* only one bit is set in the literal, so use a bcf instruction */
5417 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5418 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5421 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5422 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5423 if(know_W != (int)(lit&0xff))
5424 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5426 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5431 if (AOP_TYPE(left) == AOP_ACC) {
5432 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5434 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5435 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5442 // left & result in different registers
5443 if(AOP_TYPE(result) == AOP_CRY){
5445 // if(size), result in bit
5446 // if(!size && ifx), conditional oper: if(left & right)
5447 symbol *tlbl = newiTempLabel(NULL);
5448 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5450 pic14_emitcode("setb","c");
5452 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5453 pic14_emitcode("anl","a,%s",
5454 aopGet(AOP(left),offset,FALSE,FALSE));
5455 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5460 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5461 pic14_outBitC(result);
5463 jmpTrueOrFalse(ifx, tlbl);
5465 for(;(size--);offset++) {
5467 // result = left & right
5468 if(AOP_TYPE(right) == AOP_LIT){
5469 int t = (lit >> (offset*8)) & 0x0FFL;
5472 pic14_emitcode("clrf","%s",
5473 aopGet(AOP(result),offset,FALSE,FALSE));
5474 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5477 if(AOP_TYPE(left) != AOP_ACC) {
5478 pic14_emitcode("movf","%s,w",
5479 aopGet(AOP(left),offset,FALSE,FALSE));
5480 pic14_emitcode("movwf","%s",
5481 aopGet(AOP(result),offset,FALSE,FALSE));
5482 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5484 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5487 if(AOP_TYPE(left) == AOP_ACC) {
5488 emitpcode(POC_ANDLW, popGetLit(t));
5490 pic14_emitcode("movlw","0x%x",t);
5491 pic14_emitcode("andwf","%s,w",
5492 aopGet(AOP(left),offset,FALSE,FALSE));
5493 pic14_emitcode("movwf","%s",
5494 aopGet(AOP(result),offset,FALSE,FALSE));
5496 emitpcode(POC_MOVLW, popGetLit(t));
5497 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5499 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5504 if (AOP_TYPE(left) == AOP_ACC) {
5505 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5506 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5508 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5509 pic14_emitcode("andwf","%s,w",
5510 aopGet(AOP(left),offset,FALSE,FALSE));
5511 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5512 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5514 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5515 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5521 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5522 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5523 freeAsmop(result,NULL,ic,TRUE);
5526 /*-----------------------------------------------------------------*/
5527 /* genOr - code for or */
5528 /*-----------------------------------------------------------------*/
5529 static void genOr (iCode *ic, iCode *ifx)
5531 operand *left, *right, *result;
5533 unsigned long lit = 0L;
5535 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5537 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5538 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5539 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5541 DEBUGpic14_AopType(__LINE__,left,right,result);
5543 /* if left is a literal & right is not then exchange them */
5544 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5545 AOP_NEEDSACC(left)) {
5546 operand *tmp = right ;
5551 /* if result = right then exchange them */
5552 if(pic14_sameRegs(AOP(result),AOP(right))){
5553 operand *tmp = right ;
5558 /* if right is bit then exchange them */
5559 if (AOP_TYPE(right) == AOP_CRY &&
5560 AOP_TYPE(left) != AOP_CRY){
5561 operand *tmp = right ;
5566 DEBUGpic14_AopType(__LINE__,left,right,result);
5568 if(AOP_TYPE(right) == AOP_LIT)
5569 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5571 size = AOP_SIZE(result);
5575 if (AOP_TYPE(left) == AOP_CRY){
5576 if(AOP_TYPE(right) == AOP_LIT){
5577 // c = bit & literal;
5579 // lit != 0 => result = 1
5580 if(AOP_TYPE(result) == AOP_CRY){
5582 emitpcode(POC_BSF, popGet(AOP(result),0));
5583 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5584 // AOP(result)->aopu.aop_dir,
5585 // AOP(result)->aopu.aop_dir);
5587 continueIfTrue(ifx);
5591 // lit == 0 => result = left
5592 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5594 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5597 if (AOP_TYPE(right) == AOP_CRY){
5598 if(pic14_sameRegs(AOP(result),AOP(left))){
5600 emitpcode(POC_BCF, popGet(AOP(result),0));
5601 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5602 emitpcode(POC_BSF, popGet(AOP(result),0));
5604 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5605 AOP(result)->aopu.aop_dir,
5606 AOP(result)->aopu.aop_dir);
5607 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5608 AOP(right)->aopu.aop_dir,
5609 AOP(right)->aopu.aop_dir);
5610 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5611 AOP(result)->aopu.aop_dir,
5612 AOP(result)->aopu.aop_dir);
5614 if( AOP_TYPE(result) == AOP_ACC) {
5615 emitpcode(POC_MOVLW, popGetLit(0));
5616 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5617 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5618 emitpcode(POC_MOVLW, popGetLit(1));
5622 emitpcode(POC_BCF, popGet(AOP(result),0));
5623 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5624 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5625 emitpcode(POC_BSF, popGet(AOP(result),0));
5627 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5628 AOP(result)->aopu.aop_dir,
5629 AOP(result)->aopu.aop_dir);
5630 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5631 AOP(right)->aopu.aop_dir,
5632 AOP(right)->aopu.aop_dir);
5633 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5634 AOP(left)->aopu.aop_dir,
5635 AOP(left)->aopu.aop_dir);
5636 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5637 AOP(result)->aopu.aop_dir,
5638 AOP(result)->aopu.aop_dir);
5643 symbol *tlbl = newiTempLabel(NULL);
5644 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5647 emitpcode(POC_BCF, popGet(AOP(result),0));
5648 if( AOP_TYPE(right) == AOP_ACC) {
5649 emitpcode(POC_IORLW, popGetLit(0));
5651 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5652 emitpcode(POC_BSF, popGet(AOP(result),0));
5657 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5658 pic14_emitcode(";XXX setb","c");
5659 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5660 AOP(left)->aopu.aop_dir,tlbl->key+100);
5661 pic14_toBoolean(right);
5662 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5663 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5664 jmpTrueOrFalse(ifx, tlbl);
5668 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5675 pic14_outBitC(result);
5677 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5678 genIfxJump(ifx, "c");
5682 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5683 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5684 if((AOP_TYPE(right) == AOP_LIT) &&
5685 (AOP_TYPE(result) == AOP_CRY) &&
5686 (AOP_TYPE(left) != AOP_CRY)){
5688 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5691 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5693 continueIfTrue(ifx);
5696 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5697 // lit = 0, result = boolean(left)
5699 pic14_emitcode(";XXX setb","c");
5700 pic14_toBoolean(right);
5702 symbol *tlbl = newiTempLabel(NULL);
5703 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5705 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5707 genIfxJump (ifx,"a");
5711 pic14_outBitC(result);
5715 /* if left is same as result */
5716 if(pic14_sameRegs(AOP(result),AOP(left))){
5718 for(;size--; offset++,lit>>=8) {
5719 if(AOP_TYPE(right) == AOP_LIT){
5720 if((lit & 0xff) == 0)
5721 /* or'ing with 0 has no effect */
5724 int p = my_powof2(lit & 0xff);
5726 /* only one bit is set in the literal, so use a bsf instruction */
5728 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5730 if(know_W != (int)(lit & 0xff))
5731 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5732 know_W = lit & 0xff;
5733 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5738 if (AOP_TYPE(left) == AOP_ACC) {
5739 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5740 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5742 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5743 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5745 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5746 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5752 // left & result in different registers
5753 if(AOP_TYPE(result) == AOP_CRY){
5755 // if(size), result in bit
5756 // if(!size && ifx), conditional oper: if(left | right)
5757 symbol *tlbl = newiTempLabel(NULL);
5758 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5759 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5763 pic14_emitcode(";XXX setb","c");
5765 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5766 pic14_emitcode(";XXX orl","a,%s",
5767 aopGet(AOP(left),offset,FALSE,FALSE));
5768 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5773 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5774 pic14_outBitC(result);
5776 jmpTrueOrFalse(ifx, tlbl);
5777 } else for(;(size--);offset++){
5779 // result = left & right
5780 if(AOP_TYPE(right) == AOP_LIT){
5781 int t = (lit >> (offset*8)) & 0x0FFL;
5784 if (AOP_TYPE(left) != AOP_ACC) {
5785 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5787 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5791 if (AOP_TYPE(left) == AOP_ACC) {
5792 emitpcode(POC_IORLW, popGetLit(t));
5794 emitpcode(POC_MOVLW, popGetLit(t));
5795 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5797 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5802 // faster than result <- left, anl result,right
5803 // and better if result is SFR
5804 if (AOP_TYPE(left) == AOP_ACC) {
5805 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5806 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5808 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5809 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5811 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5812 pic14_emitcode("iorwf","%s,w",
5813 aopGet(AOP(left),offset,FALSE,FALSE));
5815 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5816 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5821 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5822 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5823 freeAsmop(result,NULL,ic,TRUE);
5826 /*-----------------------------------------------------------------*/
5827 /* genXor - code for xclusive or */
5828 /*-----------------------------------------------------------------*/
5829 static void genXor (iCode *ic, iCode *ifx)
5831 operand *left, *right, *result;
5833 unsigned long lit = 0L;
5835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5837 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5838 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5839 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5841 /* if left is a literal & right is not ||
5842 if left needs acc & right does not */
5843 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5844 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5845 operand *tmp = right ;
5850 /* if result = right then exchange them */
5851 if(pic14_sameRegs(AOP(result),AOP(right))){
5852 operand *tmp = right ;
5857 /* if right is bit then exchange them */
5858 if (AOP_TYPE(right) == AOP_CRY &&
5859 AOP_TYPE(left) != AOP_CRY){
5860 operand *tmp = right ;
5864 if(AOP_TYPE(right) == AOP_LIT)
5865 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5867 size = AOP_SIZE(result);
5871 if (AOP_TYPE(left) == AOP_CRY){
5872 if(AOP_TYPE(right) == AOP_LIT){
5873 // c = bit & literal;
5875 // lit>>1 != 0 => result = 1
5876 if(AOP_TYPE(result) == AOP_CRY){
5878 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5879 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5881 continueIfTrue(ifx);
5884 pic14_emitcode("setb","c");
5888 // lit == 0, result = left
5889 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5891 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5893 // lit == 1, result = not(left)
5894 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5895 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5896 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5897 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5900 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5901 pic14_emitcode("cpl","c");
5908 symbol *tlbl = newiTempLabel(NULL);
5909 if (AOP_TYPE(right) == AOP_CRY){
5911 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5914 int sizer = AOP_SIZE(right);
5916 // if val>>1 != 0, result = 1
5917 pic14_emitcode("setb","c");
5919 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5921 // test the msb of the lsb
5922 pic14_emitcode("anl","a,#0xfe");
5923 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5927 pic14_emitcode("rrc","a");
5929 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5930 pic14_emitcode("cpl","c");
5931 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5936 pic14_outBitC(result);
5938 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5939 genIfxJump(ifx, "c");
5943 if(pic14_sameRegs(AOP(result),AOP(left))){
5944 /* if left is same as result */
5945 for(;size--; offset++) {
5946 if(AOP_TYPE(right) == AOP_LIT){
5947 int t = (lit >> (offset*8)) & 0x0FFL;
5951 if (IS_AOP_PREG(left)) {
5952 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5953 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5954 aopPut(AOP(result),"a",offset);
5956 emitpcode(POC_MOVLW, popGetLit(t));
5957 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5958 pic14_emitcode("xrl","%s,%s",
5959 aopGet(AOP(left),offset,FALSE,TRUE),
5960 aopGet(AOP(right),offset,FALSE,FALSE));
5963 if (AOP_TYPE(left) == AOP_ACC)
5964 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5966 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5967 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5969 if (IS_AOP_PREG(left)) {
5970 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5971 aopPut(AOP(result),"a",offset);
5973 pic14_emitcode("xrl","%s,a",
5974 aopGet(AOP(left),offset,FALSE,TRUE));
5980 // left & result in different registers
5981 if(AOP_TYPE(result) == AOP_CRY){
5983 // if(size), result in bit
5984 // if(!size && ifx), conditional oper: if(left ^ right)
5985 symbol *tlbl = newiTempLabel(NULL);
5986 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5988 pic14_emitcode("setb","c");
5990 if((AOP_TYPE(right) == AOP_LIT) &&
5991 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5992 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5994 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5995 pic14_emitcode("xrl","a,%s",
5996 aopGet(AOP(left),offset,FALSE,FALSE));
5998 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6003 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6004 pic14_outBitC(result);
6006 jmpTrueOrFalse(ifx, tlbl);
6007 } else for(;(size--);offset++){
6009 // result = left & right
6010 if(AOP_TYPE(right) == AOP_LIT){
6011 int t = (lit >> (offset*8)) & 0x0FFL;
6014 if (AOP_TYPE(left) != AOP_ACC) {
6015 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6017 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6018 pic14_emitcode("movf","%s,w",
6019 aopGet(AOP(left),offset,FALSE,FALSE));
6020 pic14_emitcode("movwf","%s",
6021 aopGet(AOP(result),offset,FALSE,FALSE));
6024 if (AOP_TYPE(left) == AOP_ACC) {
6025 emitpcode(POC_XORLW, popGetLit(t));
6027 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6029 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6032 if (AOP_TYPE(left) == AOP_ACC) {
6033 emitpcode(POC_XORLW, popGetLit(t));
6035 emitpcode(POC_MOVLW, popGetLit(t));
6036 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6038 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6039 pic14_emitcode("movlw","0x%x",t);
6040 pic14_emitcode("xorwf","%s,w",
6041 aopGet(AOP(left),offset,FALSE,FALSE));
6042 pic14_emitcode("movwf","%s",
6043 aopGet(AOP(result),offset,FALSE,FALSE));
6049 // faster than result <- left, anl result,right
6050 // and better if result is SFR
6051 if (AOP_TYPE(left) == AOP_ACC) {
6052 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6053 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6055 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6056 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6057 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6058 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6060 if ( AOP_TYPE(result) != AOP_ACC){
6061 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6062 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6068 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6069 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6070 freeAsmop(result,NULL,ic,TRUE);
6073 /*-----------------------------------------------------------------*/
6074 /* genInline - write the inline code out */
6075 /*-----------------------------------------------------------------*/
6076 static void genInline (iCode *ic)
6078 char *buffer, *bp, *bp1;
6080 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6082 _G.inLine += (!options.asmpeep);
6084 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6085 strcpy(buffer,IC_INLINE(ic));
6087 /* emit each line as a code */
6093 addpCode2pBlock(pb,AssembleLine(bp1));
6100 pic14_emitcode(bp1,"");
6106 if ((bp1 != bp) && *bp1)
6107 addpCode2pBlock(pb,AssembleLine(bp1));
6111 _G.inLine -= (!options.asmpeep);
6114 /*-----------------------------------------------------------------*/
6115 /* genRRC - rotate right with carry */
6116 /*-----------------------------------------------------------------*/
6117 static void genRRC (iCode *ic)
6119 operand *left , *result ;
6120 int size, offset = 0, same;
6122 /* rotate right with carry */
6124 result=IC_RESULT(ic);
6125 aopOp (left,ic,FALSE);
6126 aopOp (result,ic,FALSE);
6128 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6130 same = pic14_sameRegs(AOP(result),AOP(left));
6132 size = AOP_SIZE(result);
6134 /* get the lsb and put it into the carry */
6135 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6142 emitpcode(POC_RRF, popGet(AOP(left),offset));
6144 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6145 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6151 freeAsmop(left,NULL,ic,TRUE);
6152 freeAsmop(result,NULL,ic,TRUE);
6155 /*-----------------------------------------------------------------*/
6156 /* genRLC - generate code for rotate left with carry */
6157 /*-----------------------------------------------------------------*/
6158 static void genRLC (iCode *ic)
6160 operand *left , *result ;
6161 int size, offset = 0;
6164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6165 /* rotate right with carry */
6167 result=IC_RESULT(ic);
6168 aopOp (left,ic,FALSE);
6169 aopOp (result,ic,FALSE);
6171 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6173 same = pic14_sameRegs(AOP(result),AOP(left));
6175 /* move it to the result */
6176 size = AOP_SIZE(result);
6178 /* get the msb and put it into the carry */
6179 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6186 emitpcode(POC_RLF, popGet(AOP(left),offset));
6188 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6189 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6196 freeAsmop(left,NULL,ic,TRUE);
6197 freeAsmop(result,NULL,ic,TRUE);
6200 /*-----------------------------------------------------------------*/
6201 /* genGetHbit - generates code get highest order bit */
6202 /*-----------------------------------------------------------------*/
6203 static void genGetHbit (iCode *ic)
6205 operand *left, *result;
6207 result=IC_RESULT(ic);
6208 aopOp (left,ic,FALSE);
6209 aopOp (result,ic,FALSE);
6211 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6212 /* get the highest order byte into a */
6213 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6214 if(AOP_TYPE(result) == AOP_CRY){
6215 pic14_emitcode("rlc","a");
6216 pic14_outBitC(result);
6219 pic14_emitcode("rl","a");
6220 pic14_emitcode("anl","a,#0x01");
6221 pic14_outAcc(result);
6225 freeAsmop(left,NULL,ic,TRUE);
6226 freeAsmop(result,NULL,ic,TRUE);
6229 /*-----------------------------------------------------------------*/
6230 /* AccRol - rotate left accumulator by known count */
6231 /*-----------------------------------------------------------------*/
6232 static void AccRol (int shCount)
6234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6235 shCount &= 0x0007; // shCount : 0..7
6240 pic14_emitcode("rl","a");
6243 pic14_emitcode("rl","a");
6244 pic14_emitcode("rl","a");
6247 pic14_emitcode("swap","a");
6248 pic14_emitcode("rr","a");
6251 pic14_emitcode("swap","a");
6254 pic14_emitcode("swap","a");
6255 pic14_emitcode("rl","a");
6258 pic14_emitcode("rr","a");
6259 pic14_emitcode("rr","a");
6262 pic14_emitcode("rr","a");
6267 /*-----------------------------------------------------------------*/
6268 /* AccLsh - left shift accumulator by known count */
6269 /*-----------------------------------------------------------------*/
6270 static void AccLsh (int shCount)
6272 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6275 pic14_emitcode("add","a,acc");
6278 pic14_emitcode("add","a,acc");
6279 pic14_emitcode("add","a,acc");
6281 /* rotate left accumulator */
6283 /* and kill the lower order bits */
6284 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6289 /*-----------------------------------------------------------------*/
6290 /* AccRsh - right shift accumulator by known count */
6291 /*-----------------------------------------------------------------*/
6292 static void AccRsh (int shCount)
6294 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6298 pic14_emitcode("rrc","a");
6300 /* rotate right accumulator */
6301 AccRol(8 - shCount);
6302 /* and kill the higher order bits */
6303 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6309 /*-----------------------------------------------------------------*/
6310 /* AccSRsh - signed right shift accumulator by known count */
6311 /*-----------------------------------------------------------------*/
6312 static void AccSRsh (int shCount)
6315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6318 pic14_emitcode("mov","c,acc.7");
6319 pic14_emitcode("rrc","a");
6320 } else if(shCount == 2){
6321 pic14_emitcode("mov","c,acc.7");
6322 pic14_emitcode("rrc","a");
6323 pic14_emitcode("mov","c,acc.7");
6324 pic14_emitcode("rrc","a");
6326 tlbl = newiTempLabel(NULL);
6327 /* rotate right accumulator */
6328 AccRol(8 - shCount);
6329 /* and kill the higher order bits */
6330 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6331 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6332 pic14_emitcode("orl","a,#0x%02x",
6333 (unsigned char)~SRMask[shCount]);
6334 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6339 /*-----------------------------------------------------------------*/
6340 /* shiftR1Left2Result - shift right one byte from left to result */
6341 /*-----------------------------------------------------------------*/
6342 static void shiftR1Left2ResultSigned (operand *left, int offl,
6343 operand *result, int offr,
6348 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6350 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6354 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6356 emitpcode(POC_RRF, popGet(AOP(result),offr));
6358 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6359 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6365 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6367 emitpcode(POC_RRF, popGet(AOP(result),offr));
6369 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6370 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6372 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6373 emitpcode(POC_RRF, popGet(AOP(result),offr));
6379 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6381 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6382 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6385 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6386 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6387 emitpcode(POC_ANDLW, popGetLit(0x1f));
6389 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6390 emitpcode(POC_IORLW, popGetLit(0xe0));
6392 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6396 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6397 emitpcode(POC_ANDLW, popGetLit(0x0f));
6398 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6399 emitpcode(POC_IORLW, popGetLit(0xf0));
6400 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6404 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6406 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6407 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6409 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6410 emitpcode(POC_ANDLW, popGetLit(0x07));
6411 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6412 emitpcode(POC_IORLW, popGetLit(0xf8));
6413 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6418 emitpcode(POC_MOVLW, popGetLit(0x00));
6419 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6420 emitpcode(POC_MOVLW, popGetLit(0xfe));
6421 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6422 emitpcode(POC_IORLW, popGetLit(0x01));
6423 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6425 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6426 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6427 emitpcode(POC_DECF, popGet(AOP(result),offr));
6428 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6429 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6435 emitpcode(POC_MOVLW, popGetLit(0x00));
6436 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6437 emitpcode(POC_MOVLW, popGetLit(0xff));
6438 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6440 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6441 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6442 emitpcode(POC_DECF, popGet(AOP(result),offr));
6450 /*-----------------------------------------------------------------*/
6451 /* shiftR1Left2Result - shift right one byte from left to result */
6452 /*-----------------------------------------------------------------*/
6453 static void shiftR1Left2Result (operand *left, int offl,
6454 operand *result, int offr,
6455 int shCount, int sign)
6459 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6461 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6463 /* Copy the msb into the carry if signed. */
6465 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6475 emitpcode(POC_RRF, popGet(AOP(result),offr));
6477 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6478 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6484 emitpcode(POC_RRF, popGet(AOP(result),offr));
6486 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6487 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6490 emitpcode(POC_RRF, popGet(AOP(result),offr));
6495 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6497 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6498 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6501 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6502 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6503 emitpcode(POC_ANDLW, popGetLit(0x1f));
6504 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6508 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6509 emitpcode(POC_ANDLW, popGetLit(0x0f));
6510 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6514 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6515 emitpcode(POC_ANDLW, popGetLit(0x0f));
6516 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6518 emitpcode(POC_RRF, popGet(AOP(result),offr));
6523 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6524 emitpcode(POC_ANDLW, popGetLit(0x80));
6525 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6526 emitpcode(POC_RLF, popGet(AOP(result),offr));
6527 emitpcode(POC_RLF, popGet(AOP(result),offr));
6532 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6533 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6534 emitpcode(POC_RLF, popGet(AOP(result),offr));
6543 /*-----------------------------------------------------------------*/
6544 /* shiftL1Left2Result - shift left one byte from left to result */
6545 /*-----------------------------------------------------------------*/
6546 static void shiftL1Left2Result (operand *left, int offl,
6547 operand *result, int offr, int shCount)
6552 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6554 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6555 DEBUGpic14_emitcode ("; ***","same = %d",same);
6556 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6558 /* shift left accumulator */
6559 //AccLsh(shCount); // don't comment out just yet...
6560 // aopPut(AOP(result),"a",offr);
6564 /* Shift left 1 bit position */
6565 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6567 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6569 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6570 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6574 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6575 emitpcode(POC_ANDLW,popGetLit(0x7e));
6576 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6577 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6580 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6581 emitpcode(POC_ANDLW,popGetLit(0x3e));
6582 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6583 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6584 emitpcode(POC_RLF, popGet(AOP(result),offr));
6587 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6588 emitpcode(POC_ANDLW, popGetLit(0xf0));
6589 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6592 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6593 emitpcode(POC_ANDLW, popGetLit(0xf0));
6594 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6595 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6598 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6599 emitpcode(POC_ANDLW, popGetLit(0x30));
6600 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6601 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6602 emitpcode(POC_RLF, popGet(AOP(result),offr));
6605 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6606 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6607 emitpcode(POC_RRF, popGet(AOP(result),offr));
6611 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6616 /*-----------------------------------------------------------------*/
6617 /* movLeft2Result - move byte from left to result */
6618 /*-----------------------------------------------------------------*/
6619 static void movLeft2Result (operand *left, int offl,
6620 operand *result, int offr)
6623 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6624 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6625 l = aopGet(AOP(left),offl,FALSE,FALSE);
6627 if (*l == '@' && (IS_AOP_PREG(result))) {
6628 pic14_emitcode("mov","a,%s",l);
6629 aopPut(AOP(result),"a",offr);
6631 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6632 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6637 /*-----------------------------------------------------------------*/
6638 /* shiftL2Left2Result - shift left two bytes from left to result */
6639 /*-----------------------------------------------------------------*/
6640 static void shiftL2Left2Result (operand *left, int offl,
6641 operand *result, int offr, int shCount)
6645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6647 if(pic14_sameRegs(AOP(result), AOP(left))) {
6655 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6656 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6657 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6661 emitpcode(POC_RLF, popGet(AOP(result),offr));
6662 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6668 emitpcode(POC_MOVLW, popGetLit(0x0f));
6669 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6671 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6672 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6673 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6674 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6676 emitpcode(POC_RLF, popGet(AOP(result),offr));
6677 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6681 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_RRF, popGet(AOP(result),offr));
6683 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6684 emitpcode(POC_RRF, popGet(AOP(result),offr));
6685 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6686 emitpcode(POC_ANDLW,popGetLit(0xc0));
6687 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6688 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6689 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6690 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6693 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6694 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6695 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6696 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6697 emitpcode(POC_RRF, popGet(AOP(result),offr));
6707 /* note, use a mov/add for the shift since the mov has a
6708 chance of getting optimized out */
6709 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6710 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6711 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6712 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6713 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6717 emitpcode(POC_RLF, popGet(AOP(result),offr));
6718 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6724 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6725 emitpcode(POC_ANDLW, popGetLit(0xF0));
6726 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6727 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6728 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6729 emitpcode(POC_ANDLW, popGetLit(0xF0));
6730 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6731 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6735 emitpcode(POC_RLF, popGet(AOP(result),offr));
6736 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6740 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6741 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6742 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6743 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6745 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_RRF, popGet(AOP(result),offr));
6747 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6748 emitpcode(POC_ANDLW,popGetLit(0xc0));
6749 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6750 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6751 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6752 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6755 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6756 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6757 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6758 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6759 emitpcode(POC_RRF, popGet(AOP(result),offr));
6764 /*-----------------------------------------------------------------*/
6765 /* shiftR2Left2Result - shift right two bytes from left to result */
6766 /*-----------------------------------------------------------------*/
6767 static void shiftR2Left2Result (operand *left, int offl,
6768 operand *result, int offr,
6769 int shCount, int sign)
6773 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6774 same = pic14_sameRegs(AOP(result), AOP(left));
6776 if(same && ((offl + MSB16) == offr)){
6778 /* don't crash result[offr] */
6779 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6780 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6783 movLeft2Result(left,offl, result, offr);
6784 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6787 /* a:x >> shCount (x = lsb(result))*/
6790 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6792 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6801 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6806 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6807 emitpcode(POC_RRF,popGet(AOP(result),offr));
6809 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6810 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6811 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6812 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6817 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6820 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6821 emitpcode(POC_RRF,popGet(AOP(result),offr));
6828 emitpcode(POC_MOVLW, popGetLit(0xf0));
6829 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6830 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6832 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6833 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6834 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6835 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6837 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6838 emitpcode(POC_ANDLW, popGetLit(0x0f));
6839 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6841 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6842 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6843 emitpcode(POC_ANDLW, popGetLit(0xf0));
6844 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6845 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6849 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6850 emitpcode(POC_RRF, popGet(AOP(result),offr));
6854 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6855 emitpcode(POC_BTFSC,
6856 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6857 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6865 emitpcode(POC_RLF, popGet(AOP(result),offr));
6866 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6868 emitpcode(POC_RLF, popGet(AOP(result),offr));
6869 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6870 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6871 emitpcode(POC_ANDLW,popGetLit(0x03));
6873 emitpcode(POC_BTFSC,
6874 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6875 emitpcode(POC_IORLW,popGetLit(0xfc));
6877 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6878 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6879 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6880 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6882 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6883 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6884 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6885 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6886 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6887 emitpcode(POC_RLF, popGet(AOP(result),offr));
6888 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6889 emitpcode(POC_ANDLW,popGetLit(0x03));
6891 emitpcode(POC_BTFSC,
6892 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6893 emitpcode(POC_IORLW,popGetLit(0xfc));
6895 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6896 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6903 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6904 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6905 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6906 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6909 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6911 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6916 /*-----------------------------------------------------------------*/
6917 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6918 /*-----------------------------------------------------------------*/
6919 static void shiftLLeftOrResult (operand *left, int offl,
6920 operand *result, int offr, int shCount)
6922 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6923 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6924 /* shift left accumulator */
6926 /* or with result */
6927 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6928 /* back to result */
6929 aopPut(AOP(result),"a",offr);
6932 /*-----------------------------------------------------------------*/
6933 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6934 /*-----------------------------------------------------------------*/
6935 static void shiftRLeftOrResult (operand *left, int offl,
6936 operand *result, int offr, int shCount)
6938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6939 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6940 /* shift right accumulator */
6942 /* or with result */
6943 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6944 /* back to result */
6945 aopPut(AOP(result),"a",offr);
6948 /*-----------------------------------------------------------------*/
6949 /* genlshOne - left shift a one byte quantity by known count */
6950 /*-----------------------------------------------------------------*/
6951 static void genlshOne (operand *result, operand *left, int shCount)
6953 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6954 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6957 /*-----------------------------------------------------------------*/
6958 /* genlshTwo - left shift two bytes by known amount != 0 */
6959 /*-----------------------------------------------------------------*/
6960 static void genlshTwo (operand *result,operand *left, int shCount)
6964 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6965 size = pic14_getDataSize(result);
6967 /* if shCount >= 8 */
6973 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6975 movLeft2Result(left, LSB, result, MSB16);
6977 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6980 /* 1 <= shCount <= 7 */
6983 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6985 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6989 /*-----------------------------------------------------------------*/
6990 /* shiftLLong - shift left one long from left to result */
6991 /* offl = LSB or MSB16 */
6992 /*-----------------------------------------------------------------*/
6993 static void shiftLLong (operand *left, operand *result, int offr )
6996 int size = AOP_SIZE(result);
6998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6999 if(size >= LSB+offr){
7000 l = aopGet(AOP(left),LSB,FALSE,FALSE);
7002 pic14_emitcode("add","a,acc");
7003 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7004 size >= MSB16+offr && offr != LSB )
7005 pic14_emitcode("xch","a,%s",
7006 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7008 aopPut(AOP(result),"a",LSB+offr);
7011 if(size >= MSB16+offr){
7012 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7013 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7016 pic14_emitcode("rlc","a");
7017 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7018 size >= MSB24+offr && offr != LSB)
7019 pic14_emitcode("xch","a,%s",
7020 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7022 aopPut(AOP(result),"a",MSB16+offr);
7025 if(size >= MSB24+offr){
7026 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7027 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7030 pic14_emitcode("rlc","a");
7031 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7032 size >= MSB32+offr && offr != LSB )
7033 pic14_emitcode("xch","a,%s",
7034 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7036 aopPut(AOP(result),"a",MSB24+offr);
7039 if(size > MSB32+offr){
7040 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7041 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7044 pic14_emitcode("rlc","a");
7045 aopPut(AOP(result),"a",MSB32+offr);
7048 aopPut(AOP(result),zero,LSB);
7051 /*-----------------------------------------------------------------*/
7052 /* genlshFour - shift four byte by a known amount != 0 */
7053 /*-----------------------------------------------------------------*/
7054 static void genlshFour (operand *result, operand *left, int shCount)
7058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7059 size = AOP_SIZE(result);
7061 /* if shifting more that 3 bytes */
7062 if (shCount >= 24 ) {
7065 /* lowest order of left goes to the highest
7066 order of the destination */
7067 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7069 movLeft2Result(left, LSB, result, MSB32);
7070 aopPut(AOP(result),zero,LSB);
7071 aopPut(AOP(result),zero,MSB16);
7072 aopPut(AOP(result),zero,MSB32);
7076 /* more than two bytes */
7077 else if ( shCount >= 16 ) {
7078 /* lower order two bytes goes to higher order two bytes */
7080 /* if some more remaining */
7082 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7084 movLeft2Result(left, MSB16, result, MSB32);
7085 movLeft2Result(left, LSB, result, MSB24);
7087 aopPut(AOP(result),zero,MSB16);
7088 aopPut(AOP(result),zero,LSB);
7092 /* if more than 1 byte */
7093 else if ( shCount >= 8 ) {
7094 /* lower order three bytes goes to higher order three bytes */
7098 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7100 movLeft2Result(left, LSB, result, MSB16);
7102 else{ /* size = 4 */
7104 movLeft2Result(left, MSB24, result, MSB32);
7105 movLeft2Result(left, MSB16, result, MSB24);
7106 movLeft2Result(left, LSB, result, MSB16);
7107 aopPut(AOP(result),zero,LSB);
7109 else if(shCount == 1)
7110 shiftLLong(left, result, MSB16);
7112 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7113 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7114 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7115 aopPut(AOP(result),zero,LSB);
7120 /* 1 <= shCount <= 7 */
7121 else if(shCount <= 2){
7122 shiftLLong(left, result, LSB);
7124 shiftLLong(result, result, LSB);
7126 /* 3 <= shCount <= 7, optimize */
7128 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7129 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7130 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7134 /*-----------------------------------------------------------------*/
7135 /* genLeftShiftLiteral - left shifting by known count */
7136 /*-----------------------------------------------------------------*/
7137 static void genLeftShiftLiteral (operand *left,
7142 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7145 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7146 freeAsmop(right,NULL,ic,TRUE);
7148 aopOp(left,ic,FALSE);
7149 aopOp(result,ic,FALSE);
7151 size = getSize(operandType(result));
7154 pic14_emitcode("; shift left ","result %d, left %d",size,
7158 /* I suppose that the left size >= result size */
7161 movLeft2Result(left, size, result, size);
7165 else if(shCount >= (size * 8))
7167 aopPut(AOP(result),zero,size);
7171 genlshOne (result,left,shCount);
7176 genlshTwo (result,left,shCount);
7180 genlshFour (result,left,shCount);
7184 freeAsmop(left,NULL,ic,TRUE);
7185 freeAsmop(result,NULL,ic,TRUE);
7188 /*-----------------------------------------------------------------*
7189 * genMultiAsm - repeat assembly instruction for size of register.
7190 * if endian == 1, then the high byte (i.e base address + size of
7191 * register) is used first else the low byte is used first;
7192 *-----------------------------------------------------------------*/
7193 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7198 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7211 emitpcode(poc, popGet(AOP(reg),offset));
7216 /*-----------------------------------------------------------------*/
7217 /* genLeftShift - generates code for left shifting */
7218 /*-----------------------------------------------------------------*/
7219 static void genLeftShift (iCode *ic)
7221 operand *left,*right, *result;
7224 symbol *tlbl , *tlbl1;
7227 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7229 right = IC_RIGHT(ic);
7231 result = IC_RESULT(ic);
7233 aopOp(right,ic,FALSE);
7235 /* if the shift count is known then do it
7236 as efficiently as possible */
7237 if (AOP_TYPE(right) == AOP_LIT) {
7238 genLeftShiftLiteral (left,right,result,ic);
7242 /* shift count is unknown then we have to form
7243 a loop get the loop count in B : Note: we take
7244 only the lower order byte since shifting
7245 more that 32 bits make no sense anyway, ( the
7246 largest size of an object can be only 32 bits ) */
7249 aopOp(left,ic,FALSE);
7250 aopOp(result,ic,FALSE);
7252 /* now move the left to the result if they are not the
7254 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7255 AOP_SIZE(result) > 1) {
7257 size = AOP_SIZE(result);
7260 l = aopGet(AOP(left),offset,FALSE,TRUE);
7261 if (*l == '@' && (IS_AOP_PREG(result))) {
7263 pic14_emitcode("mov","a,%s",l);
7264 aopPut(AOP(result),"a",offset);
7266 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7267 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7268 //aopPut(AOP(result),l,offset);
7274 size = AOP_SIZE(result);
7276 /* if it is only one byte then */
7278 if(optimized_for_speed) {
7279 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7280 emitpcode(POC_ANDLW, popGetLit(0xf0));
7281 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7282 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7283 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7284 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7285 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7286 emitpcode(POC_RLFW, popGet(AOP(result),0));
7287 emitpcode(POC_ANDLW, popGetLit(0xfe));
7288 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7289 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7290 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7293 tlbl = newiTempLabel(NULL);
7294 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7295 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7296 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7299 emitpcode(POC_COMFW, popGet(AOP(right),0));
7300 emitpcode(POC_RRF, popGet(AOP(result),0));
7301 emitpLabel(tlbl->key);
7302 emitpcode(POC_RLF, popGet(AOP(result),0));
7303 emitpcode(POC_ADDLW, popGetLit(1));
7305 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7310 if (pic14_sameRegs(AOP(left),AOP(result))) {
7312 tlbl = newiTempLabel(NULL);
7313 emitpcode(POC_COMFW, popGet(AOP(right),0));
7314 genMultiAsm(POC_RRF, result, size,1);
7315 emitpLabel(tlbl->key);
7316 genMultiAsm(POC_RLF, result, size,0);
7317 emitpcode(POC_ADDLW, popGetLit(1));
7319 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7323 //tlbl = newiTempLabel(NULL);
7325 //tlbl1 = newiTempLabel(NULL);
7327 //reAdjustPreg(AOP(result));
7329 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7330 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7331 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7333 //pic14_emitcode("add","a,acc");
7334 //aopPut(AOP(result),"a",offset++);
7336 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7338 // pic14_emitcode("rlc","a");
7339 // aopPut(AOP(result),"a",offset++);
7341 //reAdjustPreg(AOP(result));
7343 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7344 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7347 tlbl = newiTempLabel(NULL);
7348 tlbl1= newiTempLabel(NULL);
7350 size = AOP_SIZE(result);
7353 pctemp = popGetTempReg(); /* grab a temporary working register. */
7355 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7357 /* offset should be 0, 1 or 3 */
7358 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7360 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7362 emitpcode(POC_MOVWF, pctemp);
7365 emitpLabel(tlbl->key);
7368 emitpcode(POC_RLF, popGet(AOP(result),0));
7370 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7372 emitpcode(POC_DECFSZ, pctemp);
7373 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7374 emitpLabel(tlbl1->key);
7376 popReleaseTempReg(pctemp);
7380 freeAsmop (right,NULL,ic,TRUE);
7381 freeAsmop(left,NULL,ic,TRUE);
7382 freeAsmop(result,NULL,ic,TRUE);
7385 /*-----------------------------------------------------------------*/
7386 /* genrshOne - right shift a one byte quantity by known count */
7387 /*-----------------------------------------------------------------*/
7388 static void genrshOne (operand *result, operand *left,
7389 int shCount, int sign)
7391 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7392 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7395 /*-----------------------------------------------------------------*/
7396 /* genrshTwo - right shift two bytes by known amount != 0 */
7397 /*-----------------------------------------------------------------*/
7398 static void genrshTwo (operand *result,operand *left,
7399 int shCount, int sign)
7401 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7402 /* if shCount >= 8 */
7406 shiftR1Left2Result(left, MSB16, result, LSB,
7409 movLeft2Result(left, MSB16, result, LSB);
7411 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7414 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7415 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7419 /* 1 <= shCount <= 7 */
7421 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7424 /*-----------------------------------------------------------------*/
7425 /* shiftRLong - shift right one long from left to result */
7426 /* offl = LSB or MSB16 */
7427 /*-----------------------------------------------------------------*/
7428 static void shiftRLong (operand *left, int offl,
7429 operand *result, int sign)
7431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7433 pic14_emitcode("clr","c");
7434 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7436 pic14_emitcode("mov","c,acc.7");
7437 pic14_emitcode("rrc","a");
7438 aopPut(AOP(result),"a",MSB32-offl);
7440 /* add sign of "a" */
7441 addSign(result, MSB32, sign);
7443 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7444 pic14_emitcode("rrc","a");
7445 aopPut(AOP(result),"a",MSB24-offl);
7447 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7448 pic14_emitcode("rrc","a");
7449 aopPut(AOP(result),"a",MSB16-offl);
7452 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7453 pic14_emitcode("rrc","a");
7454 aopPut(AOP(result),"a",LSB);
7458 /*-----------------------------------------------------------------*/
7459 /* genrshFour - shift four byte by a known amount != 0 */
7460 /*-----------------------------------------------------------------*/
7461 static void genrshFour (operand *result, operand *left,
7462 int shCount, int sign)
7464 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7465 /* if shifting more that 3 bytes */
7466 if(shCount >= 24 ) {
7469 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7471 movLeft2Result(left, MSB32, result, LSB);
7473 addSign(result, MSB16, sign);
7475 else if(shCount >= 16){
7478 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7480 movLeft2Result(left, MSB24, result, LSB);
7481 movLeft2Result(left, MSB32, result, MSB16);
7483 addSign(result, MSB24, sign);
7485 else if(shCount >= 8){
7488 shiftRLong(left, MSB16, result, sign);
7489 else if(shCount == 0){
7490 movLeft2Result(left, MSB16, result, LSB);
7491 movLeft2Result(left, MSB24, result, MSB16);
7492 movLeft2Result(left, MSB32, result, MSB24);
7493 addSign(result, MSB32, sign);
7496 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7497 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7498 /* the last shift is signed */
7499 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7500 addSign(result, MSB32, sign);
7503 else{ /* 1 <= shCount <= 7 */
7505 shiftRLong(left, LSB, result, sign);
7507 shiftRLong(result, LSB, result, sign);
7510 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7511 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7512 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7517 /*-----------------------------------------------------------------*/
7518 /* genRightShiftLiteral - right shifting by known count */
7519 /*-----------------------------------------------------------------*/
7520 static void genRightShiftLiteral (operand *left,
7526 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7529 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7530 freeAsmop(right,NULL,ic,TRUE);
7532 aopOp(left,ic,FALSE);
7533 aopOp(result,ic,FALSE);
7536 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7540 lsize = pic14_getDataSize(left);
7541 res_size = pic14_getDataSize(result);
7542 /* test the LEFT size !!! */
7544 /* I suppose that the left size >= result size */
7547 movLeft2Result(left, lsize, result, res_size);
7550 else if(shCount >= (lsize * 8)){
7553 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7555 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7556 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7561 emitpcode(POC_MOVLW, popGetLit(0));
7562 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7563 emitpcode(POC_MOVLW, popGetLit(0xff));
7565 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7570 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7577 genrshOne (result,left,shCount,sign);
7581 genrshTwo (result,left,shCount,sign);
7585 genrshFour (result,left,shCount,sign);
7593 freeAsmop(left,NULL,ic,TRUE);
7594 freeAsmop(result,NULL,ic,TRUE);
7597 /*-----------------------------------------------------------------*/
7598 /* genSignedRightShift - right shift of signed number */
7599 /*-----------------------------------------------------------------*/
7600 static void genSignedRightShift (iCode *ic)
7602 operand *right, *left, *result;
7605 symbol *tlbl, *tlbl1 ;
7608 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7610 /* we do it the hard way put the shift count in b
7611 and loop thru preserving the sign */
7612 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7614 right = IC_RIGHT(ic);
7616 result = IC_RESULT(ic);
7618 aopOp(right,ic,FALSE);
7619 aopOp(left,ic,FALSE);
7620 aopOp(result,ic,FALSE);
7623 if ( AOP_TYPE(right) == AOP_LIT) {
7624 genRightShiftLiteral (left,right,result,ic,1);
7627 /* shift count is unknown then we have to form
7628 a loop get the loop count in B : Note: we take
7629 only the lower order byte since shifting
7630 more that 32 bits make no sense anyway, ( the
7631 largest size of an object can be only 32 bits ) */
7633 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7634 //pic14_emitcode("inc","b");
7635 //freeAsmop (right,NULL,ic,TRUE);
7636 //aopOp(left,ic,FALSE);
7637 //aopOp(result,ic,FALSE);
7639 /* now move the left to the result if they are not the
7641 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7642 AOP_SIZE(result) > 1) {
7644 size = AOP_SIZE(result);
7648 l = aopGet(AOP(left),offset,FALSE,TRUE);
7649 if (*l == '@' && IS_AOP_PREG(result)) {
7651 pic14_emitcode("mov","a,%s",l);
7652 aopPut(AOP(result),"a",offset);
7654 aopPut(AOP(result),l,offset);
7656 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7657 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7663 /* mov the highest order bit to OVR */
7664 tlbl = newiTempLabel(NULL);
7665 tlbl1= newiTempLabel(NULL);
7667 size = AOP_SIZE(result);
7670 pctemp = popGetTempReg(); /* grab a temporary working register. */
7672 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7674 /* offset should be 0, 1 or 3 */
7675 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7677 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7679 emitpcode(POC_MOVWF, pctemp);
7682 emitpLabel(tlbl->key);
7684 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7685 emitpcode(POC_RRF, popGet(AOP(result),offset));
7688 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7691 emitpcode(POC_DECFSZ, pctemp);
7692 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7693 emitpLabel(tlbl1->key);
7695 popReleaseTempReg(pctemp);
7697 size = AOP_SIZE(result);
7699 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7700 pic14_emitcode("rlc","a");
7701 pic14_emitcode("mov","ov,c");
7702 /* if it is only one byte then */
7704 l = aopGet(AOP(left),0,FALSE,FALSE);
7706 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7707 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7708 pic14_emitcode("mov","c,ov");
7709 pic14_emitcode("rrc","a");
7710 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7711 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7712 aopPut(AOP(result),"a",0);
7716 reAdjustPreg(AOP(result));
7717 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7718 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7719 pic14_emitcode("mov","c,ov");
7721 l = aopGet(AOP(result),offset,FALSE,FALSE);
7723 pic14_emitcode("rrc","a");
7724 aopPut(AOP(result),"a",offset--);
7726 reAdjustPreg(AOP(result));
7727 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7728 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7733 freeAsmop(left,NULL,ic,TRUE);
7734 freeAsmop(result,NULL,ic,TRUE);
7735 freeAsmop(right,NULL,ic,TRUE);
7738 /*-----------------------------------------------------------------*/
7739 /* genRightShift - generate code for right shifting */
7740 /*-----------------------------------------------------------------*/
7741 static void genRightShift (iCode *ic)
7743 operand *right, *left, *result;
7747 symbol *tlbl, *tlbl1 ;
7749 /* if signed then we do it the hard way preserve the
7750 sign bit moving it inwards */
7751 retype = getSpec(operandType(IC_RESULT(ic)));
7752 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7754 if (!SPEC_USIGN(retype)) {
7755 genSignedRightShift (ic);
7759 /* signed & unsigned types are treated the same : i.e. the
7760 signed is NOT propagated inwards : quoting from the
7761 ANSI - standard : "for E1 >> E2, is equivalent to division
7762 by 2**E2 if unsigned or if it has a non-negative value,
7763 otherwise the result is implementation defined ", MY definition
7764 is that the sign does not get propagated */
7766 right = IC_RIGHT(ic);
7768 result = IC_RESULT(ic);
7770 aopOp(right,ic,FALSE);
7772 /* if the shift count is known then do it
7773 as efficiently as possible */
7774 if (AOP_TYPE(right) == AOP_LIT) {
7775 genRightShiftLiteral (left,right,result,ic, 0);
7779 /* shift count is unknown then we have to form
7780 a loop get the loop count in B : Note: we take
7781 only the lower order byte since shifting
7782 more that 32 bits make no sense anyway, ( the
7783 largest size of an object can be only 32 bits ) */
7785 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7786 pic14_emitcode("inc","b");
7787 aopOp(left,ic,FALSE);
7788 aopOp(result,ic,FALSE);
7790 /* now move the left to the result if they are not the
7792 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7793 AOP_SIZE(result) > 1) {
7795 size = AOP_SIZE(result);
7798 l = aopGet(AOP(left),offset,FALSE,TRUE);
7799 if (*l == '@' && IS_AOP_PREG(result)) {
7801 pic14_emitcode("mov","a,%s",l);
7802 aopPut(AOP(result),"a",offset);
7804 aopPut(AOP(result),l,offset);
7809 tlbl = newiTempLabel(NULL);
7810 tlbl1= newiTempLabel(NULL);
7811 size = AOP_SIZE(result);
7814 /* if it is only one byte then */
7817 tlbl = newiTempLabel(NULL);
7818 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7819 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7820 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7823 emitpcode(POC_COMFW, popGet(AOP(right),0));
7824 emitpcode(POC_RLF, popGet(AOP(result),0));
7825 emitpLabel(tlbl->key);
7826 emitpcode(POC_RRF, popGet(AOP(result),0));
7827 emitpcode(POC_ADDLW, popGetLit(1));
7829 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7834 reAdjustPreg(AOP(result));
7835 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7836 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7839 l = aopGet(AOP(result),offset,FALSE,FALSE);
7841 pic14_emitcode("rrc","a");
7842 aopPut(AOP(result),"a",offset--);
7844 reAdjustPreg(AOP(result));
7846 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7847 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7850 freeAsmop(left,NULL,ic,TRUE);
7851 freeAsmop (right,NULL,ic,TRUE);
7852 freeAsmop(result,NULL,ic,TRUE);
7855 /*-----------------------------------------------------------------*/
7856 /* genUnpackBits - generates code for unpacking bits */
7857 /*-----------------------------------------------------------------*/
7858 static void genUnpackBits (operand *result, char *rname, int ptype)
7865 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7866 etype = getSpec(operandType(result));
7868 /* read the first byte */
7873 pic14_emitcode("mov","a,@%s",rname);
7877 pic14_emitcode("movx","a,@%s",rname);
7881 pic14_emitcode("movx","a,@dptr");
7885 pic14_emitcode("clr","a");
7886 pic14_emitcode("movc","a","@a+dptr");
7890 pic14_emitcode("lcall","__gptrget");
7894 /* if we have bitdisplacement then it fits */
7895 /* into this byte completely or if length is */
7896 /* less than a byte */
7897 if ((shCnt = SPEC_BSTR(etype)) ||
7898 (SPEC_BLEN(etype) <= 8)) {
7900 /* shift right acc */
7903 pic14_emitcode("anl","a,#0x%02x",
7904 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7905 aopPut(AOP(result),"a",offset);
7909 /* bit field did not fit in a byte */
7910 rlen = SPEC_BLEN(etype) - 8;
7911 aopPut(AOP(result),"a",offset++);
7918 pic14_emitcode("inc","%s",rname);
7919 pic14_emitcode("mov","a,@%s",rname);
7923 pic14_emitcode("inc","%s",rname);
7924 pic14_emitcode("movx","a,@%s",rname);
7928 pic14_emitcode("inc","dptr");
7929 pic14_emitcode("movx","a,@dptr");
7933 pic14_emitcode("clr","a");
7934 pic14_emitcode("inc","dptr");
7935 pic14_emitcode("movc","a","@a+dptr");
7939 pic14_emitcode("inc","dptr");
7940 pic14_emitcode("lcall","__gptrget");
7945 /* if we are done */
7949 aopPut(AOP(result),"a",offset++);
7954 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7955 aopPut(AOP(result),"a",offset);
7962 /*-----------------------------------------------------------------*/
7963 /* genDataPointerGet - generates code when ptr offset is known */
7964 /*-----------------------------------------------------------------*/
7965 static void genDataPointerGet (operand *left,
7969 int size , offset = 0;
7972 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7975 /* optimization - most of the time, left and result are the same
7976 * address, but different types. for the pic code, we could omit
7980 aopOp(result,ic,TRUE);
7982 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7984 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7986 size = AOP_SIZE(result);
7989 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7993 freeAsmop(left,NULL,ic,TRUE);
7994 freeAsmop(result,NULL,ic,TRUE);
7997 /*-----------------------------------------------------------------*/
7998 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7999 /*-----------------------------------------------------------------*/
8000 static void genNearPointerGet (operand *left,
8005 //regs *preg = NULL ;
8007 sym_link *rtype, *retype;
8008 sym_link *ltype = operandType(left);
8011 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8013 rtype = operandType(result);
8014 retype= getSpec(rtype);
8016 aopOp(left,ic,FALSE);
8018 /* if left is rematerialisable and
8019 result is not bit variable type and
8020 the left is pointer to data space i.e
8021 lower 128 bytes of space */
8022 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8023 !IS_BITVAR(retype) &&
8024 DCL_TYPE(ltype) == POINTER) {
8025 //genDataPointerGet (left,result,ic);
8029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8031 /* if the value is already in a pointer register
8032 then don't need anything more */
8033 if (!AOP_INPREG(AOP(left))) {
8034 /* otherwise get a free pointer register */
8035 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8038 preg = getFreePtr(ic,&aop,FALSE);
8039 pic14_emitcode("mov","%s,%s",
8041 aopGet(AOP(left),0,FALSE,TRUE));
8042 rname = preg->name ;
8046 rname = aopGet(AOP(left),0,FALSE,FALSE);
8048 aopOp (result,ic,FALSE);
8050 /* if bitfield then unpack the bits */
8051 if (IS_BITVAR(retype))
8052 genUnpackBits (result,rname,POINTER);
8054 /* we have can just get the values */
8055 int size = AOP_SIZE(result);
8058 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8060 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8061 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8063 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8064 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8066 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8070 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8072 pic14_emitcode("mov","a,@%s",rname);
8073 aopPut(AOP(result),"a",offset);
8075 sprintf(buffer,"@%s",rname);
8076 aopPut(AOP(result),buffer,offset);
8080 pic14_emitcode("inc","%s",rname);
8085 /* now some housekeeping stuff */
8087 /* we had to allocate for this iCode */
8088 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8089 freeAsmop(NULL,aop,ic,TRUE);
8091 /* we did not allocate which means left
8092 already in a pointer register, then
8093 if size > 0 && this could be used again
8094 we have to point it back to where it
8096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8097 if (AOP_SIZE(result) > 1 &&
8098 !OP_SYMBOL(left)->remat &&
8099 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8101 int size = AOP_SIZE(result) - 1;
8103 pic14_emitcode("dec","%s",rname);
8108 freeAsmop(left,NULL,ic,TRUE);
8109 freeAsmop(result,NULL,ic,TRUE);
8113 /*-----------------------------------------------------------------*/
8114 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8115 /*-----------------------------------------------------------------*/
8116 static void genPagedPointerGet (operand *left,
8123 sym_link *rtype, *retype;
8125 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8127 rtype = operandType(result);
8128 retype= getSpec(rtype);
8130 aopOp(left,ic,FALSE);
8132 /* if the value is already in a pointer register
8133 then don't need anything more */
8134 if (!AOP_INPREG(AOP(left))) {
8135 /* otherwise get a free pointer register */
8137 preg = getFreePtr(ic,&aop,FALSE);
8138 pic14_emitcode("mov","%s,%s",
8140 aopGet(AOP(left),0,FALSE,TRUE));
8141 rname = preg->name ;
8143 rname = aopGet(AOP(left),0,FALSE,FALSE);
8145 freeAsmop(left,NULL,ic,TRUE);
8146 aopOp (result,ic,FALSE);
8148 /* if bitfield then unpack the bits */
8149 if (IS_BITVAR(retype))
8150 genUnpackBits (result,rname,PPOINTER);
8152 /* we have can just get the values */
8153 int size = AOP_SIZE(result);
8158 pic14_emitcode("movx","a,@%s",rname);
8159 aopPut(AOP(result),"a",offset);
8164 pic14_emitcode("inc","%s",rname);
8168 /* now some housekeeping stuff */
8170 /* we had to allocate for this iCode */
8171 freeAsmop(NULL,aop,ic,TRUE);
8173 /* we did not allocate which means left
8174 already in a pointer register, then
8175 if size > 0 && this could be used again
8176 we have to point it back to where it
8178 if (AOP_SIZE(result) > 1 &&
8179 !OP_SYMBOL(left)->remat &&
8180 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8182 int size = AOP_SIZE(result) - 1;
8184 pic14_emitcode("dec","%s",rname);
8189 freeAsmop(result,NULL,ic,TRUE);
8194 /*-----------------------------------------------------------------*/
8195 /* genFarPointerGet - gget value from far space */
8196 /*-----------------------------------------------------------------*/
8197 static void genFarPointerGet (operand *left,
8198 operand *result, iCode *ic)
8201 sym_link *retype = getSpec(operandType(result));
8203 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8205 aopOp(left,ic,FALSE);
8207 /* if the operand is already in dptr
8208 then we do nothing else we move the value to dptr */
8209 if (AOP_TYPE(left) != AOP_STR) {
8210 /* if this is remateriazable */
8211 if (AOP_TYPE(left) == AOP_IMMD)
8212 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8213 else { /* we need to get it byte by byte */
8214 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8215 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8216 if (options.model == MODEL_FLAT24)
8218 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8222 /* so dptr know contains the address */
8223 freeAsmop(left,NULL,ic,TRUE);
8224 aopOp(result,ic,FALSE);
8226 /* if bit then unpack */
8227 if (IS_BITVAR(retype))
8228 genUnpackBits(result,"dptr",FPOINTER);
8230 size = AOP_SIZE(result);
8234 pic14_emitcode("movx","a,@dptr");
8235 aopPut(AOP(result),"a",offset++);
8237 pic14_emitcode("inc","dptr");
8241 freeAsmop(result,NULL,ic,TRUE);
8244 /*-----------------------------------------------------------------*/
8245 /* genCodePointerGet - get value from code space */
8246 /*-----------------------------------------------------------------*/
8247 static void genCodePointerGet (operand *left,
8248 operand *result, iCode *ic)
8251 sym_link *retype = getSpec(operandType(result));
8253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8255 aopOp(left,ic,FALSE);
8257 /* if the operand is already in dptr
8258 then we do nothing else we move the value to dptr */
8259 if (AOP_TYPE(left) != AOP_STR) {
8260 /* if this is remateriazable */
8261 if (AOP_TYPE(left) == AOP_IMMD)
8262 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8263 else { /* we need to get it byte by byte */
8264 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8265 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8266 if (options.model == MODEL_FLAT24)
8268 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8272 /* so dptr know contains the address */
8273 freeAsmop(left,NULL,ic,TRUE);
8274 aopOp(result,ic,FALSE);
8276 /* if bit then unpack */
8277 if (IS_BITVAR(retype))
8278 genUnpackBits(result,"dptr",CPOINTER);
8280 size = AOP_SIZE(result);
8284 pic14_emitcode("clr","a");
8285 pic14_emitcode("movc","a,@a+dptr");
8286 aopPut(AOP(result),"a",offset++);
8288 pic14_emitcode("inc","dptr");
8292 freeAsmop(result,NULL,ic,TRUE);
8295 /*-----------------------------------------------------------------*/
8296 /* genGenPointerGet - gget value from generic pointer space */
8297 /*-----------------------------------------------------------------*/
8298 static void genGenPointerGet (operand *left,
8299 operand *result, iCode *ic)
8302 sym_link *retype = getSpec(operandType(result));
8304 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8305 aopOp(left,ic,FALSE);
8306 aopOp(result,ic,FALSE);
8309 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8311 /* if the operand is already in dptr
8312 then we do nothing else we move the value to dptr */
8313 // if (AOP_TYPE(left) != AOP_STR) {
8314 /* if this is remateriazable */
8315 if (AOP_TYPE(left) == AOP_IMMD) {
8316 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8317 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8319 else { /* we need to get it byte by byte */
8321 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8322 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8324 size = AOP_SIZE(result);
8328 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8329 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8331 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8336 /* so dptr know contains the address */
8338 /* if bit then unpack */
8339 //if (IS_BITVAR(retype))
8340 // genUnpackBits(result,"dptr",GPOINTER);
8343 freeAsmop(left,NULL,ic,TRUE);
8344 freeAsmop(result,NULL,ic,TRUE);
8348 /*-----------------------------------------------------------------*/
8349 /* genConstPointerGet - get value from const generic pointer space */
8350 /*-----------------------------------------------------------------*/
8351 static void genConstPointerGet (operand *left,
8352 operand *result, iCode *ic)
8354 //sym_link *retype = getSpec(operandType(result));
8355 symbol *albl = newiTempLabel(NULL);
8356 symbol *blbl = newiTempLabel(NULL);
8359 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8360 aopOp(left,ic,FALSE);
8361 aopOp(result,ic,FALSE);
8364 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8366 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8368 emitpcode(POC_CALL,popGetLabel(albl->key));
8369 emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
8370 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8371 emitpLabel(albl->key);
8373 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8375 emitpcode(poc,popGet(AOP(left),1));
8376 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8377 emitpcode(poc,popGet(AOP(left),0));
8378 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8380 emitpLabel(blbl->key);
8382 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8385 freeAsmop(left,NULL,ic,TRUE);
8386 freeAsmop(result,NULL,ic,TRUE);
8389 /*-----------------------------------------------------------------*/
8390 /* genPointerGet - generate code for pointer get */
8391 /*-----------------------------------------------------------------*/
8392 static void genPointerGet (iCode *ic)
8394 operand *left, *result ;
8395 sym_link *type, *etype;
8398 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8401 result = IC_RESULT(ic) ;
8403 /* depending on the type of pointer we need to
8404 move it to the correct pointer register */
8405 type = operandType(left);
8406 etype = getSpec(type);
8409 if (IS_PTR_CONST(type))
8411 if (IS_CODEPTR(type))
8413 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8415 /* if left is of type of pointer then it is simple */
8416 if (IS_PTR(type) && !IS_FUNC(type->next))
8417 p_type = DCL_TYPE(type);
8419 /* we have to go by the storage class */
8420 p_type = PTR_TYPE(SPEC_OCLS(etype));
8422 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8424 if (SPEC_OCLS(etype)->codesp ) {
8425 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8426 //p_type = CPOINTER ;
8429 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8430 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8431 /*p_type = FPOINTER ;*/
8433 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8434 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8435 /* p_type = PPOINTER; */
8437 if (SPEC_OCLS(etype) == idata )
8438 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8439 /* p_type = IPOINTER; */
8441 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8442 /* p_type = POINTER ; */
8445 /* now that we have the pointer type we assign
8446 the pointer values */
8451 genNearPointerGet (left,result,ic);
8455 genPagedPointerGet(left,result,ic);
8459 genFarPointerGet (left,result,ic);
8463 genConstPointerGet (left,result,ic);
8464 //pic14_emitcodePointerGet (left,result,ic);
8469 if (IS_PTR_CONST(type))
8470 genConstPointerGet (left,result,ic);
8473 genGenPointerGet (left,result,ic);
8479 /*-----------------------------------------------------------------*/
8480 /* genPackBits - generates code for packed bit storage */
8481 /*-----------------------------------------------------------------*/
8482 static void genPackBits (sym_link *etype ,
8484 char *rname, int p_type)
8492 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8493 blen = SPEC_BLEN(etype);
8494 bstr = SPEC_BSTR(etype);
8496 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8499 /* if the bit lenth is less than or */
8500 /* it exactly fits a byte then */
8501 if (SPEC_BLEN(etype) <= 8 ) {
8502 shCount = SPEC_BSTR(etype) ;
8504 /* shift left acc */
8507 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8512 pic14_emitcode ("mov","b,a");
8513 pic14_emitcode("mov","a,@%s",rname);
8517 pic14_emitcode ("mov","b,a");
8518 pic14_emitcode("movx","a,@dptr");
8522 pic14_emitcode ("push","b");
8523 pic14_emitcode ("push","acc");
8524 pic14_emitcode ("lcall","__gptrget");
8525 pic14_emitcode ("pop","b");
8529 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8530 ((unsigned char)(0xFF << (blen+bstr)) |
8531 (unsigned char)(0xFF >> (8-bstr)) ) );
8532 pic14_emitcode ("orl","a,b");
8533 if (p_type == GPOINTER)
8534 pic14_emitcode("pop","b");
8540 pic14_emitcode("mov","@%s,a",rname);
8544 pic14_emitcode("movx","@dptr,a");
8548 DEBUGpic14_emitcode(";lcall","__gptrput");
8553 if ( SPEC_BLEN(etype) <= 8 )
8556 pic14_emitcode("inc","%s",rname);
8557 rLen = SPEC_BLEN(etype) ;
8559 /* now generate for lengths greater than one byte */
8562 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8572 pic14_emitcode("mov","@%s,a",rname);
8574 pic14_emitcode("mov","@%s,%s",rname,l);
8579 pic14_emitcode("movx","@dptr,a");
8584 DEBUGpic14_emitcode(";lcall","__gptrput");
8587 pic14_emitcode ("inc","%s",rname);
8592 /* last last was not complete */
8594 /* save the byte & read byte */
8597 pic14_emitcode ("mov","b,a");
8598 pic14_emitcode("mov","a,@%s",rname);
8602 pic14_emitcode ("mov","b,a");
8603 pic14_emitcode("movx","a,@dptr");
8607 pic14_emitcode ("push","b");
8608 pic14_emitcode ("push","acc");
8609 pic14_emitcode ("lcall","__gptrget");
8610 pic14_emitcode ("pop","b");
8614 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8615 pic14_emitcode ("orl","a,b");
8618 if (p_type == GPOINTER)
8619 pic14_emitcode("pop","b");
8624 pic14_emitcode("mov","@%s,a",rname);
8628 pic14_emitcode("movx","@dptr,a");
8632 DEBUGpic14_emitcode(";lcall","__gptrput");
8636 /*-----------------------------------------------------------------*/
8637 /* genDataPointerSet - remat pointer to data space */
8638 /*-----------------------------------------------------------------*/
8639 static void genDataPointerSet(operand *right,
8643 int size, offset = 0 ;
8644 char *l, buffer[256];
8646 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8647 aopOp(right,ic,FALSE);
8649 l = aopGet(AOP(result),0,FALSE,TRUE);
8650 size = AOP_SIZE(right);
8652 if ( AOP_TYPE(result) == AOP_PCODE) {
8653 fprintf(stderr,"genDataPointerSet %s, %d\n",
8654 AOP(result)->aopu.pcop->name,
8655 PCOI(AOP(result)->aopu.pcop)->offset);
8659 // tsd, was l+1 - the underline `_' prefix was being stripped
8662 sprintf(buffer,"(%s + %d)",l,offset);
8663 fprintf(stderr,"oops %s\n",buffer);
8665 sprintf(buffer,"%s",l);
8667 if (AOP_TYPE(right) == AOP_LIT) {
8668 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8669 lit = lit >> (8*offset);
8671 pic14_emitcode("movlw","%d",lit);
8672 pic14_emitcode("movwf","%s",buffer);
8674 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8675 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8676 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8679 pic14_emitcode("clrf","%s",buffer);
8680 //emitpcode(POC_CLRF, popRegFromString(buffer));
8681 emitpcode(POC_CLRF, popGet(AOP(result),0));
8684 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8685 pic14_emitcode("movwf","%s",buffer);
8687 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8688 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8689 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8696 freeAsmop(right,NULL,ic,TRUE);
8697 freeAsmop(result,NULL,ic,TRUE);
8700 /*-----------------------------------------------------------------*/
8701 /* genNearPointerSet - pic14_emitcode for near pointer put */
8702 /*-----------------------------------------------------------------*/
8703 static void genNearPointerSet (operand *right,
8710 sym_link *ptype = operandType(result);
8713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8714 retype= getSpec(operandType(right));
8716 aopOp(result,ic,FALSE);
8719 /* if the result is rematerializable &
8720 in data space & not a bit variable */
8721 //if (AOP_TYPE(result) == AOP_IMMD &&
8722 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8723 DCL_TYPE(ptype) == POINTER &&
8724 !IS_BITVAR(retype)) {
8725 genDataPointerSet (right,result,ic);
8726 freeAsmop(result,NULL,ic,TRUE);
8730 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8731 aopOp(right,ic,FALSE);
8732 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8734 /* if the value is already in a pointer register
8735 then don't need anything more */
8736 if (!AOP_INPREG(AOP(result))) {
8737 /* otherwise get a free pointer register */
8738 //aop = newAsmop(0);
8739 //preg = getFreePtr(ic,&aop,FALSE);
8740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8741 //pic14_emitcode("mov","%s,%s",
8743 // aopGet(AOP(result),0,FALSE,TRUE));
8744 //rname = preg->name ;
8745 //pic14_emitcode("movwf","fsr");
8746 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8747 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8748 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8749 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8753 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8756 /* if bitfield then unpack the bits */
8757 if (IS_BITVAR(retype)) {
8758 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8759 "The programmer is obviously confused");
8760 //genPackBits (retype,right,rname,POINTER);
8764 /* we have can just get the values */
8765 int size = AOP_SIZE(right);
8768 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8770 l = aopGet(AOP(right),offset,FALSE,TRUE);
8773 //pic14_emitcode("mov","@%s,a",rname);
8774 pic14_emitcode("movf","indf,w ;1");
8777 if (AOP_TYPE(right) == AOP_LIT) {
8778 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8780 pic14_emitcode("movlw","%s",l);
8781 pic14_emitcode("movwf","indf ;2");
8783 pic14_emitcode("clrf","indf");
8785 pic14_emitcode("movf","%s,w",l);
8786 pic14_emitcode("movwf","indf ;2");
8788 //pic14_emitcode("mov","@%s,%s",rname,l);
8791 pic14_emitcode("incf","fsr,f ;3");
8792 //pic14_emitcode("inc","%s",rname);
8797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8798 /* now some housekeeping stuff */
8800 /* we had to allocate for this iCode */
8801 freeAsmop(NULL,aop,ic,TRUE);
8803 /* we did not allocate which means left
8804 already in a pointer register, then
8805 if size > 0 && this could be used again
8806 we have to point it back to where it
8808 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8809 if (AOP_SIZE(right) > 1 &&
8810 !OP_SYMBOL(result)->remat &&
8811 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8813 int size = AOP_SIZE(right) - 1;
8815 pic14_emitcode("decf","fsr,f");
8816 //pic14_emitcode("dec","%s",rname);
8820 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8823 freeAsmop(right,NULL,ic,TRUE);
8824 freeAsmop(result,NULL,ic,TRUE);
8827 /*-----------------------------------------------------------------*/
8828 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8829 /*-----------------------------------------------------------------*/
8830 static void genPagedPointerSet (operand *right,
8839 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8841 retype= getSpec(operandType(right));
8843 aopOp(result,ic,FALSE);
8845 /* if the value is already in a pointer register
8846 then don't need anything more */
8847 if (!AOP_INPREG(AOP(result))) {
8848 /* otherwise get a free pointer register */
8850 preg = getFreePtr(ic,&aop,FALSE);
8851 pic14_emitcode("mov","%s,%s",
8853 aopGet(AOP(result),0,FALSE,TRUE));
8854 rname = preg->name ;
8856 rname = aopGet(AOP(result),0,FALSE,FALSE);
8858 freeAsmop(result,NULL,ic,TRUE);
8859 aopOp (right,ic,FALSE);
8861 /* if bitfield then unpack the bits */
8862 if (IS_BITVAR(retype))
8863 genPackBits (retype,right,rname,PPOINTER);
8865 /* we have can just get the values */
8866 int size = AOP_SIZE(right);
8870 l = aopGet(AOP(right),offset,FALSE,TRUE);
8873 pic14_emitcode("movx","@%s,a",rname);
8876 pic14_emitcode("inc","%s",rname);
8882 /* now some housekeeping stuff */
8884 /* we had to allocate for this iCode */
8885 freeAsmop(NULL,aop,ic,TRUE);
8887 /* we did not allocate which means left
8888 already in a pointer register, then
8889 if size > 0 && this could be used again
8890 we have to point it back to where it
8892 if (AOP_SIZE(right) > 1 &&
8893 !OP_SYMBOL(result)->remat &&
8894 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8896 int size = AOP_SIZE(right) - 1;
8898 pic14_emitcode("dec","%s",rname);
8903 freeAsmop(right,NULL,ic,TRUE);
8908 /*-----------------------------------------------------------------*/
8909 /* genFarPointerSet - set value from far space */
8910 /*-----------------------------------------------------------------*/
8911 static void genFarPointerSet (operand *right,
8912 operand *result, iCode *ic)
8915 sym_link *retype = getSpec(operandType(right));
8917 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8918 aopOp(result,ic,FALSE);
8920 /* if the operand is already in dptr
8921 then we do nothing else we move the value to dptr */
8922 if (AOP_TYPE(result) != AOP_STR) {
8923 /* if this is remateriazable */
8924 if (AOP_TYPE(result) == AOP_IMMD)
8925 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8926 else { /* we need to get it byte by byte */
8927 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8928 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8929 if (options.model == MODEL_FLAT24)
8931 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8935 /* so dptr know contains the address */
8936 freeAsmop(result,NULL,ic,TRUE);
8937 aopOp(right,ic,FALSE);
8939 /* if bit then unpack */
8940 if (IS_BITVAR(retype))
8941 genPackBits(retype,right,"dptr",FPOINTER);
8943 size = AOP_SIZE(right);
8947 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8949 pic14_emitcode("movx","@dptr,a");
8951 pic14_emitcode("inc","dptr");
8955 freeAsmop(right,NULL,ic,TRUE);
8958 /*-----------------------------------------------------------------*/
8959 /* genGenPointerSet - set value from generic pointer space */
8960 /*-----------------------------------------------------------------*/
8961 static void genGenPointerSet (operand *right,
8962 operand *result, iCode *ic)
8965 sym_link *retype = getSpec(operandType(right));
8967 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8969 aopOp(result,ic,FALSE);
8970 aopOp(right,ic,FALSE);
8971 size = AOP_SIZE(right);
8973 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8975 /* if the operand is already in dptr
8976 then we do nothing else we move the value to dptr */
8977 if (AOP_TYPE(result) != AOP_STR) {
8978 /* if this is remateriazable */
8979 if (AOP_TYPE(result) == AOP_IMMD) {
8980 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8981 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8983 else { /* we need to get it byte by byte */
8984 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8985 size = AOP_SIZE(right);
8988 /* hack hack! see if this the FSR. If so don't load W */
8989 if(AOP_TYPE(right) != AOP_ACC) {
8992 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8993 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8995 if(AOP_SIZE(result) > 1) {
8996 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8997 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8998 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
9003 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
9005 // emitpcode(POC_MOVLW,popGetLit(0xfd));
9006 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
9010 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9011 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9014 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9021 if(aopIdx(AOP(result),0) != 4) {
9023 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9027 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9032 /* so dptr know contains the address */
9035 /* if bit then unpack */
9036 if (IS_BITVAR(retype))
9037 genPackBits(retype,right,"dptr",GPOINTER);
9039 size = AOP_SIZE(right);
9042 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9046 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9047 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9049 if (AOP_TYPE(right) == AOP_LIT)
9050 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9052 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9054 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9061 freeAsmop(right,NULL,ic,TRUE);
9062 freeAsmop(result,NULL,ic,TRUE);
9065 /*-----------------------------------------------------------------*/
9066 /* genPointerSet - stores the value into a pointer location */
9067 /*-----------------------------------------------------------------*/
9068 static void genPointerSet (iCode *ic)
9070 operand *right, *result ;
9071 sym_link *type, *etype;
9074 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9076 right = IC_RIGHT(ic);
9077 result = IC_RESULT(ic) ;
9079 /* depending on the type of pointer we need to
9080 move it to the correct pointer register */
9081 type = operandType(result);
9082 etype = getSpec(type);
9083 /* if left is of type of pointer then it is simple */
9084 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9085 p_type = DCL_TYPE(type);
9088 /* we have to go by the storage class */
9089 p_type = PTR_TYPE(SPEC_OCLS(etype));
9091 /* if (SPEC_OCLS(etype)->codesp ) { */
9092 /* p_type = CPOINTER ; */
9095 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9096 /* p_type = FPOINTER ; */
9098 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9099 /* p_type = PPOINTER ; */
9101 /* if (SPEC_OCLS(etype) == idata ) */
9102 /* p_type = IPOINTER ; */
9104 /* p_type = POINTER ; */
9107 /* now that we have the pointer type we assign
9108 the pointer values */
9113 genNearPointerSet (right,result,ic);
9117 genPagedPointerSet (right,result,ic);
9121 genFarPointerSet (right,result,ic);
9125 genGenPointerSet (right,result,ic);
9129 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9130 "genPointerSet: illegal pointer type");
9134 /*-----------------------------------------------------------------*/
9135 /* genIfx - generate code for Ifx statement */
9136 /*-----------------------------------------------------------------*/
9137 static void genIfx (iCode *ic, iCode *popIc)
9139 operand *cond = IC_COND(ic);
9142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9144 aopOp(cond,ic,FALSE);
9146 /* get the value into acc */
9147 if (AOP_TYPE(cond) != AOP_CRY)
9148 pic14_toBoolean(cond);
9151 /* the result is now in the accumulator */
9152 freeAsmop(cond,NULL,ic,TRUE);
9154 /* if there was something to be popped then do it */
9158 /* if the condition is a bit variable */
9159 if (isbit && IS_ITEMP(cond) &&
9161 genIfxJump(ic,SPIL_LOC(cond)->rname);
9162 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9165 if (isbit && !IS_ITEMP(cond))
9166 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9174 /*-----------------------------------------------------------------*/
9175 /* genAddrOf - generates code for address of */
9176 /*-----------------------------------------------------------------*/
9177 static void genAddrOf (iCode *ic)
9179 operand *right, *result, *left;
9182 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9185 //aopOp(IC_RESULT(ic),ic,FALSE);
9187 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9188 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9189 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9191 DEBUGpic14_AopType(__LINE__,left,right,result);
9193 size = AOP_SIZE(IC_RESULT(ic));
9197 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9198 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9202 freeAsmop(left,NULL,ic,FALSE);
9203 freeAsmop(result,NULL,ic,TRUE);
9208 /*-----------------------------------------------------------------*/
9209 /* genFarFarAssign - assignment when both are in far space */
9210 /*-----------------------------------------------------------------*/
9211 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9213 int size = AOP_SIZE(right);
9216 /* first push the right side on to the stack */
9218 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9220 pic14_emitcode ("push","acc");
9223 freeAsmop(right,NULL,ic,FALSE);
9224 /* now assign DPTR to result */
9225 aopOp(result,ic,FALSE);
9226 size = AOP_SIZE(result);
9228 pic14_emitcode ("pop","acc");
9229 aopPut(AOP(result),"a",--offset);
9231 freeAsmop(result,NULL,ic,FALSE);
9236 /*-----------------------------------------------------------------*/
9237 /* genAssign - generate code for assignment */
9238 /*-----------------------------------------------------------------*/
9239 static void genAssign (iCode *ic)
9241 operand *result, *right;
9242 int size, offset,know_W;
9243 unsigned long lit = 0L;
9245 result = IC_RESULT(ic);
9246 right = IC_RIGHT(ic) ;
9248 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9250 /* if they are the same */
9251 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9254 aopOp(right,ic,FALSE);
9255 aopOp(result,ic,TRUE);
9257 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9259 /* if they are the same registers */
9260 if (pic14_sameRegs(AOP(right),AOP(result)))
9263 /* if the result is a bit */
9264 if (AOP_TYPE(result) == AOP_CRY) {
9266 /* if the right size is a literal then
9267 we know what the value is */
9268 if (AOP_TYPE(right) == AOP_LIT) {
9270 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9271 popGet(AOP(result),0));
9273 if (((int) operandLitValue(right)))
9274 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9275 AOP(result)->aopu.aop_dir,
9276 AOP(result)->aopu.aop_dir);
9278 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9279 AOP(result)->aopu.aop_dir,
9280 AOP(result)->aopu.aop_dir);
9284 /* the right is also a bit variable */
9285 if (AOP_TYPE(right) == AOP_CRY) {
9286 emitpcode(POC_BCF, popGet(AOP(result),0));
9287 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9288 emitpcode(POC_BSF, popGet(AOP(result),0));
9290 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9291 AOP(result)->aopu.aop_dir,
9292 AOP(result)->aopu.aop_dir);
9293 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9294 AOP(right)->aopu.aop_dir,
9295 AOP(right)->aopu.aop_dir);
9296 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9297 AOP(result)->aopu.aop_dir,
9298 AOP(result)->aopu.aop_dir);
9303 emitpcode(POC_BCF, popGet(AOP(result),0));
9304 pic14_toBoolean(right);
9306 emitpcode(POC_BSF, popGet(AOP(result),0));
9307 //aopPut(AOP(result),"a",0);
9311 /* bit variables done */
9313 size = AOP_SIZE(result);
9315 if(AOP_TYPE(right) == AOP_LIT)
9316 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9318 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9319 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9320 if(aopIdx(AOP(result),0) == 4) {
9321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9322 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9323 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9326 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9331 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9332 if(AOP_TYPE(right) == AOP_LIT) {
9334 if(know_W != (int)(lit&0xff))
9335 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9337 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9339 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9343 } else if (AOP_TYPE(right) == AOP_CRY) {
9344 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9346 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9347 emitpcode(POC_INCF, popGet(AOP(result),0));
9350 mov2w (AOP(right), offset);
9351 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9359 freeAsmop (right,NULL,ic,FALSE);
9360 freeAsmop (result,NULL,ic,TRUE);
9363 /*-----------------------------------------------------------------*/
9364 /* genJumpTab - genrates code for jump table */
9365 /*-----------------------------------------------------------------*/
9366 static void genJumpTab (iCode *ic)
9371 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9373 aopOp(IC_JTCOND(ic),ic,FALSE);
9374 /* get the condition into accumulator */
9375 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9377 /* multiply by three */
9378 pic14_emitcode("add","a,acc");
9379 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9381 jtab = newiTempLabel(NULL);
9382 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9383 pic14_emitcode("jmp","@a+dptr");
9384 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9386 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9387 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9388 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9389 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9391 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9392 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9393 emitpLabel(jtab->key);
9395 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9397 /* now generate the jump labels */
9398 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9399 jtab = setNextItem(IC_JTLABELS(ic))) {
9400 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9401 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9407 /*-----------------------------------------------------------------*/
9408 /* genMixedOperation - gen code for operators between mixed types */
9409 /*-----------------------------------------------------------------*/
9411 TSD - Written for the PIC port - but this unfortunately is buggy.
9412 This routine is good in that it is able to efficiently promote
9413 types to different (larger) sizes. Unfortunately, the temporary
9414 variables that are optimized out by this routine are sometimes
9415 used in other places. So until I know how to really parse the
9416 iCode tree, I'm going to not be using this routine :(.
9418 static int genMixedOperation (iCode *ic)
9421 operand *result = IC_RESULT(ic);
9422 sym_link *ctype = operandType(IC_LEFT(ic));
9423 operand *right = IC_RIGHT(ic);
9429 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9431 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9437 nextright = IC_RIGHT(nextic);
9438 nextleft = IC_LEFT(nextic);
9439 nextresult = IC_RESULT(nextic);
9441 aopOp(right,ic,FALSE);
9442 aopOp(result,ic,FALSE);
9443 aopOp(nextright, nextic, FALSE);
9444 aopOp(nextleft, nextic, FALSE);
9445 aopOp(nextresult, nextic, FALSE);
9447 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9453 pic14_emitcode(";remove right +","");
9455 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9461 pic14_emitcode(";remove left +","");
9465 big = AOP_SIZE(nextleft);
9466 small = AOP_SIZE(nextright);
9468 switch(nextic->op) {
9471 pic14_emitcode(";optimize a +","");
9472 /* if unsigned or not an integral type */
9473 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9474 pic14_emitcode(";add a bit to something","");
9477 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9479 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9480 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9481 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9483 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9491 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9492 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9493 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9496 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9498 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9499 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9500 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9501 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9502 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9505 pic14_emitcode("rlf","known_zero,w");
9512 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9513 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9514 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9516 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9526 freeAsmop(right,NULL,ic,TRUE);
9527 freeAsmop(result,NULL,ic,TRUE);
9528 freeAsmop(nextright,NULL,ic,TRUE);
9529 freeAsmop(nextleft,NULL,ic,TRUE);
9531 nextic->generated = 1;
9538 /*-----------------------------------------------------------------*/
9539 /* genCast - gen code for casting */
9540 /*-----------------------------------------------------------------*/
9541 static void genCast (iCode *ic)
9543 operand *result = IC_RESULT(ic);
9544 sym_link *ctype = operandType(IC_LEFT(ic));
9545 sym_link *rtype = operandType(IC_RIGHT(ic));
9546 operand *right = IC_RIGHT(ic);
9549 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9550 /* if they are equivalent then do nothing */
9551 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9554 aopOp(right,ic,FALSE) ;
9555 aopOp(result,ic,FALSE);
9557 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9559 /* if the result is a bit */
9560 if (AOP_TYPE(result) == AOP_CRY) {
9561 /* if the right size is a literal then
9562 we know what the value is */
9563 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9564 if (AOP_TYPE(right) == AOP_LIT) {
9566 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9567 popGet(AOP(result),0));
9569 if (((int) operandLitValue(right)))
9570 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9571 AOP(result)->aopu.aop_dir,
9572 AOP(result)->aopu.aop_dir);
9574 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9575 AOP(result)->aopu.aop_dir,
9576 AOP(result)->aopu.aop_dir);
9581 /* the right is also a bit variable */
9582 if (AOP_TYPE(right) == AOP_CRY) {
9585 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9587 pic14_emitcode("clrc","");
9588 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9589 AOP(right)->aopu.aop_dir,
9590 AOP(right)->aopu.aop_dir);
9591 aopPut(AOP(result),"c",0);
9596 if (AOP_TYPE(right) == AOP_REG) {
9597 emitpcode(POC_BCF, popGet(AOP(result),0));
9598 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9599 emitpcode(POC_BSF, popGet(AOP(result),0));
9601 pic14_toBoolean(right);
9602 aopPut(AOP(result),"a",0);
9606 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9608 size = AOP_SIZE(result);
9610 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9612 emitpcode(POC_CLRF, popGet(AOP(result),0));
9613 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9614 emitpcode(POC_INCF, popGet(AOP(result),0));
9617 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9622 /* if they are the same size : or less */
9623 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9625 /* if they are in the same place */
9626 if (pic14_sameRegs(AOP(right),AOP(result)))
9629 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9631 if (IS_PTR_CONST(rtype))
9633 if (IS_CODEPTR(rtype))
9635 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9637 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9639 if (IS_CODEPTR(operandType(IC_RESULT(ic))))
9641 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9643 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9644 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9645 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9646 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9647 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9648 if(AOP_SIZE(result) <2)
9649 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9653 /* if they in different places then copy */
9654 size = AOP_SIZE(result);
9657 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9658 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9660 //aopPut(AOP(result),
9661 // aopGet(AOP(right),offset,FALSE,FALSE),
9671 /* if the result is of type pointer */
9672 if (IS_PTR(ctype)) {
9675 sym_link *type = operandType(right);
9676 sym_link *etype = getSpec(type);
9677 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9679 /* pointer to generic pointer */
9680 if (IS_GENPTR(ctype)) {
9684 p_type = DCL_TYPE(type);
9686 /* we have to go by the storage class */
9687 p_type = PTR_TYPE(SPEC_OCLS(etype));
9689 /* if (SPEC_OCLS(etype)->codesp ) */
9690 /* p_type = CPOINTER ; */
9692 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9693 /* p_type = FPOINTER ; */
9695 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9696 /* p_type = PPOINTER; */
9698 /* if (SPEC_OCLS(etype) == idata ) */
9699 /* p_type = IPOINTER ; */
9701 /* p_type = POINTER ; */
9704 /* the first two bytes are known */
9705 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9706 size = GPTRSIZE - 1;
9709 if(offset < AOP_SIZE(right)) {
9710 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9711 if ((AOP_TYPE(right) == AOP_PCODE) &&
9712 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9713 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9714 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9717 aopGet(AOP(right),offset,FALSE,FALSE),
9721 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9724 /* the last byte depending on type */
9728 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9731 pic14_emitcode(";BUG!? ","%d",__LINE__);
9735 pic14_emitcode(";BUG!? ","%d",__LINE__);
9739 pic14_emitcode(";BUG!? ","%d",__LINE__);
9744 /* this should never happen */
9745 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9746 "got unknown pointer type");
9749 //aopPut(AOP(result),l, GPTRSIZE - 1);
9753 /* just copy the pointers */
9754 size = AOP_SIZE(result);
9758 aopGet(AOP(right),offset,FALSE,FALSE),
9767 /* so we now know that the size of destination is greater
9768 than the size of the source.
9769 Now, if the next iCode is an operator then we might be
9770 able to optimize the operation without performing a cast.
9772 if(genMixedOperation(ic))
9775 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9777 /* we move to result for the size of source */
9778 size = AOP_SIZE(right);
9781 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9782 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9786 /* now depending on the sign of the destination */
9787 size = AOP_SIZE(result) - AOP_SIZE(right);
9788 /* if unsigned or not an integral type */
9789 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9791 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9793 /* we need to extend the sign :{ */
9796 /* Save one instruction of casting char to int */
9797 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9798 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9799 emitpcode(POC_DECF, popGet(AOP(result),offset));
9801 emitpcodeNULLop(POC_CLRW);
9804 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9806 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9808 emitpcode(POC_MOVLW, popGetLit(0xff));
9811 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9816 freeAsmop(right,NULL,ic,TRUE);
9817 freeAsmop(result,NULL,ic,TRUE);
9821 /*-----------------------------------------------------------------*/
9822 /* genDjnz - generate decrement & jump if not zero instrucion */
9823 /*-----------------------------------------------------------------*/
9824 static int genDjnz (iCode *ic, iCode *ifx)
9827 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9832 /* if the if condition has a false label
9833 then we cannot save */
9837 /* if the minus is not of the form
9839 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9840 !IS_OP_LITERAL(IC_RIGHT(ic)))
9843 if (operandLitValue(IC_RIGHT(ic)) != 1)
9846 /* if the size of this greater than one then no
9848 if (getSize(operandType(IC_RESULT(ic))) > 1)
9851 /* otherwise we can save BIG */
9852 lbl = newiTempLabel(NULL);
9853 lbl1= newiTempLabel(NULL);
9855 aopOp(IC_RESULT(ic),ic,FALSE);
9857 if (IS_AOP_PREG(IC_RESULT(ic))) {
9858 pic14_emitcode("dec","%s",
9859 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9860 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9861 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9865 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9866 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9868 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9869 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9872 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9873 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9874 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9875 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9878 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9883 /*-----------------------------------------------------------------*/
9884 /* genReceive - generate code for a receive iCode */
9885 /*-----------------------------------------------------------------*/
9886 static void genReceive (iCode *ic)
9888 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9890 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9891 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9892 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9894 int size = getSize(operandType(IC_RESULT(ic)));
9895 int offset = fReturnSizePic - size;
9897 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9898 fReturn[fReturnSizePic - offset - 1] : "acc"));
9901 aopOp(IC_RESULT(ic),ic,FALSE);
9902 size = AOP_SIZE(IC_RESULT(ic));
9905 pic14_emitcode ("pop","acc");
9906 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9911 aopOp(IC_RESULT(ic),ic,FALSE);
9913 assignResultValue(IC_RESULT(ic));
9916 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9919 /*-----------------------------------------------------------------*/
9920 /* genDummyRead - generate code for dummy read of volatiles */
9921 /*-----------------------------------------------------------------*/
9923 genDummyRead (iCode * ic)
9925 pic14_emitcode ("; genDummyRead","");
9926 pic14_emitcode ("; not implemented","");
9931 /*-----------------------------------------------------------------*/
9932 /* genpic14Code - generate code for pic14 based controllers */
9933 /*-----------------------------------------------------------------*/
9935 * At this point, ralloc.c has gone through the iCode and attempted
9936 * to optimize in a way suitable for a PIC. Now we've got to generate
9937 * PIC instructions that correspond to the iCode.
9939 * Once the instructions are generated, we'll pass through both the
9940 * peep hole optimizer and the pCode optimizer.
9941 *-----------------------------------------------------------------*/
9943 void genpic14Code (iCode *lic)
9948 lineHead = lineCurr = NULL;
9950 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9953 /* if debug information required */
9954 if (options.debug && currFunc) {
9956 debugFile->writeFunction(currFunc);
9958 if (IS_STATIC(currFunc->etype)) {
9959 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9960 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9962 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9963 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9970 for (ic = lic ; ic ; ic = ic->next ) {
9972 DEBUGpic14_emitcode(";ic","");
9973 if ( cln != ic->lineno ) {
9974 if ( options.debug ) {
9976 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9977 FileBaseName(ic->filename),ic->lineno,
9978 ic->level,ic->block);
9982 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9983 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9984 printCLine(ic->filename, ic->lineno));
9986 if (!options.noCcodeInAsm) {
9988 newpCodeCSource(ic->lineno,
9990 printCLine(ic->filename, ic->lineno)));
9996 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9998 /* if the result is marked as
9999 spilt and rematerializable or code for
10000 this has already been generated then
10002 if (resultRemat(ic) || ic->generated )
10005 /* depending on the operation */
10024 /* IPOP happens only when trying to restore a
10025 spilt live range, if there is an ifx statement
10026 following this pop then the if statement might
10027 be using some of the registers being popped which
10028 would destory the contents of the register so
10029 we need to check for this condition and handle it */
10031 ic->next->op == IFX &&
10032 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10033 genIfx (ic->next,ic);
10051 genEndFunction (ic);
10071 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10088 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10092 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10099 /* note these two are xlated by algebraic equivalence
10100 during parsing SDCC.y */
10101 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10102 "got '>=' or '<=' shouldn't have come here");
10106 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10118 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10122 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10126 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10150 genRightShift (ic);
10153 case GET_VALUE_AT_ADDRESS:
10158 if (POINTER_SET(ic))
10185 addSet(&_G.sendSet,ic);
10188 case DUMMY_READ_VOLATILE:
10198 /* now we are ready to call the
10199 peep hole optimizer */
10200 if (!options.nopeep) {
10201 peepHole (&lineHead);
10203 /* now do the actual printing */
10204 printLine (lineHead,codeOutFile);
10207 DFPRINTF((stderr,"printing pBlock\n\n"));
10208 printpBlock(stdout,pb);