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);
613 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
614 PCOI(aop->aopu.pcop)->index = val;
616 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
617 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
618 val, IS_PTR_CONST(operandType(op)));
620 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
622 allocDirReg (IC_LEFT(ic));
627 int aopIdx (asmop *aop, int offset)
632 if(aop->type != AOP_REG)
635 return aop->aopu.aop_reg[offset]->rIdx;
638 /*-----------------------------------------------------------------*/
639 /* regsInCommon - two operands have some registers in common */
640 /*-----------------------------------------------------------------*/
641 static bool regsInCommon (operand *op1, operand *op2)
646 /* if they have registers in common */
647 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
650 sym1 = OP_SYMBOL(op1);
651 sym2 = OP_SYMBOL(op2);
653 if (sym1->nRegs == 0 || sym2->nRegs == 0)
656 for (i = 0 ; i < sym1->nRegs ; i++) {
661 for (j = 0 ; j < sym2->nRegs ;j++ ) {
665 if (sym2->regs[j] == sym1->regs[i])
673 /*-----------------------------------------------------------------*/
674 /* operandsEqu - equivalent */
675 /*-----------------------------------------------------------------*/
676 static bool operandsEqu ( operand *op1, operand *op2)
680 /* if they not symbols */
681 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
684 sym1 = OP_SYMBOL(op1);
685 sym2 = OP_SYMBOL(op2);
687 /* if both are itemps & one is spilt
688 and the other is not then false */
689 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
690 sym1->isspilt != sym2->isspilt )
693 /* if they are the same */
697 if (strcmp(sym1->rname,sym2->rname) == 0)
701 /* if left is a tmp & right is not */
705 (sym1->usl.spillLoc == sym2))
712 (sym2->usl.spillLoc == sym1))
718 /*-----------------------------------------------------------------*/
719 /* pic14_sameRegs - two asmops have the same registers */
720 /*-----------------------------------------------------------------*/
721 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
728 if (aop1->type != AOP_REG ||
729 aop2->type != AOP_REG )
732 if (aop1->size != aop2->size )
735 for (i = 0 ; i < aop1->size ; i++ )
736 if (aop1->aopu.aop_reg[i] !=
737 aop2->aopu.aop_reg[i] )
743 /*-----------------------------------------------------------------*/
744 /* aopOp - allocates an asmop for an operand : */
745 /*-----------------------------------------------------------------*/
746 void aopOp (operand *op, iCode *ic, bool result)
755 // DEBUGpic14_emitcode(";","%d",__LINE__);
756 /* if this a literal */
757 if (IS_OP_LITERAL(op)) {
758 op->aop = aop = newAsmop(AOP_LIT);
759 aop->aopu.aop_lit = op->operand.valOperand;
760 aop->size = getSize(operandType(op));
765 sym_link *type = operandType(op);
766 if(IS_PTR_CONST(type))
767 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
770 /* if already has a asmop then continue */
774 /* if the underlying symbol has a aop */
775 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
776 DEBUGpic14_emitcode(";","%d",__LINE__);
777 op->aop = OP_SYMBOL(op)->aop;
781 /* if this is a true symbol */
782 if (IS_TRUE_SYMOP(op)) {
783 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
784 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
788 /* this is a temporary : this has
794 e) can be a return use only */
799 /* if the type is a conditional */
800 if (sym->regType == REG_CND) {
801 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
806 /* if it is spilt then two situations
808 b) has a spill location */
809 if (sym->isspilt || sym->nRegs == 0) {
811 DEBUGpic14_emitcode(";","%d",__LINE__);
812 /* rematerialize it NOW */
815 sym->aop = op->aop = aop =
817 aop->size = getSize(sym->type);
818 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
824 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
825 aop->size = getSize(sym->type);
826 for ( i = 0 ; i < 2 ; i++ )
827 aop->aopu.aop_str[i] = accUse[i];
828 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
833 if(sym->isptr) { // && sym->uptr
834 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
835 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
837 //PCOI(aop->aopu.pcop)->_const = 0;
838 //PCOI(aop->aopu.pcop)->index = 0;
840 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
841 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
843 //allocDirReg (IC_LEFT(ic));
845 aop->size = getSize(sym->type);
846 DEBUGpic14_emitcode(";","%d",__LINE__);
853 aop = op->aop = sym->aop = newAsmop(AOP_STR);
854 aop->size = getSize(sym->type);
855 for ( i = 0 ; i < fReturnSizePic ; i++ )
856 aop->aopu.aop_str[i] = fReturn[i];
858 DEBUGpic14_emitcode(";","%d",__LINE__);
863 /* else spill location */
864 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
865 /* force a new aop if sizes differ */
866 sym->usl.spillLoc->aop = NULL;
868 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
869 __FUNCTION__,__LINE__,
870 sym->usl.spillLoc->rname,
871 sym->rname, sym->usl.spillLoc->offset);
873 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
874 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
875 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
877 sym->usl.spillLoc->offset);
878 aop->size = getSize(sym->type);
884 sym_link *type = operandType(op);
885 if(IS_PTR_CONST(type))
886 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
889 /* must be in a register */
890 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
891 sym->aop = op->aop = aop = newAsmop(AOP_REG);
892 aop->size = sym->nRegs;
893 for ( i = 0 ; i < sym->nRegs ;i++)
894 aop->aopu.aop_reg[i] = sym->regs[i];
897 /*-----------------------------------------------------------------*/
898 /* freeAsmop - free up the asmop given to an operand */
899 /*----------------------------------------------------------------*/
900 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
917 /* depending on the asmop type only three cases need work AOP_RO
918 , AOP_R1 && AOP_STK */
924 pic14_emitcode ("pop","ar0");
928 bitVectUnSetBit(ic->rUsed,R0_IDX);
934 pic14_emitcode ("pop","ar1");
938 bitVectUnSetBit(ic->rUsed,R1_IDX);
944 int stk = aop->aopu.aop_stk + aop->size;
945 bitVectUnSetBit(ic->rUsed,R0_IDX);
946 bitVectUnSetBit(ic->rUsed,R1_IDX);
948 getFreePtr(ic,&aop,FALSE);
950 if (options.stack10bit)
952 /* I'm not sure what to do here yet... */
955 "*** Warning: probably generating bad code for "
956 "10 bit stack mode.\n");
960 pic14_emitcode ("mov","a,_bp");
961 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
962 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
964 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
968 pic14_emitcode("pop","acc");
969 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
971 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
974 freeAsmop(op,NULL,ic,TRUE);
976 pic14_emitcode("pop","ar0");
981 pic14_emitcode("pop","ar1");
989 /* all other cases just dealloc */
993 OP_SYMBOL(op)->aop = NULL;
994 /* if the symbol has a spill */
996 SPIL_LOC(op)->aop = NULL;
1001 /*-----------------------------------------------------------------*/
1002 /* aopGet - for fetching value of the aop */
1003 /*-----------------------------------------------------------------*/
1004 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1009 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1010 /* offset is greater than
1012 if (offset > (aop->size - 1) &&
1013 aop->type != AOP_LIT)
1016 /* depending on type */
1017 switch (aop->type) {
1021 DEBUGpic14_emitcode(";","%d",__LINE__);
1022 /* if we need to increment it */
1023 while (offset > aop->coff) {
1024 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1028 while (offset < aop->coff) {
1029 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1033 aop->coff = offset ;
1035 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1036 return (dname ? "acc" : "a");
1038 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1039 rs = Safe_calloc(1,strlen(s)+1);
1045 DEBUGpic14_emitcode(";","%d",__LINE__);
1046 if (aop->type == AOP_DPTR2)
1051 while (offset > aop->coff) {
1052 pic14_emitcode ("inc","dptr");
1056 while (offset < aop->coff) {
1057 pic14_emitcode("lcall","__decdptr");
1063 pic14_emitcode("clr","a");
1064 pic14_emitcode("movc","a,@a+dptr");
1067 pic14_emitcode("movx","a,@dptr");
1070 if (aop->type == AOP_DPTR2)
1075 return (dname ? "acc" : "a");
1080 sprintf (s,"%s",aop->aopu.aop_immd);
1083 sprintf(s,"(%s >> %d)",
1088 aop->aopu.aop_immd);
1089 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1090 rs = Safe_calloc(1,strlen(s)+1);
1096 sprintf(s,"(%s + %d)",
1099 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1101 sprintf(s,"%s",aop->aopu.aop_dir);
1102 rs = Safe_calloc(1,strlen(s)+1);
1108 // return aop->aopu.aop_reg[offset]->dname;
1110 return aop->aopu.aop_reg[offset]->name;
1113 //pic14_emitcode(";","%d",__LINE__);
1114 return aop->aopu.aop_dir;
1117 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1118 return "AOP_accumulator_bug";
1121 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1122 rs = Safe_calloc(1,strlen(s)+1);
1127 aop->coff = offset ;
1128 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1131 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1133 return aop->aopu.aop_str[offset];
1137 pCodeOp *pcop = aop->aopu.pcop;
1138 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1140 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1141 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1142 sprintf(s,"%s", pcop->name);
1144 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1147 rs = Safe_calloc(1,strlen(s)+1);
1153 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1154 "aopget got unsupported aop->type");
1159 /*-----------------------------------------------------------------*/
1160 /* popGetTempReg - create a new temporary pCodeOp */
1161 /*-----------------------------------------------------------------*/
1162 pCodeOp *popGetTempReg(void)
1167 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1168 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1169 PCOR(pcop)->r->wasUsed=1;
1170 PCOR(pcop)->r->isFree=0;
1176 /*-----------------------------------------------------------------*/
1177 /* popGetTempReg - create a new temporary pCodeOp */
1178 /*-----------------------------------------------------------------*/
1179 void popReleaseTempReg(pCodeOp *pcop)
1182 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1183 PCOR(pcop)->r->isFree = 1;
1186 /*-----------------------------------------------------------------*/
1187 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1188 /*-----------------------------------------------------------------*/
1189 pCodeOp *popGetLabel(unsigned int key)
1192 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1194 if(key>(unsigned int)max_key)
1197 return newpCodeOpLabel(NULL,key+100+labelOffset);
1200 /*-------------------------------------------------------------------*/
1201 /* popGetLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1202 /*-------------------------------------------------------------------*/
1203 pCodeOp *popGetHighLabel(unsigned int key)
1206 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1208 if(key>(unsigned int)max_key)
1211 pcop = newpCodeOpLabel(NULL,key+100+labelOffset);
1212 PCOLAB(pcop)->offset = 1;
1216 /*-----------------------------------------------------------------*/
1217 /* popCopyReg - copy a pcode operator */
1218 /*-----------------------------------------------------------------*/
1219 pCodeOp *popCopyReg(pCodeOpReg *pc)
1223 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1224 pcor->pcop.type = pc->pcop.type;
1226 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1227 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1229 pcor->pcop.name = NULL;
1232 pcor->rIdx = pc->rIdx;
1235 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1239 /*-----------------------------------------------------------------*/
1240 /* popGet - asm operator to pcode operator conversion */
1241 /*-----------------------------------------------------------------*/
1242 pCodeOp *popGetLit(unsigned int lit)
1245 return newpCodeOpLit(lit);
1249 /*-----------------------------------------------------------------*/
1250 /* popGetImmd - asm operator to pcode immediate conversion */
1251 /*-----------------------------------------------------------------*/
1252 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1255 return newpCodeOpImmd(name, offset,index, 0, is_func);
1259 /*-----------------------------------------------------------------*/
1260 /* popGet - asm operator to pcode operator conversion */
1261 /*-----------------------------------------------------------------*/
1262 pCodeOp *popGetWithString(char *str)
1268 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1272 pcop = newpCodeOp(str,PO_STR);
1277 /*-----------------------------------------------------------------*/
1278 /* popRegFromString - */
1279 /*-----------------------------------------------------------------*/
1280 pCodeOp *popRegFromString(char *str, int size, int offset)
1283 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1284 pcop->type = PO_DIR;
1286 DEBUGpic14_emitcode(";","%d",__LINE__);
1291 pcop->name = Safe_calloc(1,strlen(str)+1);
1292 strcpy(pcop->name,str);
1294 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1296 PCOR(pcop)->r = dirregWithName(pcop->name);
1297 if(PCOR(pcop)->r == NULL) {
1298 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1299 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1300 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1302 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1304 PCOR(pcop)->instance = offset;
1309 pCodeOp *popRegFromIdx(int rIdx)
1313 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1314 __FUNCTION__,__LINE__,rIdx);
1316 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1318 PCOR(pcop)->rIdx = rIdx;
1319 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1320 PCOR(pcop)->r->isFree = 0;
1321 PCOR(pcop)->r->wasUsed = 1;
1323 pcop->type = PCOR(pcop)->r->pc_type;
1328 /*-----------------------------------------------------------------*/
1329 /* popGet - asm operator to pcode operator conversion */
1330 /*-----------------------------------------------------------------*/
1331 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1333 //char *s = buffer ;
1338 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1339 /* offset is greater than
1342 if (offset > (aop->size - 1) &&
1343 aop->type != AOP_LIT)
1344 return NULL; //zero;
1346 /* depending on type */
1347 switch (aop->type) {
1354 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1358 DEBUGpic14_emitcode(";","%d",__LINE__);
1359 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1362 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1364 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1365 pcop->type = PO_DIR;
1369 sprintf(s,"(%s + %d)",
1373 sprintf(s,"%s",aop->aopu.aop_dir);
1374 pcop->name = Safe_calloc(1,strlen(s)+1);
1375 strcpy(pcop->name,s);
1377 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1378 strcpy(pcop->name,aop->aopu.aop_dir);
1379 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1380 if(PCOR(pcop)->r == NULL) {
1381 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1382 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1383 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1385 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1387 PCOR(pcop)->instance = offset;
1394 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1396 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1397 PCOR(pcop)->rIdx = rIdx;
1398 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1399 PCOR(pcop)->r->wasUsed=1;
1400 PCOR(pcop)->r->isFree=0;
1402 PCOR(pcop)->instance = offset;
1403 pcop->type = PCOR(pcop)->r->pc_type;
1404 //rs = aop->aopu.aop_reg[offset]->name;
1405 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1410 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1411 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1412 //if(PCOR(pcop)->r == NULL)
1413 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1417 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1420 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1421 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1423 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1424 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1425 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1426 pcop->type = PCOR(pcop)->r->pc_type;
1427 pcop->name = PCOR(pcop)->r->name;
1433 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1435 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1436 pcop = pCodeOpCopy(aop->aopu.pcop);
1437 PCOI(pcop)->offset = offset;
1441 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1442 "popGet got unsupported aop->type");
1445 /*-----------------------------------------------------------------*/
1446 /* aopPut - puts a string for a aop */
1447 /*-----------------------------------------------------------------*/
1448 void aopPut (asmop *aop, char *s, int offset)
1453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1455 if (aop->size && offset > ( aop->size - 1)) {
1456 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1457 "aopPut got offset > aop->size");
1461 /* will assign value to value */
1462 /* depending on where it is ofcourse */
1463 switch (aop->type) {
1466 sprintf(d,"(%s + %d)",
1467 aop->aopu.aop_dir,offset);
1468 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1471 sprintf(d,"%s",aop->aopu.aop_dir);
1474 DEBUGpic14_emitcode(";","%d",__LINE__);
1476 pic14_emitcode("movf","%s,w",s);
1477 pic14_emitcode("movwf","%s",d);
1480 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1481 if(offset >= aop->size) {
1482 emitpcode(POC_CLRF,popGet(aop,offset));
1485 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1488 emitpcode(POC_MOVWF,popGet(aop,offset));
1495 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1496 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1499 strcmp(s,"r0") == 0 ||
1500 strcmp(s,"r1") == 0 ||
1501 strcmp(s,"r2") == 0 ||
1502 strcmp(s,"r3") == 0 ||
1503 strcmp(s,"r4") == 0 ||
1504 strcmp(s,"r5") == 0 ||
1505 strcmp(s,"r6") == 0 ||
1506 strcmp(s,"r7") == 0 )
1507 pic14_emitcode("mov","%s,%s ; %d",
1508 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1512 if(strcmp(s,"W")==0 )
1513 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1515 pic14_emitcode("movwf","%s",
1516 aop->aopu.aop_reg[offset]->name);
1518 if(strcmp(s,zero)==0) {
1519 emitpcode(POC_CLRF,popGet(aop,offset));
1521 } else if(strcmp(s,"W")==0) {
1522 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1523 pcop->type = PO_GPR_REGISTER;
1525 PCOR(pcop)->rIdx = -1;
1526 PCOR(pcop)->r = NULL;
1528 DEBUGpic14_emitcode(";","%d",__LINE__);
1529 pcop->name = Safe_strdup(s);
1530 emitpcode(POC_MOVFW,pcop);
1531 emitpcode(POC_MOVWF,popGet(aop,offset));
1532 } else if(strcmp(s,one)==0) {
1533 emitpcode(POC_CLRF,popGet(aop,offset));
1534 emitpcode(POC_INCF,popGet(aop,offset));
1536 emitpcode(POC_MOVWF,popGet(aop,offset));
1544 if (aop->type == AOP_DPTR2)
1550 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1551 "aopPut writting to code space");
1555 while (offset > aop->coff) {
1557 pic14_emitcode ("inc","dptr");
1560 while (offset < aop->coff) {
1562 pic14_emitcode("lcall","__decdptr");
1567 /* if not in accumulater */
1570 pic14_emitcode ("movx","@dptr,a");
1572 if (aop->type == AOP_DPTR2)
1580 while (offset > aop->coff) {
1582 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1584 while (offset < aop->coff) {
1586 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1592 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1597 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1599 if (strcmp(s,"r0") == 0 ||
1600 strcmp(s,"r1") == 0 ||
1601 strcmp(s,"r2") == 0 ||
1602 strcmp(s,"r3") == 0 ||
1603 strcmp(s,"r4") == 0 ||
1604 strcmp(s,"r5") == 0 ||
1605 strcmp(s,"r6") == 0 ||
1606 strcmp(s,"r7") == 0 ) {
1608 sprintf(buffer,"a%s",s);
1609 pic14_emitcode("mov","@%s,%s",
1610 aop->aopu.aop_ptr->name,buffer);
1612 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1617 if (strcmp(s,"a") == 0)
1618 pic14_emitcode("push","acc");
1620 pic14_emitcode("push","%s",s);
1625 /* if bit variable */
1626 if (!aop->aopu.aop_dir) {
1627 pic14_emitcode("clr","a");
1628 pic14_emitcode("rlc","a");
1631 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1634 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1637 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1639 lbl = newiTempLabel(NULL);
1641 if (strcmp(s,"a")) {
1644 pic14_emitcode("clr","c");
1645 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1646 pic14_emitcode("cpl","c");
1647 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1648 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1655 if (strcmp(aop->aopu.aop_str[offset],s))
1656 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1661 if (!offset && (strcmp(s,"acc") == 0))
1664 if (strcmp(aop->aopu.aop_str[offset],s))
1665 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1669 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1670 "aopPut got unsupported aop->type");
1676 /*-----------------------------------------------------------------*/
1677 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1678 /*-----------------------------------------------------------------*/
1679 void mov2w (asmop *aop, int offset)
1685 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1687 if ( aop->type == AOP_PCODE ||
1688 aop->type == AOP_LIT ||
1689 aop->type == AOP_IMMD )
1690 emitpcode(POC_MOVLW,popGet(aop,offset));
1692 emitpcode(POC_MOVFW,popGet(aop,offset));
1696 /*-----------------------------------------------------------------*/
1697 /* reAdjustPreg - points a register back to where it should */
1698 /*-----------------------------------------------------------------*/
1699 static void reAdjustPreg (asmop *aop)
1703 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1705 if ((size = aop->size) <= 1)
1708 switch (aop->type) {
1712 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1716 if (aop->type == AOP_DPTR2)
1722 pic14_emitcode("lcall","__decdptr");
1725 if (aop->type == AOP_DPTR2)
1737 /*-----------------------------------------------------------------*/
1738 /* opIsGptr: returns non-zero if the passed operand is */
1739 /* a generic pointer type. */
1740 /*-----------------------------------------------------------------*/
1741 static int opIsGptr(operand *op)
1743 sym_link *type = operandType(op);
1745 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1746 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1754 /*-----------------------------------------------------------------*/
1755 /* pic14_getDataSize - get the operand data size */
1756 /*-----------------------------------------------------------------*/
1757 int pic14_getDataSize(operand *op)
1759 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1762 return AOP_SIZE(op);
1764 // tsd- in the pic port, the genptr size is 1, so this code here
1765 // fails. ( in the 8051 port, the size was 4).
1768 size = AOP_SIZE(op);
1769 if (size == GPTRSIZE)
1771 sym_link *type = operandType(op);
1772 if (IS_GENPTR(type))
1774 /* generic pointer; arithmetic operations
1775 * should ignore the high byte (pointer type).
1778 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1785 /*-----------------------------------------------------------------*/
1786 /* pic14_outAcc - output Acc */
1787 /*-----------------------------------------------------------------*/
1788 void pic14_outAcc(operand *result)
1791 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1792 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1795 size = pic14_getDataSize(result);
1797 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1800 /* unsigned or positive */
1802 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1807 /*-----------------------------------------------------------------*/
1808 /* pic14_outBitC - output a bit C */
1809 /*-----------------------------------------------------------------*/
1810 void pic14_outBitC(operand *result)
1813 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1814 /* if the result is bit */
1815 if (AOP_TYPE(result) == AOP_CRY)
1816 aopPut(AOP(result),"c",0);
1818 pic14_emitcode("clr","a ; %d", __LINE__);
1819 pic14_emitcode("rlc","a");
1820 pic14_outAcc(result);
1824 /*-----------------------------------------------------------------*/
1825 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1826 /*-----------------------------------------------------------------*/
1827 void pic14_toBoolean(operand *oper)
1829 int size = AOP_SIZE(oper) - 1;
1832 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1834 if ( AOP_TYPE(oper) != AOP_ACC) {
1835 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1838 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1843 /*-----------------------------------------------------------------*/
1844 /* genNot - generate code for ! operation */
1845 /*-----------------------------------------------------------------*/
1846 static void genNot (iCode *ic)
1851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1852 /* assign asmOps to operand & result */
1853 aopOp (IC_LEFT(ic),ic,FALSE);
1854 aopOp (IC_RESULT(ic),ic,TRUE);
1856 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1857 /* if in bit space then a special case */
1858 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1859 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1860 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1861 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1863 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1864 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1865 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1870 size = AOP_SIZE(IC_LEFT(ic));
1872 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1873 emitpcode(POC_ANDLW,popGetLit(1));
1874 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1877 pic14_toBoolean(IC_LEFT(ic));
1879 tlbl = newiTempLabel(NULL);
1880 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1881 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1882 pic14_outBitC(IC_RESULT(ic));
1885 /* release the aops */
1886 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1887 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1891 /*-----------------------------------------------------------------*/
1892 /* genCpl - generate code for complement */
1893 /*-----------------------------------------------------------------*/
1894 static void genCpl (iCode *ic)
1896 operand *left, *result;
1900 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1901 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1902 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1904 /* if both are in bit space then
1906 if (AOP_TYPE(result) == AOP_CRY &&
1907 AOP_TYPE(left) == AOP_CRY ) {
1909 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1910 pic14_emitcode("cpl","c");
1911 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1915 size = AOP_SIZE(result);
1918 if(AOP_TYPE(left) == AOP_ACC)
1919 emitpcode(POC_XORLW, popGetLit(0xff));
1921 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1923 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1929 /* release the aops */
1930 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1931 freeAsmop(result,NULL,ic,TRUE);
1934 /*-----------------------------------------------------------------*/
1935 /* genUminusFloat - unary minus for floating points */
1936 /*-----------------------------------------------------------------*/
1937 static void genUminusFloat(operand *op,operand *result)
1939 int size ,offset =0 ;
1942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1943 /* for this we just need to flip the
1944 first it then copy the rest in place */
1945 size = AOP_SIZE(op) - 1;
1946 l = aopGet(AOP(op),3,FALSE,FALSE);
1950 pic14_emitcode("cpl","acc.7");
1951 aopPut(AOP(result),"a",3);
1955 aopGet(AOP(op),offset,FALSE,FALSE),
1961 /*-----------------------------------------------------------------*/
1962 /* genUminus - unary minus code generation */
1963 /*-----------------------------------------------------------------*/
1964 static void genUminus (iCode *ic)
1967 sym_link *optype, *rtype;
1970 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1972 aopOp(IC_LEFT(ic),ic,FALSE);
1973 aopOp(IC_RESULT(ic),ic,TRUE);
1975 /* if both in bit space then special
1977 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1978 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1980 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1981 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1982 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1987 optype = operandType(IC_LEFT(ic));
1988 rtype = operandType(IC_RESULT(ic));
1990 /* if float then do float stuff */
1991 if (IS_FLOAT(optype)) {
1992 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1996 /* otherwise subtract from zero by taking the 2's complement */
1997 size = AOP_SIZE(IC_LEFT(ic));
1999 for(i=0; i<size; i++) {
2000 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2001 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2003 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2004 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2008 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2009 for(i=1; i<size; i++) {
2011 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2015 /* release the aops */
2016 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2017 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2020 /*-----------------------------------------------------------------*/
2021 /* saveRegisters - will look for a call and save the registers */
2022 /*-----------------------------------------------------------------*/
2023 static void saveRegisters(iCode *lic)
2030 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2032 for (ic = lic ; ic ; ic = ic->next)
2033 if (ic->op == CALL || ic->op == PCALL)
2037 fprintf(stderr,"found parameter push with no function call\n");
2041 /* if the registers have been saved already then
2043 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2046 /* find the registers in use at this time
2047 and push them away to safety */
2048 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2052 if (options.useXstack) {
2053 if (bitVectBitValue(rsave,R0_IDX))
2054 pic14_emitcode("mov","b,r0");
2055 pic14_emitcode("mov","r0,%s",spname);
2056 for (i = 0 ; i < pic14_nRegs ; i++) {
2057 if (bitVectBitValue(rsave,i)) {
2059 pic14_emitcode("mov","a,b");
2061 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2062 pic14_emitcode("movx","@r0,a");
2063 pic14_emitcode("inc","r0");
2066 pic14_emitcode("mov","%s,r0",spname);
2067 if (bitVectBitValue(rsave,R0_IDX))
2068 pic14_emitcode("mov","r0,b");
2070 //for (i = 0 ; i < pic14_nRegs ; i++) {
2071 // if (bitVectBitValue(rsave,i))
2072 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2075 dtype = operandType(IC_LEFT(ic));
2076 if (currFunc && dtype &&
2077 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2078 IFFUNC_ISISR(currFunc->type) &&
2081 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2084 /*-----------------------------------------------------------------*/
2085 /* unsaveRegisters - pop the pushed registers */
2086 /*-----------------------------------------------------------------*/
2087 static void unsaveRegisters (iCode *ic)
2092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2093 /* find the registers in use at this time
2094 and push them away to safety */
2095 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2098 if (options.useXstack) {
2099 pic14_emitcode("mov","r0,%s",spname);
2100 for (i = pic14_nRegs ; i >= 0 ; i--) {
2101 if (bitVectBitValue(rsave,i)) {
2102 pic14_emitcode("dec","r0");
2103 pic14_emitcode("movx","a,@r0");
2105 pic14_emitcode("mov","b,a");
2107 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2111 pic14_emitcode("mov","%s,r0",spname);
2112 if (bitVectBitValue(rsave,R0_IDX))
2113 pic14_emitcode("mov","r0,b");
2115 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2116 // if (bitVectBitValue(rsave,i))
2117 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2123 /*-----------------------------------------------------------------*/
2125 /*-----------------------------------------------------------------*/
2126 static void pushSide(operand * oper, int size)
2130 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2132 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2133 if (AOP_TYPE(oper) != AOP_REG &&
2134 AOP_TYPE(oper) != AOP_DIR &&
2136 pic14_emitcode("mov","a,%s",l);
2137 pic14_emitcode("push","acc");
2139 pic14_emitcode("push","%s",l);
2144 /*-----------------------------------------------------------------*/
2145 /* assignResultValue - */
2146 /*-----------------------------------------------------------------*/
2147 static void assignResultValue(operand * oper)
2149 int size = AOP_SIZE(oper);
2151 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2153 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2155 if(!GpsuedoStkPtr) {
2156 /* The last byte in the assignment is in W */
2158 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2160 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2164 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2166 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2171 /*-----------------------------------------------------------------*/
2172 /* genIpush - genrate code for pushing this gets a little complex */
2173 /*-----------------------------------------------------------------*/
2174 static void genIpush (iCode *ic)
2177 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2179 int size, offset = 0 ;
2183 /* if this is not a parm push : ie. it is spill push
2184 and spill push is always done on the local stack */
2185 if (!ic->parmPush) {
2187 /* and the item is spilt then do nothing */
2188 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2191 aopOp(IC_LEFT(ic),ic,FALSE);
2192 size = AOP_SIZE(IC_LEFT(ic));
2193 /* push it on the stack */
2195 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2200 pic14_emitcode("push","%s",l);
2205 /* this is a paramter push: in this case we call
2206 the routine to find the call and save those
2207 registers that need to be saved */
2210 /* then do the push */
2211 aopOp(IC_LEFT(ic),ic,FALSE);
2214 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2215 size = AOP_SIZE(IC_LEFT(ic));
2218 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2219 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2220 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2222 pic14_emitcode("mov","a,%s",l);
2223 pic14_emitcode("push","acc");
2225 pic14_emitcode("push","%s",l);
2228 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2232 /*-----------------------------------------------------------------*/
2233 /* genIpop - recover the registers: can happen only for spilling */
2234 /*-----------------------------------------------------------------*/
2235 static void genIpop (iCode *ic)
2237 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2242 /* if the temp was not pushed then */
2243 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2246 aopOp(IC_LEFT(ic),ic,FALSE);
2247 size = AOP_SIZE(IC_LEFT(ic));
2250 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2253 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2257 /*-----------------------------------------------------------------*/
2258 /* unsaverbank - restores the resgister bank from stack */
2259 /*-----------------------------------------------------------------*/
2260 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2262 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2268 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2270 if (options.useXstack) {
2272 r = getFreePtr(ic,&aop,FALSE);
2275 pic14_emitcode("mov","%s,_spx",r->name);
2276 pic14_emitcode("movx","a,@%s",r->name);
2277 pic14_emitcode("mov","psw,a");
2278 pic14_emitcode("dec","%s",r->name);
2281 pic14_emitcode ("pop","psw");
2284 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2285 if (options.useXstack) {
2286 pic14_emitcode("movx","a,@%s",r->name);
2287 //pic14_emitcode("mov","(%s+%d),a",
2288 // regspic14[i].base,8*bank+regspic14[i].offset);
2289 pic14_emitcode("dec","%s",r->name);
2292 pic14_emitcode("pop",""); //"(%s+%d)",
2293 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2296 if (options.useXstack) {
2298 pic14_emitcode("mov","_spx,%s",r->name);
2299 freeAsmop(NULL,aop,ic,TRUE);
2305 /*-----------------------------------------------------------------*/
2306 /* saverbank - saves an entire register bank on the stack */
2307 /*-----------------------------------------------------------------*/
2308 static void saverbank (int bank, iCode *ic, bool pushPsw)
2310 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2317 if (options.useXstack) {
2320 r = getFreePtr(ic,&aop,FALSE);
2321 pic14_emitcode("mov","%s,_spx",r->name);
2325 for (i = 0 ; i < pic14_nRegs ;i++) {
2326 if (options.useXstack) {
2327 pic14_emitcode("inc","%s",r->name);
2328 //pic14_emitcode("mov","a,(%s+%d)",
2329 // regspic14[i].base,8*bank+regspic14[i].offset);
2330 pic14_emitcode("movx","@%s,a",r->name);
2332 pic14_emitcode("push","");// "(%s+%d)",
2333 //regspic14[i].base,8*bank+regspic14[i].offset);
2337 if (options.useXstack) {
2338 pic14_emitcode("mov","a,psw");
2339 pic14_emitcode("movx","@%s,a",r->name);
2340 pic14_emitcode("inc","%s",r->name);
2341 pic14_emitcode("mov","_spx,%s",r->name);
2342 freeAsmop (NULL,aop,ic,TRUE);
2345 pic14_emitcode("push","psw");
2347 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2353 /*-----------------------------------------------------------------*/
2354 /* genCall - generates a call statement */
2355 /*-----------------------------------------------------------------*/
2356 static void genCall (iCode *ic)
2360 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2362 /* if caller saves & we have not saved then */
2366 /* if we are calling a function that is not using
2367 the same register bank then we need to save the
2368 destination registers on the stack */
2369 dtype = operandType(IC_LEFT(ic));
2370 if (currFunc && dtype &&
2371 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2372 IFFUNC_ISISR(currFunc->type) &&
2375 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2377 /* if send set is not empty the assign */
2380 /* For the Pic port, there is no data stack.
2381 * So parameters passed to functions are stored
2382 * in registers. (The pCode optimizer will get
2383 * rid of most of these :).
2385 int psuedoStkPtr=-1;
2386 int firstTimeThruLoop = 1;
2388 _G.sendSet = reverseSet(_G.sendSet);
2390 /* First figure how many parameters are getting passed */
2391 for (sic = setFirstItem(_G.sendSet) ; sic ;
2392 sic = setNextItem(_G.sendSet)) {
2394 aopOp(IC_LEFT(sic),sic,FALSE);
2395 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2396 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2399 for (sic = setFirstItem(_G.sendSet) ; sic ;
2400 sic = setNextItem(_G.sendSet)) {
2401 int size, offset = 0;
2403 aopOp(IC_LEFT(sic),sic,FALSE);
2404 size = AOP_SIZE(IC_LEFT(sic));
2407 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2408 AopType(AOP_TYPE(IC_LEFT(sic))));
2410 if(!firstTimeThruLoop) {
2411 /* If this is not the first time we've been through the loop
2412 * then we need to save the parameter in a temporary
2413 * register. The last byte of the last parameter is
2415 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2418 firstTimeThruLoop=0;
2420 //if (strcmp(l,fReturn[offset])) {
2421 mov2w (AOP(IC_LEFT(sic)), offset);
2423 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2424 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2425 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2427 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2432 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2437 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2438 OP_SYMBOL(IC_LEFT(ic))->rname :
2439 OP_SYMBOL(IC_LEFT(ic))->name));
2442 /* if we need assign a result value */
2443 if ((IS_ITEMP(IC_RESULT(ic)) &&
2444 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2445 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2446 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2449 aopOp(IC_RESULT(ic),ic,FALSE);
2452 assignResultValue(IC_RESULT(ic));
2454 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2455 AopType(AOP_TYPE(IC_RESULT(ic))));
2457 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2460 /* adjust the stack for parameters if
2462 if (ic->parmBytes) {
2464 if (ic->parmBytes > 3) {
2465 pic14_emitcode("mov","a,%s",spname);
2466 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2467 pic14_emitcode("mov","%s,a",spname);
2469 for ( i = 0 ; i < ic->parmBytes ;i++)
2470 pic14_emitcode("dec","%s",spname);
2474 /* if register bank was saved then pop them */
2476 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2478 /* if we hade saved some registers then unsave them */
2479 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2480 unsaveRegisters (ic);
2485 /*-----------------------------------------------------------------*/
2486 /* genPcall - generates a call by pointer statement */
2487 /*-----------------------------------------------------------------*/
2488 static void genPcall (iCode *ic)
2491 symbol *albl = newiTempLabel(NULL);
2492 symbol *blbl = newiTempLabel(NULL);
2496 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2497 /* if caller saves & we have not saved then */
2501 /* if we are calling a function that is not using
2502 the same register bank then we need to save the
2503 destination registers on the stack */
2504 dtype = operandType(IC_LEFT(ic));
2505 if (currFunc && dtype &&
2506 IFFUNC_ISISR(currFunc->type) &&
2507 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2508 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2511 aopOp(left,ic,FALSE);
2512 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2514 pushSide(IC_LEFT(ic), FPTRSIZE);
2516 /* if send set is not empty, assign parameters */
2519 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2520 /* no way to pass args - W always gets used to make the call */
2522 /* first idea - factor out a common helper function and call it.
2523 But don't know how to get it generated only once in its own block
2525 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2528 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2529 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2530 buffer = Safe_calloc(1,strlen(rname)+16);
2531 sprintf(buffer, "%s_goto_helper", rname);
2532 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2536 emitpcode(POC_CALL,popGetLabel(albl->key));
2537 emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
2538 emitpcode(POC_GOTO,popGetLabel(blbl->key));
2539 emitpLabel(albl->key);
2541 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2543 emitpcode(poc,popGet(AOP(left),1));
2544 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2545 emitpcode(poc,popGet(AOP(left),0));
2546 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2548 emitpLabel(blbl->key);
2550 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2552 /* if we need to assign a result value */
2553 if ((IS_ITEMP(IC_RESULT(ic)) &&
2554 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2555 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2556 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2559 aopOp(IC_RESULT(ic),ic,FALSE);
2562 assignResultValue(IC_RESULT(ic));
2564 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2567 /* if register bank was saved then unsave them */
2568 if (currFunc && dtype &&
2569 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2570 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2572 /* if we hade saved some registers then
2575 unsaveRegisters (ic);
2579 /*-----------------------------------------------------------------*/
2580 /* resultRemat - result is rematerializable */
2581 /*-----------------------------------------------------------------*/
2582 static int resultRemat (iCode *ic)
2584 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2585 if (SKIP_IC(ic) || ic->op == IFX)
2588 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2589 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2590 if (sym->remat && !POINTER_SET(ic))
2597 #if defined(__BORLANDC__) || defined(_MSC_VER)
2598 #define STRCASECMP stricmp
2600 #define STRCASECMP strcasecmp
2604 /*-----------------------------------------------------------------*/
2605 /* inExcludeList - return 1 if the string is in exclude Reg list */
2606 /*-----------------------------------------------------------------*/
2607 static bool inExcludeList(char *s)
2609 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2612 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2613 if (options.excludeRegs[i] &&
2614 STRCASECMP(options.excludeRegs[i],"none") == 0)
2617 for ( i = 0 ; options.excludeRegs[i]; i++) {
2618 if (options.excludeRegs[i] &&
2619 STRCASECMP(s,options.excludeRegs[i]) == 0)
2626 /*-----------------------------------------------------------------*/
2627 /* genFunction - generated code for function entry */
2628 /*-----------------------------------------------------------------*/
2629 static void genFunction (iCode *ic)
2634 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2636 labelOffset += (max_key+4);
2640 /* create the function header */
2641 pic14_emitcode(";","-----------------------------------------");
2642 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2643 pic14_emitcode(";","-----------------------------------------");
2645 pic14_emitcode("","%s:",sym->rname);
2646 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2648 ftype = operandType(IC_LEFT(ic));
2650 /* if critical function then turn interrupts off */
2651 if (IFFUNC_ISCRITICAL(ftype))
2652 pic14_emitcode("clr","ea");
2654 /* here we need to generate the equates for the
2655 register bank if required */
2657 if (FUNC_REGBANK(ftype) != rbank) {
2660 rbank = FUNC_REGBANK(ftype);
2661 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2662 if (strcmp(regspic14[i].base,"0") == 0)
2663 pic14_emitcode("","%s = 0x%02x",
2665 8*rbank+regspic14[i].offset);
2667 pic14_emitcode ("","%s = %s + 0x%02x",
2670 8*rbank+regspic14[i].offset);
2675 /* if this is an interrupt service routine */
2676 if (IFFUNC_ISISR(sym->type)) {
2677 /* already done in pic14createInterruptVect() - delete me
2678 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2679 emitpcodeNULLop(POC_NOP);
2680 emitpcodeNULLop(POC_NOP);
2681 emitpcodeNULLop(POC_NOP);
2683 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2684 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2685 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2686 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2687 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2688 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2689 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* durring an interrupt PCLATH must be cleared before a goto or call statement */
2691 pBlockConvert2ISR(pb);
2693 if (!inExcludeList("acc"))
2694 pic14_emitcode ("push","acc");
2695 if (!inExcludeList("b"))
2696 pic14_emitcode ("push","b");
2697 if (!inExcludeList("dpl"))
2698 pic14_emitcode ("push","dpl");
2699 if (!inExcludeList("dph"))
2700 pic14_emitcode ("push","dph");
2701 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2703 pic14_emitcode ("push", "dpx");
2704 /* Make sure we're using standard DPTR */
2705 pic14_emitcode ("push", "dps");
2706 pic14_emitcode ("mov", "dps, #0x00");
2707 if (options.stack10bit)
2709 /* This ISR could conceivably use DPTR2. Better save it. */
2710 pic14_emitcode ("push", "dpl1");
2711 pic14_emitcode ("push", "dph1");
2712 pic14_emitcode ("push", "dpx1");
2715 /* if this isr has no bank i.e. is going to
2716 run with bank 0 , then we need to save more
2718 if (!FUNC_REGBANK(sym->type)) {
2720 /* if this function does not call any other
2721 function then we can be economical and
2722 save only those registers that are used */
2723 if (! IFFUNC_HASFCALL(sym->type)) {
2726 /* if any registers used */
2727 if (sym->regsUsed) {
2728 /* save the registers used */
2729 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2730 if (bitVectBitValue(sym->regsUsed,i) ||
2731 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2732 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2737 /* this function has a function call cannot
2738 determines register usage so we will have the
2740 saverbank(0,ic,FALSE);
2745 /* if callee-save to be used for this function
2746 then save the registers being used in this function */
2747 if (IFFUNC_CALLEESAVES(sym->type)) {
2750 /* if any registers used */
2751 if (sym->regsUsed) {
2752 /* save the registers used */
2753 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2754 if (bitVectBitValue(sym->regsUsed,i) ||
2755 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2756 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2764 /* set the register bank to the desired value */
2765 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2766 pic14_emitcode("push","psw");
2767 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2770 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2772 if (options.useXstack) {
2773 pic14_emitcode("mov","r0,%s",spname);
2774 pic14_emitcode("mov","a,_bp");
2775 pic14_emitcode("movx","@r0,a");
2776 pic14_emitcode("inc","%s",spname);
2780 /* set up the stack */
2781 pic14_emitcode ("push","_bp"); /* save the callers stack */
2783 pic14_emitcode ("mov","_bp,%s",spname);
2786 /* adjust the stack for the function */
2791 werror(W_STACK_OVERFLOW,sym->name);
2793 if (i > 3 && sym->recvSize < 4) {
2795 pic14_emitcode ("mov","a,sp");
2796 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2797 pic14_emitcode ("mov","sp,a");
2802 pic14_emitcode("inc","sp");
2807 pic14_emitcode ("mov","a,_spx");
2808 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2809 pic14_emitcode ("mov","_spx,a");
2814 /*-----------------------------------------------------------------*/
2815 /* genEndFunction - generates epilogue for functions */
2816 /*-----------------------------------------------------------------*/
2817 static void genEndFunction (iCode *ic)
2819 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2821 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2823 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2825 pic14_emitcode ("mov","%s,_bp",spname);
2828 /* if use external stack but some variables were
2829 added to the local stack then decrement the
2831 if (options.useXstack && sym->stack) {
2832 pic14_emitcode("mov","a,sp");
2833 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2834 pic14_emitcode("mov","sp,a");
2838 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2839 if (options.useXstack) {
2840 pic14_emitcode("mov","r0,%s",spname);
2841 pic14_emitcode("movx","a,@r0");
2842 pic14_emitcode("mov","_bp,a");
2843 pic14_emitcode("dec","%s",spname);
2847 pic14_emitcode ("pop","_bp");
2851 /* restore the register bank */
2852 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2853 pic14_emitcode ("pop","psw");
2855 if (IFFUNC_ISISR(sym->type)) {
2857 /* now we need to restore the registers */
2858 /* if this isr has no bank i.e. is going to
2859 run with bank 0 , then we need to save more
2861 if (!FUNC_REGBANK(sym->type)) {
2863 /* if this function does not call any other
2864 function then we can be economical and
2865 save only those registers that are used */
2866 if (! IFFUNC_HASFCALL(sym->type)) {
2869 /* if any registers used */
2870 if (sym->regsUsed) {
2871 /* save the registers used */
2872 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2873 if (bitVectBitValue(sym->regsUsed,i) ||
2874 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2875 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2880 /* this function has a function call cannot
2881 determines register usage so we will have the
2883 unsaverbank(0,ic,FALSE);
2887 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2889 if (options.stack10bit)
2891 pic14_emitcode ("pop", "dpx1");
2892 pic14_emitcode ("pop", "dph1");
2893 pic14_emitcode ("pop", "dpl1");
2895 pic14_emitcode ("pop", "dps");
2896 pic14_emitcode ("pop", "dpx");
2898 if (!inExcludeList("dph"))
2899 pic14_emitcode ("pop","dph");
2900 if (!inExcludeList("dpl"))
2901 pic14_emitcode ("pop","dpl");
2902 if (!inExcludeList("b"))
2903 pic14_emitcode ("pop","b");
2904 if (!inExcludeList("acc"))
2905 pic14_emitcode ("pop","acc");
2907 if (IFFUNC_ISCRITICAL(sym->type))
2908 pic14_emitcode("setb","ea");
2911 /* if debug then send end of function */
2912 /* if (options.debug && currFunc) { */
2915 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2916 FileBaseName(ic->filename),currFunc->lastLine,
2917 ic->level,ic->block);
2918 if (IS_STATIC(currFunc->etype))
2919 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2921 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2925 pic14_emitcode ("reti","");
2926 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2927 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2928 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2929 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2930 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2931 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2932 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2933 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2934 emitpcodeNULLop(POC_RETFIE);
2937 if (IFFUNC_ISCRITICAL(sym->type))
2938 pic14_emitcode("setb","ea");
2940 if (IFFUNC_CALLEESAVES(sym->type)) {
2943 /* if any registers used */
2944 if (sym->regsUsed) {
2945 /* save the registers used */
2946 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2947 if (bitVectBitValue(sym->regsUsed,i) ||
2948 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2949 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2955 /* if debug then send end of function */
2958 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2959 FileBaseName(ic->filename),currFunc->lastLine,
2960 ic->level,ic->block);
2961 if (IS_STATIC(currFunc->etype))
2962 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2964 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2968 pic14_emitcode ("return","");
2969 emitpcodeNULLop(POC_RETURN);
2971 /* Mark the end of a function */
2972 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2977 /*-----------------------------------------------------------------*/
2978 /* genRet - generate code for return statement */
2979 /*-----------------------------------------------------------------*/
2980 static void genRet (iCode *ic)
2982 int size,offset = 0 , pushed = 0;
2984 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2985 /* if we have no return value then
2986 just generate the "ret" */
2990 /* we have something to return then
2991 move the return value into place */
2992 aopOp(IC_LEFT(ic),ic,FALSE);
2993 size = AOP_SIZE(IC_LEFT(ic));
2997 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2999 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3001 pic14_emitcode("push","%s",l);
3004 l = aopGet(AOP(IC_LEFT(ic)),offset,
3006 if (strcmp(fReturn[offset],l)) {
3007 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
3008 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3009 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3010 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3011 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3013 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3016 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3026 if (strcmp(fReturn[pushed],"a"))
3027 pic14_emitcode("pop",fReturn[pushed]);
3029 pic14_emitcode("pop","acc");
3032 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3035 /* generate a jump to the return label
3036 if the next is not the return statement */
3037 if (!(ic->next && ic->next->op == LABEL &&
3038 IC_LABEL(ic->next) == returnLabel)) {
3040 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3041 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3046 /*-----------------------------------------------------------------*/
3047 /* genLabel - generates a label */
3048 /*-----------------------------------------------------------------*/
3049 static void genLabel (iCode *ic)
3051 /* special case never generate */
3052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3053 if (IC_LABEL(ic) == entryLabel)
3056 emitpLabel(IC_LABEL(ic)->key);
3057 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3060 /*-----------------------------------------------------------------*/
3061 /* genGoto - generates a goto */
3062 /*-----------------------------------------------------------------*/
3064 static void genGoto (iCode *ic)
3066 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3067 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3071 /*-----------------------------------------------------------------*/
3072 /* genMultbits :- multiplication of bits */
3073 /*-----------------------------------------------------------------*/
3074 static void genMultbits (operand *left,
3078 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3080 if(!pic14_sameRegs(AOP(result),AOP(right)))
3081 emitpcode(POC_BSF, popGet(AOP(result),0));
3083 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3084 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3085 emitpcode(POC_BCF, popGet(AOP(result),0));
3090 /*-----------------------------------------------------------------*/
3091 /* genMultOneByte : 8 bit multiplication & division */
3092 /*-----------------------------------------------------------------*/
3093 static void genMultOneByte (operand *left,
3097 sym_link *opetype = operandType(result);
3102 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3103 DEBUGpic14_AopType(__LINE__,left,right,result);
3104 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3106 /* (if two literals, the value is computed before) */
3107 /* if one literal, literal on the right */
3108 if (AOP_TYPE(left) == AOP_LIT){
3114 size = AOP_SIZE(result);
3117 if (AOP_TYPE(right) == AOP_LIT){
3118 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3119 aopGet(AOP(right),0,FALSE,FALSE),
3120 aopGet(AOP(left),0,FALSE,FALSE),
3121 aopGet(AOP(result),0,FALSE,FALSE));
3122 pic14_emitcode("call","genMultLit");
3124 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3125 aopGet(AOP(right),0,FALSE,FALSE),
3126 aopGet(AOP(left),0,FALSE,FALSE),
3127 aopGet(AOP(result),0,FALSE,FALSE));
3128 pic14_emitcode("call","genMult8X8_8");
3131 genMult8X8_8 (left, right,result);
3134 /* signed or unsigned */
3135 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3136 //l = aopGet(AOP(left),0,FALSE,FALSE);
3138 //pic14_emitcode("mul","ab");
3139 /* if result size = 1, mul signed = mul unsigned */
3140 //aopPut(AOP(result),"a",0);
3142 } else { // (size > 1)
3144 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3145 aopGet(AOP(right),0,FALSE,FALSE),
3146 aopGet(AOP(left),0,FALSE,FALSE),
3147 aopGet(AOP(result),0,FALSE,FALSE));
3149 if (SPEC_USIGN(opetype)){
3150 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3151 genUMult8X8_16 (left, right, result, NULL);
3154 /* for filling the MSBs */
3155 emitpcode(POC_CLRF, popGet(AOP(result),2));
3156 emitpcode(POC_CLRF, popGet(AOP(result),3));
3160 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3162 pic14_emitcode("mov","a,b");
3164 /* adjust the MSB if left or right neg */
3166 /* if one literal */
3167 if (AOP_TYPE(right) == AOP_LIT){
3168 pic14_emitcode("multiply ","right is a lit");
3169 /* AND literal negative */
3170 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3171 /* adjust MSB (c==0 after mul) */
3172 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3176 genSMult8X8_16 (left, right, result, NULL);
3180 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3182 pic14_emitcode("rlc","a");
3183 pic14_emitcode("subb","a,acc");
3191 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3192 //aopPut(AOP(result),"a",offset++);
3196 /*-----------------------------------------------------------------*/
3197 /* genMult - generates code for multiplication */
3198 /*-----------------------------------------------------------------*/
3199 static void genMult (iCode *ic)
3201 operand *left = IC_LEFT(ic);
3202 operand *right = IC_RIGHT(ic);
3203 operand *result= IC_RESULT(ic);
3205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3206 /* assign the amsops */
3207 aopOp (left,ic,FALSE);
3208 aopOp (right,ic,FALSE);
3209 aopOp (result,ic,TRUE);
3211 DEBUGpic14_AopType(__LINE__,left,right,result);
3213 /* special cases first */
3215 if (AOP_TYPE(left) == AOP_CRY &&
3216 AOP_TYPE(right)== AOP_CRY) {
3217 genMultbits(left,right,result);
3221 /* if both are of size == 1 */
3222 if (AOP_SIZE(left) == 1 &&
3223 AOP_SIZE(right) == 1 ) {
3224 genMultOneByte(left,right,result);
3228 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3230 /* should have been converted to function call */
3234 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3235 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3236 freeAsmop(result,NULL,ic,TRUE);
3239 /*-----------------------------------------------------------------*/
3240 /* genDivbits :- division of bits */
3241 /*-----------------------------------------------------------------*/
3242 static void genDivbits (operand *left,
3249 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3250 /* the result must be bit */
3251 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3252 l = aopGet(AOP(left),0,FALSE,FALSE);
3256 pic14_emitcode("div","ab");
3257 pic14_emitcode("rrc","a");
3258 aopPut(AOP(result),"c",0);
3261 /*-----------------------------------------------------------------*/
3262 /* genDivOneByte : 8 bit division */
3263 /*-----------------------------------------------------------------*/
3264 static void genDivOneByte (operand *left,
3268 sym_link *opetype = operandType(result);
3273 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3274 size = AOP_SIZE(result) - 1;
3276 /* signed or unsigned */
3277 if (SPEC_USIGN(opetype)) {
3278 /* unsigned is easy */
3279 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3280 l = aopGet(AOP(left),0,FALSE,FALSE);
3282 pic14_emitcode("div","ab");
3283 aopPut(AOP(result),"a",0);
3285 aopPut(AOP(result),zero,offset++);
3289 /* signed is a little bit more difficult */
3291 /* save the signs of the operands */
3292 l = aopGet(AOP(left),0,FALSE,FALSE);
3294 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3295 pic14_emitcode("push","acc"); /* save it on the stack */
3297 /* now sign adjust for both left & right */
3298 l = aopGet(AOP(right),0,FALSE,FALSE);
3300 lbl = newiTempLabel(NULL);
3301 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3302 pic14_emitcode("cpl","a");
3303 pic14_emitcode("inc","a");
3304 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3305 pic14_emitcode("mov","b,a");
3307 /* sign adjust left side */
3308 l = aopGet(AOP(left),0,FALSE,FALSE);
3311 lbl = newiTempLabel(NULL);
3312 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3313 pic14_emitcode("cpl","a");
3314 pic14_emitcode("inc","a");
3315 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3317 /* now the division */
3318 pic14_emitcode("div","ab");
3319 /* we are interested in the lower order
3321 pic14_emitcode("mov","b,a");
3322 lbl = newiTempLabel(NULL);
3323 pic14_emitcode("pop","acc");
3324 /* if there was an over flow we don't
3325 adjust the sign of the result */
3326 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3327 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3329 pic14_emitcode("clr","a");
3330 pic14_emitcode("subb","a,b");
3331 pic14_emitcode("mov","b,a");
3332 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3334 /* now we are done */
3335 aopPut(AOP(result),"b",0);
3337 pic14_emitcode("mov","c,b.7");
3338 pic14_emitcode("subb","a,acc");
3341 aopPut(AOP(result),"a",offset++);
3345 /*-----------------------------------------------------------------*/
3346 /* genDiv - generates code for division */
3347 /*-----------------------------------------------------------------*/
3348 static void genDiv (iCode *ic)
3350 operand *left = IC_LEFT(ic);
3351 operand *right = IC_RIGHT(ic);
3352 operand *result= IC_RESULT(ic);
3354 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3355 /* assign the amsops */
3356 aopOp (left,ic,FALSE);
3357 aopOp (right,ic,FALSE);
3358 aopOp (result,ic,TRUE);
3360 /* special cases first */
3362 if (AOP_TYPE(left) == AOP_CRY &&
3363 AOP_TYPE(right)== AOP_CRY) {
3364 genDivbits(left,right,result);
3368 /* if both are of size == 1 */
3369 if (AOP_SIZE(left) == 1 &&
3370 AOP_SIZE(right) == 1 ) {
3371 genDivOneByte(left,right,result);
3375 /* should have been converted to function call */
3378 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3379 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3380 freeAsmop(result,NULL,ic,TRUE);
3383 /*-----------------------------------------------------------------*/
3384 /* genModbits :- modulus of bits */
3385 /*-----------------------------------------------------------------*/
3386 static void genModbits (operand *left,
3393 /* the result must be bit */
3394 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3395 l = aopGet(AOP(left),0,FALSE,FALSE);
3399 pic14_emitcode("div","ab");
3400 pic14_emitcode("mov","a,b");
3401 pic14_emitcode("rrc","a");
3402 aopPut(AOP(result),"c",0);
3405 /*-----------------------------------------------------------------*/
3406 /* genModOneByte : 8 bit modulus */
3407 /*-----------------------------------------------------------------*/
3408 static void genModOneByte (operand *left,
3412 sym_link *opetype = operandType(result);
3416 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3417 /* signed or unsigned */
3418 if (SPEC_USIGN(opetype)) {
3419 /* unsigned is easy */
3420 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3421 l = aopGet(AOP(left),0,FALSE,FALSE);
3423 pic14_emitcode("div","ab");
3424 aopPut(AOP(result),"b",0);
3428 /* signed is a little bit more difficult */
3430 /* save the signs of the operands */
3431 l = aopGet(AOP(left),0,FALSE,FALSE);
3434 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3435 pic14_emitcode("push","acc"); /* save it on the stack */
3437 /* now sign adjust for both left & right */
3438 l = aopGet(AOP(right),0,FALSE,FALSE);
3441 lbl = newiTempLabel(NULL);
3442 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3443 pic14_emitcode("cpl","a");
3444 pic14_emitcode("inc","a");
3445 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3446 pic14_emitcode("mov","b,a");
3448 /* sign adjust left side */
3449 l = aopGet(AOP(left),0,FALSE,FALSE);
3452 lbl = newiTempLabel(NULL);
3453 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3454 pic14_emitcode("cpl","a");
3455 pic14_emitcode("inc","a");
3456 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3458 /* now the multiplication */
3459 pic14_emitcode("div","ab");
3460 /* we are interested in the lower order
3462 lbl = newiTempLabel(NULL);
3463 pic14_emitcode("pop","acc");
3464 /* if there was an over flow we don't
3465 adjust the sign of the result */
3466 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3467 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3469 pic14_emitcode("clr","a");
3470 pic14_emitcode("subb","a,b");
3471 pic14_emitcode("mov","b,a");
3472 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3474 /* now we are done */
3475 aopPut(AOP(result),"b",0);
3479 /*-----------------------------------------------------------------*/
3480 /* genMod - generates code for division */
3481 /*-----------------------------------------------------------------*/
3482 static void genMod (iCode *ic)
3484 operand *left = IC_LEFT(ic);
3485 operand *right = IC_RIGHT(ic);
3486 operand *result= IC_RESULT(ic);
3488 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3489 /* assign the amsops */
3490 aopOp (left,ic,FALSE);
3491 aopOp (right,ic,FALSE);
3492 aopOp (result,ic,TRUE);
3494 /* special cases first */
3496 if (AOP_TYPE(left) == AOP_CRY &&
3497 AOP_TYPE(right)== AOP_CRY) {
3498 genModbits(left,right,result);
3502 /* if both are of size == 1 */
3503 if (AOP_SIZE(left) == 1 &&
3504 AOP_SIZE(right) == 1 ) {
3505 genModOneByte(left,right,result);
3509 /* should have been converted to function call */
3513 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3514 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3515 freeAsmop(result,NULL,ic,TRUE);
3518 /*-----------------------------------------------------------------*/
3519 /* genIfxJump :- will create a jump depending on the ifx */
3520 /*-----------------------------------------------------------------*/
3522 note: May need to add parameter to indicate when a variable is in bit space.
3524 static void genIfxJump (iCode *ic, char *jval)
3527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3528 /* if true label then we jump if condition
3530 if ( IC_TRUE(ic) ) {
3532 if(strcmp(jval,"a") == 0)
3534 else if (strcmp(jval,"c") == 0)
3537 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3538 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3541 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3542 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3546 /* false label is present */
3547 if(strcmp(jval,"a") == 0)
3549 else if (strcmp(jval,"c") == 0)
3552 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3553 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3556 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3557 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3562 /* mark the icode as generated */
3566 /*-----------------------------------------------------------------*/
3568 /*-----------------------------------------------------------------*/
3569 static void genSkip(iCode *ifx,int status_bit)
3574 if ( IC_TRUE(ifx) ) {
3575 switch(status_bit) {
3590 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3591 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3595 switch(status_bit) {
3609 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3610 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3616 /*-----------------------------------------------------------------*/
3618 /*-----------------------------------------------------------------*/
3619 static void genSkipc(resolvedIfx *rifx)
3629 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3630 rifx->generated = 1;
3633 /*-----------------------------------------------------------------*/
3635 /*-----------------------------------------------------------------*/
3636 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3641 if( (rifx->condition ^ invert_condition) & 1)
3646 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3647 rifx->generated = 1;
3650 /*-----------------------------------------------------------------*/
3652 /*-----------------------------------------------------------------*/
3653 static void genSkipz(iCode *ifx, int condition)
3664 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3666 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3669 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3671 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3674 /*-----------------------------------------------------------------*/
3676 /*-----------------------------------------------------------------*/
3677 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3683 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3685 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3688 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3689 rifx->generated = 1;
3693 /*-----------------------------------------------------------------*/
3694 /* genChkZeroes :- greater or less than comparison */
3695 /* For each byte in a literal that is zero, inclusive or the */
3696 /* the corresponding byte in the operand with W */
3697 /* returns true if any of the bytes are zero */
3698 /*-----------------------------------------------------------------*/
3699 static int genChkZeroes(operand *op, int lit, int size)
3706 i = (lit >> (size*8)) & 0xff;
3710 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3712 emitpcode(POC_IORFW, popGet(AOP(op),size));
3721 /*-----------------------------------------------------------------*/
3722 /* genCmp :- greater or less than comparison */
3723 /*-----------------------------------------------------------------*/
3724 static void genCmp (operand *left,operand *right,
3725 operand *result, iCode *ifx, int sign)
3727 int size; //, offset = 0 ;
3728 unsigned long lit = 0L,i = 0;
3729 resolvedIfx rFalseIfx;
3730 // resolvedIfx rTrueIfx;
3732 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3735 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3736 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3740 resolveIfx(&rFalseIfx,ifx);
3741 truelbl = newiTempLabel(NULL);
3742 size = max(AOP_SIZE(left),AOP_SIZE(right));
3744 DEBUGpic14_AopType(__LINE__,left,right,result);
3748 /* if literal is on the right then swap with left */
3749 if ((AOP_TYPE(right) == AOP_LIT)) {
3750 operand *tmp = right ;
3751 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3752 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3755 lit = (lit - 1) & mask;
3758 rFalseIfx.condition ^= 1;
3761 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3762 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3766 //if(IC_TRUE(ifx) == NULL)
3767 /* if left & right are bit variables */
3768 if (AOP_TYPE(left) == AOP_CRY &&
3769 AOP_TYPE(right) == AOP_CRY ) {
3770 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3771 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3773 /* subtract right from left if at the
3774 end the carry flag is set then we know that
3775 left is greater than right */
3779 symbol *lbl = newiTempLabel(NULL);
3782 if(AOP_TYPE(right) == AOP_LIT) {
3784 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3786 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3793 genSkipCond(&rFalseIfx,left,size-1,7);
3795 /* no need to compare to 0...*/
3796 /* NOTE: this is a de-generate compare that most certainly
3797 * creates some dead code. */
3798 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3800 if(ifx) ifx->generated = 1;
3807 //i = (lit >> (size*8)) & 0xff;
3808 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3810 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3812 i = ((0-lit) & 0xff);
3815 /* lit is 0x7f, all signed chars are less than
3816 * this except for 0x7f itself */
3817 emitpcode(POC_XORLW, popGetLit(0x7f));
3818 genSkipz2(&rFalseIfx,0);
3820 emitpcode(POC_ADDLW, popGetLit(0x80));
3821 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3822 genSkipc(&rFalseIfx);
3827 genSkipz2(&rFalseIfx,1);
3829 emitpcode(POC_ADDLW, popGetLit(i));
3830 genSkipc(&rFalseIfx);
3834 if(ifx) ifx->generated = 1;
3838 /* chars are out of the way. now do ints and longs */
3841 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3848 genSkipCond(&rFalseIfx,left,size,7);
3849 if(ifx) ifx->generated = 1;
3854 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3856 //rFalseIfx.condition ^= 1;
3857 //genSkipCond(&rFalseIfx,left,size,7);
3858 //rFalseIfx.condition ^= 1;
3860 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3861 if(rFalseIfx.condition)
3862 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3864 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3866 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3867 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3868 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3871 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3873 if(rFalseIfx.condition) {
3875 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3881 genSkipc(&rFalseIfx);
3882 emitpLabel(truelbl->key);
3883 if(ifx) ifx->generated = 1;
3890 if( (lit & 0xff) == 0) {
3891 /* lower byte is zero */
3892 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3893 i = ((lit >> 8) & 0xff) ^0x80;
3894 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3895 emitpcode(POC_ADDLW, popGetLit( 0x80));
3896 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3897 genSkipc(&rFalseIfx);
3900 if(ifx) ifx->generated = 1;
3905 /* Special cases for signed longs */
3906 if( (lit & 0xffffff) == 0) {
3907 /* lower byte is zero */
3908 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3909 i = ((lit >> 8*3) & 0xff) ^0x80;
3910 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3911 emitpcode(POC_ADDLW, popGetLit( 0x80));
3912 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3913 genSkipc(&rFalseIfx);
3916 if(ifx) ifx->generated = 1;
3924 if(lit & (0x80 << (size*8))) {
3925 /* lit is negative */
3926 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3928 //genSkipCond(&rFalseIfx,left,size,7);
3930 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3932 if(rFalseIfx.condition)
3933 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3935 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3939 /* lit is positive */
3940 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3941 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3942 if(rFalseIfx.condition)
3943 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3945 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3950 This works, but is only good for ints.
3951 It also requires a "known zero" register.
3952 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3953 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3954 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3955 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3956 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3957 genSkipc(&rFalseIfx);
3959 emitpLabel(truelbl->key);
3960 if(ifx) ifx->generated = 1;
3964 /* There are no more special cases, so perform a general compare */
3966 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3967 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3971 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3973 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3975 //rFalseIfx.condition ^= 1;
3976 genSkipc(&rFalseIfx);
3978 emitpLabel(truelbl->key);
3980 if(ifx) ifx->generated = 1;
3987 /* sign is out of the way. So now do an unsigned compare */
3988 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3991 /* General case - compare to an unsigned literal on the right.*/
3993 i = (lit >> (size*8)) & 0xff;
3994 emitpcode(POC_MOVLW, popGetLit(i));
3995 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3997 i = (lit >> (size*8)) & 0xff;
4000 emitpcode(POC_MOVLW, popGetLit(i));
4002 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4004 /* this byte of the lit is zero,
4005 *if it's not the last then OR in the variable */
4007 emitpcode(POC_IORFW, popGet(AOP(left),size));
4012 emitpLabel(lbl->key);
4013 //if(emitFinalCheck)
4014 genSkipc(&rFalseIfx);
4016 emitpLabel(truelbl->key);
4018 if(ifx) ifx->generated = 1;
4025 if(AOP_TYPE(left) == AOP_LIT) {
4026 //symbol *lbl = newiTempLabel(NULL);
4028 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4031 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4034 if((lit == 0) && (sign == 0)){
4037 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4039 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4041 genSkipz2(&rFalseIfx,0);
4042 if(ifx) ifx->generated = 1;
4049 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4050 /* degenerate compare can never be true */
4051 if(rFalseIfx.condition == 0)
4052 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4054 if(ifx) ifx->generated = 1;
4059 /* signed comparisons to a literal byte */
4061 int lp1 = (lit+1) & 0xff;
4063 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4066 rFalseIfx.condition ^= 1;
4067 genSkipCond(&rFalseIfx,right,0,7);
4070 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4071 emitpcode(POC_XORLW, popGetLit(0x7f));
4072 genSkipz2(&rFalseIfx,1);
4075 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4076 emitpcode(POC_ADDLW, popGetLit(0x80));
4077 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4078 rFalseIfx.condition ^= 1;
4079 genSkipc(&rFalseIfx);
4082 if(ifx) ifx->generated = 1;
4084 /* unsigned comparisons to a literal byte */
4086 switch(lit & 0xff ) {
4088 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4089 genSkipz2(&rFalseIfx,0);
4090 if(ifx) ifx->generated = 1;
4093 rFalseIfx.condition ^= 1;
4094 genSkipCond(&rFalseIfx,right,0,7);
4095 if(ifx) ifx->generated = 1;
4099 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4100 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4102 rFalseIfx.condition ^= 1;
4103 if (AOP_TYPE(result) == AOP_CRY) {
4104 genSkipc(&rFalseIfx);
4105 if(ifx) ifx->generated = 1;
4107 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4108 emitpcode(POC_CLRF, popGet(AOP(result),0));
4109 emitpcode(POC_RLF, popGet(AOP(result),0));
4110 emitpcode(POC_MOVLW, popGetLit(0x01));
4111 emitpcode(POC_XORWF, popGet(AOP(result),0));
4122 /* Size is greater than 1 */
4130 /* this means lit = 0xffffffff, or -1 */
4133 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4134 rFalseIfx.condition ^= 1;
4135 genSkipCond(&rFalseIfx,right,size,7);
4136 if(ifx) ifx->generated = 1;
4143 if(rFalseIfx.condition) {
4144 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4145 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4148 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4150 emitpcode(POC_IORFW, popGet(AOP(right),size));
4154 if(rFalseIfx.condition) {
4155 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4156 emitpLabel(truelbl->key);
4158 rFalseIfx.condition ^= 1;
4159 genSkipCond(&rFalseIfx,right,s,7);
4162 if(ifx) ifx->generated = 1;
4166 if((size == 1) && (0 == (lp1&0xff))) {
4167 /* lower byte of signed word is zero */
4168 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4169 i = ((lp1 >> 8) & 0xff) ^0x80;
4170 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4171 emitpcode(POC_ADDLW, popGetLit( 0x80));
4172 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4173 rFalseIfx.condition ^= 1;
4174 genSkipc(&rFalseIfx);
4177 if(ifx) ifx->generated = 1;
4181 if(lit & (0x80 << (size*8))) {
4182 /* Lit is less than zero */
4183 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4184 //rFalseIfx.condition ^= 1;
4185 //genSkipCond(&rFalseIfx,left,size,7);
4186 //rFalseIfx.condition ^= 1;
4187 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4188 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4190 if(rFalseIfx.condition)
4191 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4193 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4197 /* Lit is greater than or equal to zero */
4198 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4199 //rFalseIfx.condition ^= 1;
4200 //genSkipCond(&rFalseIfx,right,size,7);
4201 //rFalseIfx.condition ^= 1;
4203 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4204 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4206 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4207 if(rFalseIfx.condition)
4208 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4210 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4215 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4216 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4220 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4222 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4224 rFalseIfx.condition ^= 1;
4225 //rFalseIfx.condition = 1;
4226 genSkipc(&rFalseIfx);
4228 emitpLabel(truelbl->key);
4230 if(ifx) ifx->generated = 1;
4235 /* compare word or long to an unsigned literal on the right.*/
4240 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4243 break; /* handled above */
4246 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4248 emitpcode(POC_IORFW, popGet(AOP(right),size));
4249 genSkipz2(&rFalseIfx,0);
4253 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4255 emitpcode(POC_IORFW, popGet(AOP(right),size));
4258 if(rFalseIfx.condition)
4259 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4261 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4264 emitpcode(POC_MOVLW, popGetLit(lit+1));
4265 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4267 rFalseIfx.condition ^= 1;
4268 genSkipc(&rFalseIfx);
4271 emitpLabel(truelbl->key);
4273 if(ifx) ifx->generated = 1;
4279 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4280 i = (lit >> (size*8)) & 0xff;
4282 emitpcode(POC_MOVLW, popGetLit(i));
4283 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4286 i = (lit >> (size*8)) & 0xff;
4289 emitpcode(POC_MOVLW, popGetLit(i));
4291 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4293 /* this byte of the lit is zero,
4294 *if it's not the last then OR in the variable */
4296 emitpcode(POC_IORFW, popGet(AOP(right),size));
4301 emitpLabel(lbl->key);
4303 rFalseIfx.condition ^= 1;
4304 genSkipc(&rFalseIfx);
4308 emitpLabel(truelbl->key);
4309 if(ifx) ifx->generated = 1;
4313 /* Compare two variables */
4315 DEBUGpic14_emitcode(";sign","%d",sign);
4319 /* Sigh. thus sucks... */
4321 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4322 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4323 emitpcode(POC_MOVLW, popGetLit(0x80));
4324 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4325 emitpcode(POC_XORFW, popGet(AOP(right),size));
4326 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4328 /* Signed char comparison */
4329 /* Special thanks to Nikolai Golovchenko for this snippet */
4330 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4331 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4332 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4333 emitpcode(POC_XORFW, popGet(AOP(left),0));
4334 emitpcode(POC_XORFW, popGet(AOP(right),0));
4335 emitpcode(POC_ADDLW, popGetLit(0x80));
4337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4338 genSkipc(&rFalseIfx);
4340 if(ifx) ifx->generated = 1;
4346 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4347 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4351 /* The rest of the bytes of a multi-byte compare */
4355 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4358 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4359 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4364 emitpLabel(lbl->key);
4366 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4367 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4368 (AOP_TYPE(result) == AOP_REG)) {
4369 emitpcode(POC_CLRF, popGet(AOP(result),0));
4370 emitpcode(POC_RLF, popGet(AOP(result),0));
4372 genSkipc(&rFalseIfx);
4374 //genSkipc(&rFalseIfx);
4375 if(ifx) ifx->generated = 1;
4382 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4383 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4384 pic14_outBitC(result);
4386 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4387 /* if the result is used in the next
4388 ifx conditional branch then generate
4389 code a little differently */
4391 genIfxJump (ifx,"c");
4393 pic14_outBitC(result);
4394 /* leave the result in acc */
4399 /*-----------------------------------------------------------------*/
4400 /* genCmpGt :- greater than comparison */
4401 /*-----------------------------------------------------------------*/
4402 static void genCmpGt (iCode *ic, iCode *ifx)
4404 operand *left, *right, *result;
4405 sym_link *letype , *retype;
4408 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4410 right= IC_RIGHT(ic);
4411 result = IC_RESULT(ic);
4413 letype = getSpec(operandType(left));
4414 retype =getSpec(operandType(right));
4415 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4416 /* assign the amsops */
4417 aopOp (left,ic,FALSE);
4418 aopOp (right,ic,FALSE);
4419 aopOp (result,ic,TRUE);
4421 genCmp(right, left, result, ifx, sign);
4423 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4424 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4425 freeAsmop(result,NULL,ic,TRUE);
4428 /*-----------------------------------------------------------------*/
4429 /* genCmpLt - less than comparisons */
4430 /*-----------------------------------------------------------------*/
4431 static void genCmpLt (iCode *ic, iCode *ifx)
4433 operand *left, *right, *result;
4434 sym_link *letype , *retype;
4437 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4439 right= IC_RIGHT(ic);
4440 result = IC_RESULT(ic);
4442 letype = getSpec(operandType(left));
4443 retype =getSpec(operandType(right));
4444 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4446 /* assign the amsops */
4447 aopOp (left,ic,FALSE);
4448 aopOp (right,ic,FALSE);
4449 aopOp (result,ic,TRUE);
4451 genCmp(left, right, result, ifx, sign);
4453 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4454 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4455 freeAsmop(result,NULL,ic,TRUE);
4458 /*-----------------------------------------------------------------*/
4459 /* genc16bit2lit - compare a 16 bit value to a literal */
4460 /*-----------------------------------------------------------------*/
4461 static void genc16bit2lit(operand *op, int lit, int offset)
4465 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4466 if( (lit&0xff) == 0)
4471 switch( BYTEofLONG(lit,i)) {
4473 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4476 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4479 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4482 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4483 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4488 switch( BYTEofLONG(lit,i)) {
4490 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4494 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4498 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4501 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4503 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4509 /*-----------------------------------------------------------------*/
4510 /* gencjneshort - compare and jump if not equal */
4511 /*-----------------------------------------------------------------*/
4512 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4514 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4516 int res_offset = 0; /* the result may be a different size then left or right */
4517 int res_size = AOP_SIZE(result);
4521 unsigned long lit = 0L;
4522 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4523 DEBUGpic14_AopType(__LINE__,left,right,result);
4525 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4526 resolveIfx(&rIfx,ifx);
4527 lbl = newiTempLabel(NULL);
4530 /* if the left side is a literal or
4531 if the right is in a pointer register and left
4533 if ((AOP_TYPE(left) == AOP_LIT) ||
4534 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4539 if(AOP_TYPE(right) == AOP_LIT)
4540 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4542 /* if the right side is a literal then anything goes */
4543 if (AOP_TYPE(right) == AOP_LIT &&
4544 AOP_TYPE(left) != AOP_DIR ) {
4547 genc16bit2lit(left, lit, 0);
4549 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4554 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4555 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4557 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4561 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4563 if(res_offset < res_size-1)
4571 /* if the right side is in a register or in direct space or
4572 if the left is a pointer register & right is not */
4573 else if (AOP_TYPE(right) == AOP_REG ||
4574 AOP_TYPE(right) == AOP_DIR ||
4575 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4576 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4577 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4578 int lbl_key = lbl->key;
4581 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4582 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4584 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4585 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4586 __FUNCTION__,__LINE__);
4590 /* switch(size) { */
4592 /* genc16bit2lit(left, lit, 0); */
4594 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4599 if((AOP_TYPE(left) == AOP_DIR) &&
4600 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4602 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4603 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4605 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4607 switch (lit & 0xff) {
4609 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4612 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4613 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4614 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4618 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4619 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4620 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4621 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4625 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4626 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4631 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4634 if(AOP_TYPE(result) == AOP_CRY) {
4635 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4640 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4642 /* fix me. probably need to check result size too */
4643 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4648 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4649 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4656 if(res_offset < res_size-1)
4661 } else if(AOP_TYPE(right) == AOP_REG &&
4662 AOP_TYPE(left) != AOP_DIR){
4665 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4666 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4667 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4672 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4674 if(res_offset < res_size-1)
4679 /* right is a pointer reg need both a & b */
4681 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4683 pic14_emitcode("mov","b,%s",l);
4684 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4685 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4690 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4692 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4694 emitpLabel(lbl->key);
4696 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4703 /*-----------------------------------------------------------------*/
4704 /* gencjne - compare and jump if not equal */
4705 /*-----------------------------------------------------------------*/
4706 static void gencjne(operand *left, operand *right, iCode *ifx)
4708 symbol *tlbl = newiTempLabel(NULL);
4710 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4711 gencjneshort(left, right, lbl);
4713 pic14_emitcode("mov","a,%s",one);
4714 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4715 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4716 pic14_emitcode("clr","a");
4717 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4719 emitpLabel(lbl->key);
4720 emitpLabel(tlbl->key);
4725 /*-----------------------------------------------------------------*/
4726 /* genCmpEq - generates code for equal to */
4727 /*-----------------------------------------------------------------*/
4728 static void genCmpEq (iCode *ic, iCode *ifx)
4730 operand *left, *right, *result;
4731 unsigned long lit = 0L;
4734 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4737 DEBUGpic14_emitcode ("; ifx is non-null","");
4739 DEBUGpic14_emitcode ("; ifx is null","");
4741 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4742 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4743 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4745 size = max(AOP_SIZE(left),AOP_SIZE(right));
4747 DEBUGpic14_AopType(__LINE__,left,right,result);
4749 /* if literal, literal on the right or
4750 if the right is in a pointer register and left
4752 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4753 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4754 operand *tmp = right ;
4760 if(ifx && !AOP_SIZE(result)){
4762 /* if they are both bit variables */
4763 if (AOP_TYPE(left) == AOP_CRY &&
4764 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4765 if(AOP_TYPE(right) == AOP_LIT){
4766 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4768 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4769 pic14_emitcode("cpl","c");
4770 } else if(lit == 1L) {
4771 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4773 pic14_emitcode("clr","c");
4775 /* AOP_TYPE(right) == AOP_CRY */
4777 symbol *lbl = newiTempLabel(NULL);
4778 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4779 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4780 pic14_emitcode("cpl","c");
4781 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4783 /* if true label then we jump if condition
4785 tlbl = newiTempLabel(NULL);
4786 if ( IC_TRUE(ifx) ) {
4787 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4788 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4790 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4791 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4793 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4796 /* left and right are both bit variables, result is carry */
4799 resolveIfx(&rIfx,ifx);
4801 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4802 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4803 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4804 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4809 /* They're not both bit variables. Is the right a literal? */
4810 if(AOP_TYPE(right) == AOP_LIT) {
4811 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4816 switch(lit & 0xff) {
4818 if ( IC_TRUE(ifx) ) {
4819 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4821 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4823 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4824 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4828 if ( IC_TRUE(ifx) ) {
4829 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4831 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4833 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4834 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4838 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4840 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4845 /* end of size == 1 */
4849 genc16bit2lit(left,lit,offset);
4852 /* end of size == 2 */
4857 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4858 emitpcode(POC_IORFW,popGet(AOP(left),1));
4859 emitpcode(POC_IORFW,popGet(AOP(left),2));
4860 emitpcode(POC_IORFW,popGet(AOP(left),3));
4864 /* search for patterns that can be optimized */
4866 genc16bit2lit(left,lit,0);
4869 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4871 genc16bit2lit(left,lit,2);
4873 emitpcode(POC_IORFW,popGet(AOP(left),2));
4874 emitpcode(POC_IORFW,popGet(AOP(left),3));
4887 } else if(AOP_TYPE(right) == AOP_CRY ) {
4888 /* we know the left is not a bit, but that the right is */
4889 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4890 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4891 popGet(AOP(right),offset));
4892 emitpcode(POC_XORLW,popGetLit(1));
4894 /* if the two are equal, then W will be 0 and the Z bit is set
4895 * we could test Z now, or go ahead and check the high order bytes if
4896 * the variable we're comparing is larger than a byte. */
4899 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4901 if ( IC_TRUE(ifx) ) {
4903 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4904 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4907 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4908 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4912 /* They're both variables that are larger than bits */
4915 tlbl = newiTempLabel(NULL);
4918 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4919 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4921 if ( IC_TRUE(ifx) ) {
4924 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4925 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4928 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4929 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4933 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4934 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4938 if(s>1 && IC_TRUE(ifx)) {
4939 emitpLabel(tlbl->key);
4940 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4944 /* mark the icode as generated */
4949 /* if they are both bit variables */
4950 if (AOP_TYPE(left) == AOP_CRY &&
4951 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4952 if(AOP_TYPE(right) == AOP_LIT){
4953 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4955 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4956 pic14_emitcode("cpl","c");
4957 } else if(lit == 1L) {
4958 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4960 pic14_emitcode("clr","c");
4962 /* AOP_TYPE(right) == AOP_CRY */
4964 symbol *lbl = newiTempLabel(NULL);
4965 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4966 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4967 pic14_emitcode("cpl","c");
4968 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4971 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4972 pic14_outBitC(result);
4976 genIfxJump (ifx,"c");
4979 /* if the result is used in an arithmetic operation
4980 then put the result in place */
4981 pic14_outBitC(result);
4984 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4985 gencjne(left,right,result,ifx);
4988 gencjne(left,right,newiTempLabel(NULL));
4990 if(IC_TRUE(ifx)->key)
4991 gencjne(left,right,IC_TRUE(ifx)->key);
4993 gencjne(left,right,IC_FALSE(ifx)->key);
4997 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4998 aopPut(AOP(result),"a",0);
5003 genIfxJump (ifx,"a");
5007 /* if the result is used in an arithmetic operation
5008 then put the result in place */
5010 if (AOP_TYPE(result) != AOP_CRY)
5011 pic14_outAcc(result);
5013 /* leave the result in acc */
5017 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5018 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5019 freeAsmop(result,NULL,ic,TRUE);
5022 /*-----------------------------------------------------------------*/
5023 /* ifxForOp - returns the icode containing the ifx for operand */
5024 /*-----------------------------------------------------------------*/
5025 static iCode *ifxForOp ( operand *op, iCode *ic )
5027 /* if true symbol then needs to be assigned */
5028 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5029 if (IS_TRUE_SYMOP(op))
5032 /* if this has register type condition and
5033 the next instruction is ifx with the same operand
5034 and live to of the operand is upto the ifx only then */
5036 ic->next->op == IFX &&
5037 IC_COND(ic->next)->key == op->key &&
5038 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5042 ic->next->op == IFX &&
5043 IC_COND(ic->next)->key == op->key) {
5044 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5048 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5050 ic->next->op == IFX)
5051 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5054 ic->next->op == IFX &&
5055 IC_COND(ic->next)->key == op->key) {
5056 DEBUGpic14_emitcode ("; "," key is okay");
5057 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5058 OP_SYMBOL(op)->liveTo,
5065 /*-----------------------------------------------------------------*/
5066 /* genAndOp - for && operation */
5067 /*-----------------------------------------------------------------*/
5068 static void genAndOp (iCode *ic)
5070 operand *left,*right, *result;
5073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5074 /* note here that && operations that are in an
5075 if statement are taken away by backPatchLabels
5076 only those used in arthmetic operations remain */
5077 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5078 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5079 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5081 DEBUGpic14_AopType(__LINE__,left,right,result);
5083 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5084 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5085 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5087 /* if both are bit variables */
5088 /* if (AOP_TYPE(left) == AOP_CRY && */
5089 /* AOP_TYPE(right) == AOP_CRY ) { */
5090 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5091 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5092 /* pic14_outBitC(result); */
5094 /* tlbl = newiTempLabel(NULL); */
5095 /* pic14_toBoolean(left); */
5096 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5097 /* pic14_toBoolean(right); */
5098 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5099 /* pic14_outBitAcc(result); */
5102 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5103 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5104 freeAsmop(result,NULL,ic,TRUE);
5108 /*-----------------------------------------------------------------*/
5109 /* genOrOp - for || operation */
5110 /*-----------------------------------------------------------------*/
5113 modified this code, but it doesn't appear to ever get called
5116 static void genOrOp (iCode *ic)
5118 operand *left,*right, *result;
5121 /* note here that || operations that are in an
5122 if statement are taken away by backPatchLabels
5123 only those used in arthmetic operations remain */
5124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5125 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5126 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5127 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5129 DEBUGpic14_AopType(__LINE__,left,right,result);
5131 /* if both are bit variables */
5132 if (AOP_TYPE(left) == AOP_CRY &&
5133 AOP_TYPE(right) == AOP_CRY ) {
5134 pic14_emitcode("clrc","");
5135 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5136 AOP(left)->aopu.aop_dir,
5137 AOP(left)->aopu.aop_dir);
5138 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5139 AOP(right)->aopu.aop_dir,
5140 AOP(right)->aopu.aop_dir);
5141 pic14_emitcode("setc","");
5144 tlbl = newiTempLabel(NULL);
5145 pic14_toBoolean(left);
5147 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5148 pic14_toBoolean(right);
5149 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5151 pic14_outBitAcc(result);
5154 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5155 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5156 freeAsmop(result,NULL,ic,TRUE);
5159 /*-----------------------------------------------------------------*/
5160 /* isLiteralBit - test if lit == 2^n */
5161 /*-----------------------------------------------------------------*/
5162 static int isLiteralBit(unsigned long lit)
5164 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5165 0x100L,0x200L,0x400L,0x800L,
5166 0x1000L,0x2000L,0x4000L,0x8000L,
5167 0x10000L,0x20000L,0x40000L,0x80000L,
5168 0x100000L,0x200000L,0x400000L,0x800000L,
5169 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5170 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5173 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5174 for(idx = 0; idx < 32; idx++)
5180 /*-----------------------------------------------------------------*/
5181 /* continueIfTrue - */
5182 /*-----------------------------------------------------------------*/
5183 static void continueIfTrue (iCode *ic)
5185 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5187 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5191 /*-----------------------------------------------------------------*/
5193 /*-----------------------------------------------------------------*/
5194 static void jumpIfTrue (iCode *ic)
5196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5198 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5202 /*-----------------------------------------------------------------*/
5203 /* jmpTrueOrFalse - */
5204 /*-----------------------------------------------------------------*/
5205 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5207 // ugly but optimized by peephole
5208 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5210 symbol *nlbl = newiTempLabel(NULL);
5211 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5212 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5213 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5214 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5217 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5218 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5223 /*-----------------------------------------------------------------*/
5224 /* genAnd - code for and */
5225 /*-----------------------------------------------------------------*/
5226 static void genAnd (iCode *ic, iCode *ifx)
5228 operand *left, *right, *result;
5230 unsigned long lit = 0L;
5235 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5236 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5237 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5238 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5240 resolveIfx(&rIfx,ifx);
5242 /* if left is a literal & right is not then exchange them */
5243 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5244 AOP_NEEDSACC(left)) {
5245 operand *tmp = right ;
5250 /* if result = right then exchange them */
5251 if(pic14_sameRegs(AOP(result),AOP(right))){
5252 operand *tmp = right ;
5257 /* if right is bit then exchange them */
5258 if (AOP_TYPE(right) == AOP_CRY &&
5259 AOP_TYPE(left) != AOP_CRY){
5260 operand *tmp = right ;
5264 if(AOP_TYPE(right) == AOP_LIT)
5265 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5267 size = AOP_SIZE(result);
5269 DEBUGpic14_AopType(__LINE__,left,right,result);
5272 // result = bit & yy;
5273 if (AOP_TYPE(left) == AOP_CRY){
5274 // c = bit & literal;
5275 if(AOP_TYPE(right) == AOP_LIT){
5277 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5280 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5283 if(size && (AOP_TYPE(result) == AOP_CRY)){
5284 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5287 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5291 pic14_emitcode("clr","c");
5294 if (AOP_TYPE(right) == AOP_CRY){
5296 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5297 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5300 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5302 pic14_emitcode("rrc","a");
5303 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5309 pic14_outBitC(result);
5311 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5312 genIfxJump(ifx, "c");
5316 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5317 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5318 if((AOP_TYPE(right) == AOP_LIT) &&
5319 (AOP_TYPE(result) == AOP_CRY) &&
5320 (AOP_TYPE(left) != AOP_CRY)){
5321 int posbit = isLiteralBit(lit);
5325 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5328 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5334 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5335 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5337 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5338 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5341 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5342 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5343 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5350 symbol *tlbl = newiTempLabel(NULL);
5351 int sizel = AOP_SIZE(left);
5353 pic14_emitcode("setb","c");
5355 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5356 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5358 if((posbit = isLiteralBit(bytelit)) != 0)
5359 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5361 if(bytelit != 0x0FFL)
5362 pic14_emitcode("anl","a,%s",
5363 aopGet(AOP(right),offset,FALSE,TRUE));
5364 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5369 // bit = left & literal
5371 pic14_emitcode("clr","c");
5372 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5374 // if(left & literal)
5377 jmpTrueOrFalse(ifx, tlbl);
5381 pic14_outBitC(result);
5385 /* if left is same as result */
5386 if(pic14_sameRegs(AOP(result),AOP(left))){
5388 for(;size--; offset++,lit>>=8) {
5389 if(AOP_TYPE(right) == AOP_LIT){
5390 switch(lit & 0xff) {
5392 /* and'ing with 0 has clears the result */
5393 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5394 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5397 /* and'ing with 0xff is a nop when the result and left are the same */
5402 int p = my_powof2( (~lit) & 0xff );
5404 /* only one bit is set in the literal, so use a bcf instruction */
5405 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5406 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5409 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5410 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5411 if(know_W != (int)(lit&0xff))
5412 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5414 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5419 if (AOP_TYPE(left) == AOP_ACC) {
5420 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5422 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5423 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5430 // left & result in different registers
5431 if(AOP_TYPE(result) == AOP_CRY){
5433 // if(size), result in bit
5434 // if(!size && ifx), conditional oper: if(left & right)
5435 symbol *tlbl = newiTempLabel(NULL);
5436 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5438 pic14_emitcode("setb","c");
5440 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5441 pic14_emitcode("anl","a,%s",
5442 aopGet(AOP(left),offset,FALSE,FALSE));
5443 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5448 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5449 pic14_outBitC(result);
5451 jmpTrueOrFalse(ifx, tlbl);
5453 for(;(size--);offset++) {
5455 // result = left & right
5456 if(AOP_TYPE(right) == AOP_LIT){
5457 int t = (lit >> (offset*8)) & 0x0FFL;
5460 pic14_emitcode("clrf","%s",
5461 aopGet(AOP(result),offset,FALSE,FALSE));
5462 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5465 if(AOP_TYPE(left) != AOP_ACC) {
5466 pic14_emitcode("movf","%s,w",
5467 aopGet(AOP(left),offset,FALSE,FALSE));
5468 pic14_emitcode("movwf","%s",
5469 aopGet(AOP(result),offset,FALSE,FALSE));
5470 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5472 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5475 if(AOP_TYPE(left) == AOP_ACC) {
5476 emitpcode(POC_ANDLW, popGetLit(t));
5478 pic14_emitcode("movlw","0x%x",t);
5479 pic14_emitcode("andwf","%s,w",
5480 aopGet(AOP(left),offset,FALSE,FALSE));
5481 pic14_emitcode("movwf","%s",
5482 aopGet(AOP(result),offset,FALSE,FALSE));
5484 emitpcode(POC_MOVLW, popGetLit(t));
5485 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5487 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5492 if (AOP_TYPE(left) == AOP_ACC) {
5493 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5494 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5496 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5497 pic14_emitcode("andwf","%s,w",
5498 aopGet(AOP(left),offset,FALSE,FALSE));
5499 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5500 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5502 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5503 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5509 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5510 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5511 freeAsmop(result,NULL,ic,TRUE);
5514 /*-----------------------------------------------------------------*/
5515 /* genOr - code for or */
5516 /*-----------------------------------------------------------------*/
5517 static void genOr (iCode *ic, iCode *ifx)
5519 operand *left, *right, *result;
5521 unsigned long lit = 0L;
5523 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5525 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5526 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5527 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5529 DEBUGpic14_AopType(__LINE__,left,right,result);
5531 /* if left is a literal & right is not then exchange them */
5532 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5533 AOP_NEEDSACC(left)) {
5534 operand *tmp = right ;
5539 /* if result = right then exchange them */
5540 if(pic14_sameRegs(AOP(result),AOP(right))){
5541 operand *tmp = right ;
5546 /* if right is bit then exchange them */
5547 if (AOP_TYPE(right) == AOP_CRY &&
5548 AOP_TYPE(left) != AOP_CRY){
5549 operand *tmp = right ;
5554 DEBUGpic14_AopType(__LINE__,left,right,result);
5556 if(AOP_TYPE(right) == AOP_LIT)
5557 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5559 size = AOP_SIZE(result);
5563 if (AOP_TYPE(left) == AOP_CRY){
5564 if(AOP_TYPE(right) == AOP_LIT){
5565 // c = bit & literal;
5567 // lit != 0 => result = 1
5568 if(AOP_TYPE(result) == AOP_CRY){
5570 emitpcode(POC_BSF, popGet(AOP(result),0));
5571 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5572 // AOP(result)->aopu.aop_dir,
5573 // AOP(result)->aopu.aop_dir);
5575 continueIfTrue(ifx);
5579 // lit == 0 => result = left
5580 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5582 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5585 if (AOP_TYPE(right) == AOP_CRY){
5586 if(pic14_sameRegs(AOP(result),AOP(left))){
5588 emitpcode(POC_BCF, popGet(AOP(result),0));
5589 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5590 emitpcode(POC_BSF, popGet(AOP(result),0));
5592 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5593 AOP(result)->aopu.aop_dir,
5594 AOP(result)->aopu.aop_dir);
5595 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5596 AOP(right)->aopu.aop_dir,
5597 AOP(right)->aopu.aop_dir);
5598 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5599 AOP(result)->aopu.aop_dir,
5600 AOP(result)->aopu.aop_dir);
5602 if( AOP_TYPE(result) == AOP_ACC) {
5603 emitpcode(POC_MOVLW, popGetLit(0));
5604 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5605 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5606 emitpcode(POC_MOVLW, popGetLit(1));
5610 emitpcode(POC_BCF, popGet(AOP(result),0));
5611 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5612 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5613 emitpcode(POC_BSF, popGet(AOP(result),0));
5615 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5616 AOP(result)->aopu.aop_dir,
5617 AOP(result)->aopu.aop_dir);
5618 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5619 AOP(right)->aopu.aop_dir,
5620 AOP(right)->aopu.aop_dir);
5621 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5622 AOP(left)->aopu.aop_dir,
5623 AOP(left)->aopu.aop_dir);
5624 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5625 AOP(result)->aopu.aop_dir,
5626 AOP(result)->aopu.aop_dir);
5631 symbol *tlbl = newiTempLabel(NULL);
5632 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5635 emitpcode(POC_BCF, popGet(AOP(result),0));
5636 if( AOP_TYPE(right) == AOP_ACC) {
5637 emitpcode(POC_IORLW, popGetLit(0));
5639 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5640 emitpcode(POC_BSF, popGet(AOP(result),0));
5645 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5646 pic14_emitcode(";XXX setb","c");
5647 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5648 AOP(left)->aopu.aop_dir,tlbl->key+100);
5649 pic14_toBoolean(right);
5650 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5651 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5652 jmpTrueOrFalse(ifx, tlbl);
5656 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5663 pic14_outBitC(result);
5665 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5666 genIfxJump(ifx, "c");
5670 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5671 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5672 if((AOP_TYPE(right) == AOP_LIT) &&
5673 (AOP_TYPE(result) == AOP_CRY) &&
5674 (AOP_TYPE(left) != AOP_CRY)){
5676 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5679 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5681 continueIfTrue(ifx);
5684 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5685 // lit = 0, result = boolean(left)
5687 pic14_emitcode(";XXX setb","c");
5688 pic14_toBoolean(right);
5690 symbol *tlbl = newiTempLabel(NULL);
5691 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5693 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5695 genIfxJump (ifx,"a");
5699 pic14_outBitC(result);
5703 /* if left is same as result */
5704 if(pic14_sameRegs(AOP(result),AOP(left))){
5706 for(;size--; offset++,lit>>=8) {
5707 if(AOP_TYPE(right) == AOP_LIT){
5708 if((lit & 0xff) == 0)
5709 /* or'ing with 0 has no effect */
5712 int p = my_powof2(lit & 0xff);
5714 /* only one bit is set in the literal, so use a bsf instruction */
5716 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5718 if(know_W != (int)(lit & 0xff))
5719 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5720 know_W = lit & 0xff;
5721 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5726 if (AOP_TYPE(left) == AOP_ACC) {
5727 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5728 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5730 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5731 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5733 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5734 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5740 // left & result in different registers
5741 if(AOP_TYPE(result) == AOP_CRY){
5743 // if(size), result in bit
5744 // if(!size && ifx), conditional oper: if(left | right)
5745 symbol *tlbl = newiTempLabel(NULL);
5746 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5747 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5751 pic14_emitcode(";XXX setb","c");
5753 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5754 pic14_emitcode(";XXX orl","a,%s",
5755 aopGet(AOP(left),offset,FALSE,FALSE));
5756 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5761 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5762 pic14_outBitC(result);
5764 jmpTrueOrFalse(ifx, tlbl);
5765 } else for(;(size--);offset++){
5767 // result = left & right
5768 if(AOP_TYPE(right) == AOP_LIT){
5769 int t = (lit >> (offset*8)) & 0x0FFL;
5772 if (AOP_TYPE(left) != AOP_ACC) {
5773 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5775 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5779 if (AOP_TYPE(left) == AOP_ACC) {
5780 emitpcode(POC_IORLW, popGetLit(t));
5782 emitpcode(POC_MOVLW, popGetLit(t));
5783 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5785 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5790 // faster than result <- left, anl result,right
5791 // and better if result is SFR
5792 if (AOP_TYPE(left) == AOP_ACC) {
5793 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5794 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5796 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5797 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5799 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5800 pic14_emitcode("iorwf","%s,w",
5801 aopGet(AOP(left),offset,FALSE,FALSE));
5803 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5804 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5809 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5810 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5811 freeAsmop(result,NULL,ic,TRUE);
5814 /*-----------------------------------------------------------------*/
5815 /* genXor - code for xclusive or */
5816 /*-----------------------------------------------------------------*/
5817 static void genXor (iCode *ic, iCode *ifx)
5819 operand *left, *right, *result;
5821 unsigned long lit = 0L;
5823 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5825 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5826 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5827 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5829 /* if left is a literal & right is not ||
5830 if left needs acc & right does not */
5831 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5832 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5833 operand *tmp = right ;
5838 /* if result = right then exchange them */
5839 if(pic14_sameRegs(AOP(result),AOP(right))){
5840 operand *tmp = right ;
5845 /* if right is bit then exchange them */
5846 if (AOP_TYPE(right) == AOP_CRY &&
5847 AOP_TYPE(left) != AOP_CRY){
5848 operand *tmp = right ;
5852 if(AOP_TYPE(right) == AOP_LIT)
5853 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5855 size = AOP_SIZE(result);
5859 if (AOP_TYPE(left) == AOP_CRY){
5860 if(AOP_TYPE(right) == AOP_LIT){
5861 // c = bit & literal;
5863 // lit>>1 != 0 => result = 1
5864 if(AOP_TYPE(result) == AOP_CRY){
5866 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5867 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5869 continueIfTrue(ifx);
5872 pic14_emitcode("setb","c");
5876 // lit == 0, result = left
5877 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5879 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5881 // lit == 1, result = not(left)
5882 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5883 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5884 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5885 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5888 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5889 pic14_emitcode("cpl","c");
5896 symbol *tlbl = newiTempLabel(NULL);
5897 if (AOP_TYPE(right) == AOP_CRY){
5899 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5902 int sizer = AOP_SIZE(right);
5904 // if val>>1 != 0, result = 1
5905 pic14_emitcode("setb","c");
5907 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5909 // test the msb of the lsb
5910 pic14_emitcode("anl","a,#0xfe");
5911 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5915 pic14_emitcode("rrc","a");
5917 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5918 pic14_emitcode("cpl","c");
5919 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5924 pic14_outBitC(result);
5926 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5927 genIfxJump(ifx, "c");
5931 if(pic14_sameRegs(AOP(result),AOP(left))){
5932 /* if left is same as result */
5933 for(;size--; offset++) {
5934 if(AOP_TYPE(right) == AOP_LIT){
5935 int t = (lit >> (offset*8)) & 0x0FFL;
5939 if (IS_AOP_PREG(left)) {
5940 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5941 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5942 aopPut(AOP(result),"a",offset);
5944 emitpcode(POC_MOVLW, popGetLit(t));
5945 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5946 pic14_emitcode("xrl","%s,%s",
5947 aopGet(AOP(left),offset,FALSE,TRUE),
5948 aopGet(AOP(right),offset,FALSE,FALSE));
5951 if (AOP_TYPE(left) == AOP_ACC)
5952 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5954 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5955 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5957 if (IS_AOP_PREG(left)) {
5958 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5959 aopPut(AOP(result),"a",offset);
5961 pic14_emitcode("xrl","%s,a",
5962 aopGet(AOP(left),offset,FALSE,TRUE));
5968 // left & result in different registers
5969 if(AOP_TYPE(result) == AOP_CRY){
5971 // if(size), result in bit
5972 // if(!size && ifx), conditional oper: if(left ^ right)
5973 symbol *tlbl = newiTempLabel(NULL);
5974 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5976 pic14_emitcode("setb","c");
5978 if((AOP_TYPE(right) == AOP_LIT) &&
5979 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5980 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5982 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5983 pic14_emitcode("xrl","a,%s",
5984 aopGet(AOP(left),offset,FALSE,FALSE));
5986 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5991 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5992 pic14_outBitC(result);
5994 jmpTrueOrFalse(ifx, tlbl);
5995 } else for(;(size--);offset++){
5997 // result = left & right
5998 if(AOP_TYPE(right) == AOP_LIT){
5999 int t = (lit >> (offset*8)) & 0x0FFL;
6002 if (AOP_TYPE(left) != AOP_ACC) {
6003 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6005 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6006 pic14_emitcode("movf","%s,w",
6007 aopGet(AOP(left),offset,FALSE,FALSE));
6008 pic14_emitcode("movwf","%s",
6009 aopGet(AOP(result),offset,FALSE,FALSE));
6012 if (AOP_TYPE(left) == AOP_ACC) {
6013 emitpcode(POC_XORLW, popGetLit(t));
6015 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6017 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6020 if (AOP_TYPE(left) == AOP_ACC) {
6021 emitpcode(POC_XORLW, popGetLit(t));
6023 emitpcode(POC_MOVLW, popGetLit(t));
6024 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6026 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6027 pic14_emitcode("movlw","0x%x",t);
6028 pic14_emitcode("xorwf","%s,w",
6029 aopGet(AOP(left),offset,FALSE,FALSE));
6030 pic14_emitcode("movwf","%s",
6031 aopGet(AOP(result),offset,FALSE,FALSE));
6037 // faster than result <- left, anl result,right
6038 // and better if result is SFR
6039 if (AOP_TYPE(left) == AOP_ACC) {
6040 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6041 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6043 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6044 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6045 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6046 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6048 if ( AOP_TYPE(result) != AOP_ACC){
6049 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6050 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6056 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6057 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6058 freeAsmop(result,NULL,ic,TRUE);
6061 /*-----------------------------------------------------------------*/
6062 /* genInline - write the inline code out */
6063 /*-----------------------------------------------------------------*/
6064 static void genInline (iCode *ic)
6066 char *buffer, *bp, *bp1;
6068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6070 _G.inLine += (!options.asmpeep);
6072 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6073 strcpy(buffer,IC_INLINE(ic));
6075 /* emit each line as a code */
6081 addpCode2pBlock(pb,AssembleLine(bp1));
6088 pic14_emitcode(bp1,"");
6094 if ((bp1 != bp) && *bp1)
6095 addpCode2pBlock(pb,AssembleLine(bp1));
6099 _G.inLine -= (!options.asmpeep);
6102 /*-----------------------------------------------------------------*/
6103 /* genRRC - rotate right with carry */
6104 /*-----------------------------------------------------------------*/
6105 static void genRRC (iCode *ic)
6107 operand *left , *result ;
6108 int size, offset = 0, same;
6110 /* rotate right with carry */
6112 result=IC_RESULT(ic);
6113 aopOp (left,ic,FALSE);
6114 aopOp (result,ic,FALSE);
6116 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6118 same = pic14_sameRegs(AOP(result),AOP(left));
6120 size = AOP_SIZE(result);
6122 /* get the lsb and put it into the carry */
6123 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6130 emitpcode(POC_RRF, popGet(AOP(left),offset));
6132 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6133 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6139 freeAsmop(left,NULL,ic,TRUE);
6140 freeAsmop(result,NULL,ic,TRUE);
6143 /*-----------------------------------------------------------------*/
6144 /* genRLC - generate code for rotate left with carry */
6145 /*-----------------------------------------------------------------*/
6146 static void genRLC (iCode *ic)
6148 operand *left , *result ;
6149 int size, offset = 0;
6152 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6153 /* rotate right with carry */
6155 result=IC_RESULT(ic);
6156 aopOp (left,ic,FALSE);
6157 aopOp (result,ic,FALSE);
6159 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6161 same = pic14_sameRegs(AOP(result),AOP(left));
6163 /* move it to the result */
6164 size = AOP_SIZE(result);
6166 /* get the msb and put it into the carry */
6167 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6174 emitpcode(POC_RLF, popGet(AOP(left),offset));
6176 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6177 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6184 freeAsmop(left,NULL,ic,TRUE);
6185 freeAsmop(result,NULL,ic,TRUE);
6188 /*-----------------------------------------------------------------*/
6189 /* genGetHbit - generates code get highest order bit */
6190 /*-----------------------------------------------------------------*/
6191 static void genGetHbit (iCode *ic)
6193 operand *left, *result;
6195 result=IC_RESULT(ic);
6196 aopOp (left,ic,FALSE);
6197 aopOp (result,ic,FALSE);
6199 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6200 /* get the highest order byte into a */
6201 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6202 if(AOP_TYPE(result) == AOP_CRY){
6203 pic14_emitcode("rlc","a");
6204 pic14_outBitC(result);
6207 pic14_emitcode("rl","a");
6208 pic14_emitcode("anl","a,#0x01");
6209 pic14_outAcc(result);
6213 freeAsmop(left,NULL,ic,TRUE);
6214 freeAsmop(result,NULL,ic,TRUE);
6217 /*-----------------------------------------------------------------*/
6218 /* AccRol - rotate left accumulator by known count */
6219 /*-----------------------------------------------------------------*/
6220 static void AccRol (int shCount)
6222 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6223 shCount &= 0x0007; // shCount : 0..7
6228 pic14_emitcode("rl","a");
6231 pic14_emitcode("rl","a");
6232 pic14_emitcode("rl","a");
6235 pic14_emitcode("swap","a");
6236 pic14_emitcode("rr","a");
6239 pic14_emitcode("swap","a");
6242 pic14_emitcode("swap","a");
6243 pic14_emitcode("rl","a");
6246 pic14_emitcode("rr","a");
6247 pic14_emitcode("rr","a");
6250 pic14_emitcode("rr","a");
6255 /*-----------------------------------------------------------------*/
6256 /* AccLsh - left shift accumulator by known count */
6257 /*-----------------------------------------------------------------*/
6258 static void AccLsh (int shCount)
6260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6263 pic14_emitcode("add","a,acc");
6266 pic14_emitcode("add","a,acc");
6267 pic14_emitcode("add","a,acc");
6269 /* rotate left accumulator */
6271 /* and kill the lower order bits */
6272 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6277 /*-----------------------------------------------------------------*/
6278 /* AccRsh - right shift accumulator by known count */
6279 /*-----------------------------------------------------------------*/
6280 static void AccRsh (int shCount)
6282 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6286 pic14_emitcode("rrc","a");
6288 /* rotate right accumulator */
6289 AccRol(8 - shCount);
6290 /* and kill the higher order bits */
6291 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6297 /*-----------------------------------------------------------------*/
6298 /* AccSRsh - signed right shift accumulator by known count */
6299 /*-----------------------------------------------------------------*/
6300 static void AccSRsh (int shCount)
6303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6306 pic14_emitcode("mov","c,acc.7");
6307 pic14_emitcode("rrc","a");
6308 } else if(shCount == 2){
6309 pic14_emitcode("mov","c,acc.7");
6310 pic14_emitcode("rrc","a");
6311 pic14_emitcode("mov","c,acc.7");
6312 pic14_emitcode("rrc","a");
6314 tlbl = newiTempLabel(NULL);
6315 /* rotate right accumulator */
6316 AccRol(8 - shCount);
6317 /* and kill the higher order bits */
6318 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6319 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6320 pic14_emitcode("orl","a,#0x%02x",
6321 (unsigned char)~SRMask[shCount]);
6322 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6327 /*-----------------------------------------------------------------*/
6328 /* shiftR1Left2Result - shift right one byte from left to result */
6329 /*-----------------------------------------------------------------*/
6330 static void shiftR1Left2ResultSigned (operand *left, int offl,
6331 operand *result, int offr,
6336 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6338 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6342 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6344 emitpcode(POC_RRF, popGet(AOP(result),offr));
6346 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6347 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6353 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6355 emitpcode(POC_RRF, popGet(AOP(result),offr));
6357 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6358 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6360 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6361 emitpcode(POC_RRF, popGet(AOP(result),offr));
6367 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6369 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6370 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6373 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6374 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6375 emitpcode(POC_ANDLW, popGetLit(0x1f));
6377 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6378 emitpcode(POC_IORLW, popGetLit(0xe0));
6380 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6384 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6385 emitpcode(POC_ANDLW, popGetLit(0x0f));
6386 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6387 emitpcode(POC_IORLW, popGetLit(0xf0));
6388 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6392 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6394 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6395 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6397 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6398 emitpcode(POC_ANDLW, popGetLit(0x07));
6399 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6400 emitpcode(POC_IORLW, popGetLit(0xf8));
6401 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6406 emitpcode(POC_MOVLW, popGetLit(0x00));
6407 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6408 emitpcode(POC_MOVLW, popGetLit(0xfe));
6409 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6410 emitpcode(POC_IORLW, popGetLit(0x01));
6411 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6413 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6414 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6415 emitpcode(POC_DECF, popGet(AOP(result),offr));
6416 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6417 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6423 emitpcode(POC_MOVLW, popGetLit(0x00));
6424 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6425 emitpcode(POC_MOVLW, popGetLit(0xff));
6426 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6428 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6429 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6430 emitpcode(POC_DECF, popGet(AOP(result),offr));
6438 /*-----------------------------------------------------------------*/
6439 /* shiftR1Left2Result - shift right one byte from left to result */
6440 /*-----------------------------------------------------------------*/
6441 static void shiftR1Left2Result (operand *left, int offl,
6442 operand *result, int offr,
6443 int shCount, int sign)
6447 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6449 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6451 /* Copy the msb into the carry if signed. */
6453 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6463 emitpcode(POC_RRF, popGet(AOP(result),offr));
6465 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6466 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6472 emitpcode(POC_RRF, popGet(AOP(result),offr));
6474 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6475 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6478 emitpcode(POC_RRF, popGet(AOP(result),offr));
6483 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6485 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6486 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6489 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6490 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6491 emitpcode(POC_ANDLW, popGetLit(0x1f));
6492 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6496 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6497 emitpcode(POC_ANDLW, popGetLit(0x0f));
6498 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6502 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6503 emitpcode(POC_ANDLW, popGetLit(0x0f));
6504 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6506 emitpcode(POC_RRF, popGet(AOP(result),offr));
6511 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6512 emitpcode(POC_ANDLW, popGetLit(0x80));
6513 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6514 emitpcode(POC_RLF, popGet(AOP(result),offr));
6515 emitpcode(POC_RLF, popGet(AOP(result),offr));
6520 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6521 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6522 emitpcode(POC_RLF, popGet(AOP(result),offr));
6531 /*-----------------------------------------------------------------*/
6532 /* shiftL1Left2Result - shift left one byte from left to result */
6533 /*-----------------------------------------------------------------*/
6534 static void shiftL1Left2Result (operand *left, int offl,
6535 operand *result, int offr, int shCount)
6540 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6542 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6543 DEBUGpic14_emitcode ("; ***","same = %d",same);
6544 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6546 /* shift left accumulator */
6547 //AccLsh(shCount); // don't comment out just yet...
6548 // aopPut(AOP(result),"a",offr);
6552 /* Shift left 1 bit position */
6553 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6555 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6557 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6558 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6562 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6563 emitpcode(POC_ANDLW,popGetLit(0x7e));
6564 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6565 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6568 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6569 emitpcode(POC_ANDLW,popGetLit(0x3e));
6570 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6571 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6572 emitpcode(POC_RLF, popGet(AOP(result),offr));
6575 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6576 emitpcode(POC_ANDLW, popGetLit(0xf0));
6577 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6580 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6581 emitpcode(POC_ANDLW, popGetLit(0xf0));
6582 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6583 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6586 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6587 emitpcode(POC_ANDLW, popGetLit(0x30));
6588 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6589 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6590 emitpcode(POC_RLF, popGet(AOP(result),offr));
6593 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6594 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6595 emitpcode(POC_RRF, popGet(AOP(result),offr));
6599 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6604 /*-----------------------------------------------------------------*/
6605 /* movLeft2Result - move byte from left to result */
6606 /*-----------------------------------------------------------------*/
6607 static void movLeft2Result (operand *left, int offl,
6608 operand *result, int offr)
6611 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6612 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6613 l = aopGet(AOP(left),offl,FALSE,FALSE);
6615 if (*l == '@' && (IS_AOP_PREG(result))) {
6616 pic14_emitcode("mov","a,%s",l);
6617 aopPut(AOP(result),"a",offr);
6619 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6620 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6625 /*-----------------------------------------------------------------*/
6626 /* shiftL2Left2Result - shift left two bytes from left to result */
6627 /*-----------------------------------------------------------------*/
6628 static void shiftL2Left2Result (operand *left, int offl,
6629 operand *result, int offr, int shCount)
6633 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6635 if(pic14_sameRegs(AOP(result), AOP(left))) {
6643 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6644 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6645 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6649 emitpcode(POC_RLF, popGet(AOP(result),offr));
6650 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6656 emitpcode(POC_MOVLW, popGetLit(0x0f));
6657 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6658 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6659 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6660 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6661 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6662 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6664 emitpcode(POC_RLF, popGet(AOP(result),offr));
6665 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6669 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_RRF, popGet(AOP(result),offr));
6671 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6672 emitpcode(POC_RRF, popGet(AOP(result),offr));
6673 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6674 emitpcode(POC_ANDLW,popGetLit(0xc0));
6675 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6676 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6677 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6678 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6681 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6682 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6683 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6684 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6685 emitpcode(POC_RRF, popGet(AOP(result),offr));
6695 /* note, use a mov/add for the shift since the mov has a
6696 chance of getting optimized out */
6697 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6698 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6699 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6700 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6701 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6705 emitpcode(POC_RLF, popGet(AOP(result),offr));
6706 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6712 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6713 emitpcode(POC_ANDLW, popGetLit(0xF0));
6714 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6715 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6716 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6717 emitpcode(POC_ANDLW, popGetLit(0xF0));
6718 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6719 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6723 emitpcode(POC_RLF, popGet(AOP(result),offr));
6724 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6728 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6729 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6730 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6731 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6733 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6734 emitpcode(POC_RRF, popGet(AOP(result),offr));
6735 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_ANDLW,popGetLit(0xc0));
6737 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6738 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6739 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6740 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6744 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6745 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6747 emitpcode(POC_RRF, popGet(AOP(result),offr));
6752 /*-----------------------------------------------------------------*/
6753 /* shiftR2Left2Result - shift right two bytes from left to result */
6754 /*-----------------------------------------------------------------*/
6755 static void shiftR2Left2Result (operand *left, int offl,
6756 operand *result, int offr,
6757 int shCount, int sign)
6761 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6762 same = pic14_sameRegs(AOP(result), AOP(left));
6764 if(same && ((offl + MSB16) == offr)){
6766 /* don't crash result[offr] */
6767 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6768 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6771 movLeft2Result(left,offl, result, offr);
6772 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6775 /* a:x >> shCount (x = lsb(result))*/
6778 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6780 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6789 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6794 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6795 emitpcode(POC_RRF,popGet(AOP(result),offr));
6797 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6798 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6799 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6800 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6805 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_RRF,popGet(AOP(result),offr));
6816 emitpcode(POC_MOVLW, popGetLit(0xf0));
6817 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6818 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6820 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6821 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6822 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6823 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6825 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6826 emitpcode(POC_ANDLW, popGetLit(0x0f));
6827 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6829 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6830 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6831 emitpcode(POC_ANDLW, popGetLit(0xf0));
6832 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6833 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6837 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6838 emitpcode(POC_RRF, popGet(AOP(result),offr));
6842 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6843 emitpcode(POC_BTFSC,
6844 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6845 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6853 emitpcode(POC_RLF, popGet(AOP(result),offr));
6854 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6856 emitpcode(POC_RLF, popGet(AOP(result),offr));
6857 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6858 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6859 emitpcode(POC_ANDLW,popGetLit(0x03));
6861 emitpcode(POC_BTFSC,
6862 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6863 emitpcode(POC_IORLW,popGetLit(0xfc));
6865 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6866 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6867 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6868 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6870 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6871 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6872 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6873 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6874 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6875 emitpcode(POC_RLF, popGet(AOP(result),offr));
6876 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6877 emitpcode(POC_ANDLW,popGetLit(0x03));
6879 emitpcode(POC_BTFSC,
6880 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6881 emitpcode(POC_IORLW,popGetLit(0xfc));
6883 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6884 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6891 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6892 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6893 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6894 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6897 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6899 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6904 /*-----------------------------------------------------------------*/
6905 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6906 /*-----------------------------------------------------------------*/
6907 static void shiftLLeftOrResult (operand *left, int offl,
6908 operand *result, int offr, int shCount)
6910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6911 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6912 /* shift left accumulator */
6914 /* or with result */
6915 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6916 /* back to result */
6917 aopPut(AOP(result),"a",offr);
6920 /*-----------------------------------------------------------------*/
6921 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6922 /*-----------------------------------------------------------------*/
6923 static void shiftRLeftOrResult (operand *left, int offl,
6924 operand *result, int offr, int shCount)
6926 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6927 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6928 /* shift right accumulator */
6930 /* or with result */
6931 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6932 /* back to result */
6933 aopPut(AOP(result),"a",offr);
6936 /*-----------------------------------------------------------------*/
6937 /* genlshOne - left shift a one byte quantity by known count */
6938 /*-----------------------------------------------------------------*/
6939 static void genlshOne (operand *result, operand *left, int shCount)
6941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6942 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6945 /*-----------------------------------------------------------------*/
6946 /* genlshTwo - left shift two bytes by known amount != 0 */
6947 /*-----------------------------------------------------------------*/
6948 static void genlshTwo (operand *result,operand *left, int shCount)
6952 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6953 size = pic14_getDataSize(result);
6955 /* if shCount >= 8 */
6961 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6963 movLeft2Result(left, LSB, result, MSB16);
6965 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6968 /* 1 <= shCount <= 7 */
6971 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6973 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6977 /*-----------------------------------------------------------------*/
6978 /* shiftLLong - shift left one long from left to result */
6979 /* offl = LSB or MSB16 */
6980 /*-----------------------------------------------------------------*/
6981 static void shiftLLong (operand *left, operand *result, int offr )
6984 int size = AOP_SIZE(result);
6986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6987 if(size >= LSB+offr){
6988 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6990 pic14_emitcode("add","a,acc");
6991 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6992 size >= MSB16+offr && offr != LSB )
6993 pic14_emitcode("xch","a,%s",
6994 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6996 aopPut(AOP(result),"a",LSB+offr);
6999 if(size >= MSB16+offr){
7000 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7001 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7004 pic14_emitcode("rlc","a");
7005 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7006 size >= MSB24+offr && offr != LSB)
7007 pic14_emitcode("xch","a,%s",
7008 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7010 aopPut(AOP(result),"a",MSB16+offr);
7013 if(size >= MSB24+offr){
7014 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7015 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7018 pic14_emitcode("rlc","a");
7019 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7020 size >= MSB32+offr && offr != LSB )
7021 pic14_emitcode("xch","a,%s",
7022 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7024 aopPut(AOP(result),"a",MSB24+offr);
7027 if(size > MSB32+offr){
7028 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7029 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7032 pic14_emitcode("rlc","a");
7033 aopPut(AOP(result),"a",MSB32+offr);
7036 aopPut(AOP(result),zero,LSB);
7039 /*-----------------------------------------------------------------*/
7040 /* genlshFour - shift four byte by a known amount != 0 */
7041 /*-----------------------------------------------------------------*/
7042 static void genlshFour (operand *result, operand *left, int shCount)
7046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7047 size = AOP_SIZE(result);
7049 /* if shifting more that 3 bytes */
7050 if (shCount >= 24 ) {
7053 /* lowest order of left goes to the highest
7054 order of the destination */
7055 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7057 movLeft2Result(left, LSB, result, MSB32);
7058 aopPut(AOP(result),zero,LSB);
7059 aopPut(AOP(result),zero,MSB16);
7060 aopPut(AOP(result),zero,MSB32);
7064 /* more than two bytes */
7065 else if ( shCount >= 16 ) {
7066 /* lower order two bytes goes to higher order two bytes */
7068 /* if some more remaining */
7070 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7072 movLeft2Result(left, MSB16, result, MSB32);
7073 movLeft2Result(left, LSB, result, MSB24);
7075 aopPut(AOP(result),zero,MSB16);
7076 aopPut(AOP(result),zero,LSB);
7080 /* if more than 1 byte */
7081 else if ( shCount >= 8 ) {
7082 /* lower order three bytes goes to higher order three bytes */
7086 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7088 movLeft2Result(left, LSB, result, MSB16);
7090 else{ /* size = 4 */
7092 movLeft2Result(left, MSB24, result, MSB32);
7093 movLeft2Result(left, MSB16, result, MSB24);
7094 movLeft2Result(left, LSB, result, MSB16);
7095 aopPut(AOP(result),zero,LSB);
7097 else if(shCount == 1)
7098 shiftLLong(left, result, MSB16);
7100 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7101 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7102 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7103 aopPut(AOP(result),zero,LSB);
7108 /* 1 <= shCount <= 7 */
7109 else if(shCount <= 2){
7110 shiftLLong(left, result, LSB);
7112 shiftLLong(result, result, LSB);
7114 /* 3 <= shCount <= 7, optimize */
7116 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7117 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7118 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7122 /*-----------------------------------------------------------------*/
7123 /* genLeftShiftLiteral - left shifting by known count */
7124 /*-----------------------------------------------------------------*/
7125 static void genLeftShiftLiteral (operand *left,
7130 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7134 freeAsmop(right,NULL,ic,TRUE);
7136 aopOp(left,ic,FALSE);
7137 aopOp(result,ic,FALSE);
7139 size = getSize(operandType(result));
7142 pic14_emitcode("; shift left ","result %d, left %d",size,
7146 /* I suppose that the left size >= result size */
7149 movLeft2Result(left, size, result, size);
7153 else if(shCount >= (size * 8))
7155 aopPut(AOP(result),zero,size);
7159 genlshOne (result,left,shCount);
7164 genlshTwo (result,left,shCount);
7168 genlshFour (result,left,shCount);
7172 freeAsmop(left,NULL,ic,TRUE);
7173 freeAsmop(result,NULL,ic,TRUE);
7176 /*-----------------------------------------------------------------*
7177 * genMultiAsm - repeat assembly instruction for size of register.
7178 * if endian == 1, then the high byte (i.e base address + size of
7179 * register) is used first else the low byte is used first;
7180 *-----------------------------------------------------------------*/
7181 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7186 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7199 emitpcode(poc, popGet(AOP(reg),offset));
7204 /*-----------------------------------------------------------------*/
7205 /* genLeftShift - generates code for left shifting */
7206 /*-----------------------------------------------------------------*/
7207 static void genLeftShift (iCode *ic)
7209 operand *left,*right, *result;
7212 symbol *tlbl , *tlbl1;
7215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7217 right = IC_RIGHT(ic);
7219 result = IC_RESULT(ic);
7221 aopOp(right,ic,FALSE);
7223 /* if the shift count is known then do it
7224 as efficiently as possible */
7225 if (AOP_TYPE(right) == AOP_LIT) {
7226 genLeftShiftLiteral (left,right,result,ic);
7230 /* shift count is unknown then we have to form
7231 a loop get the loop count in B : Note: we take
7232 only the lower order byte since shifting
7233 more that 32 bits make no sense anyway, ( the
7234 largest size of an object can be only 32 bits ) */
7237 aopOp(left,ic,FALSE);
7238 aopOp(result,ic,FALSE);
7240 /* now move the left to the result if they are not the
7242 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7243 AOP_SIZE(result) > 1) {
7245 size = AOP_SIZE(result);
7248 l = aopGet(AOP(left),offset,FALSE,TRUE);
7249 if (*l == '@' && (IS_AOP_PREG(result))) {
7251 pic14_emitcode("mov","a,%s",l);
7252 aopPut(AOP(result),"a",offset);
7254 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7255 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7256 //aopPut(AOP(result),l,offset);
7262 size = AOP_SIZE(result);
7264 /* if it is only one byte then */
7266 if(optimized_for_speed) {
7267 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7268 emitpcode(POC_ANDLW, popGetLit(0xf0));
7269 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7270 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7271 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7272 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7273 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7274 emitpcode(POC_RLFW, popGet(AOP(result),0));
7275 emitpcode(POC_ANDLW, popGetLit(0xfe));
7276 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7277 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7278 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7281 tlbl = newiTempLabel(NULL);
7282 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7283 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7284 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7287 emitpcode(POC_COMFW, popGet(AOP(right),0));
7288 emitpcode(POC_RRF, popGet(AOP(result),0));
7289 emitpLabel(tlbl->key);
7290 emitpcode(POC_RLF, popGet(AOP(result),0));
7291 emitpcode(POC_ADDLW, popGetLit(1));
7293 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7298 if (pic14_sameRegs(AOP(left),AOP(result))) {
7300 tlbl = newiTempLabel(NULL);
7301 emitpcode(POC_COMFW, popGet(AOP(right),0));
7302 genMultiAsm(POC_RRF, result, size,1);
7303 emitpLabel(tlbl->key);
7304 genMultiAsm(POC_RLF, result, size,0);
7305 emitpcode(POC_ADDLW, popGetLit(1));
7307 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7311 //tlbl = newiTempLabel(NULL);
7313 //tlbl1 = newiTempLabel(NULL);
7315 //reAdjustPreg(AOP(result));
7317 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7318 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7319 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7321 //pic14_emitcode("add","a,acc");
7322 //aopPut(AOP(result),"a",offset++);
7324 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7326 // pic14_emitcode("rlc","a");
7327 // aopPut(AOP(result),"a",offset++);
7329 //reAdjustPreg(AOP(result));
7331 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7332 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7335 tlbl = newiTempLabel(NULL);
7336 tlbl1= newiTempLabel(NULL);
7338 size = AOP_SIZE(result);
7341 pctemp = popGetTempReg(); /* grab a temporary working register. */
7343 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7345 /* offset should be 0, 1 or 3 */
7346 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7348 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7350 emitpcode(POC_MOVWF, pctemp);
7353 emitpLabel(tlbl->key);
7356 emitpcode(POC_RLF, popGet(AOP(result),0));
7358 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7360 emitpcode(POC_DECFSZ, pctemp);
7361 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7362 emitpLabel(tlbl1->key);
7364 popReleaseTempReg(pctemp);
7368 freeAsmop (right,NULL,ic,TRUE);
7369 freeAsmop(left,NULL,ic,TRUE);
7370 freeAsmop(result,NULL,ic,TRUE);
7373 /*-----------------------------------------------------------------*/
7374 /* genrshOne - right shift a one byte quantity by known count */
7375 /*-----------------------------------------------------------------*/
7376 static void genrshOne (operand *result, operand *left,
7377 int shCount, int sign)
7379 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7380 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7383 /*-----------------------------------------------------------------*/
7384 /* genrshTwo - right shift two bytes by known amount != 0 */
7385 /*-----------------------------------------------------------------*/
7386 static void genrshTwo (operand *result,operand *left,
7387 int shCount, int sign)
7389 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7390 /* if shCount >= 8 */
7394 shiftR1Left2Result(left, MSB16, result, LSB,
7397 movLeft2Result(left, MSB16, result, LSB);
7399 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7402 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7403 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7407 /* 1 <= shCount <= 7 */
7409 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7412 /*-----------------------------------------------------------------*/
7413 /* shiftRLong - shift right one long from left to result */
7414 /* offl = LSB or MSB16 */
7415 /*-----------------------------------------------------------------*/
7416 static void shiftRLong (operand *left, int offl,
7417 operand *result, int sign)
7419 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7421 pic14_emitcode("clr","c");
7422 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7424 pic14_emitcode("mov","c,acc.7");
7425 pic14_emitcode("rrc","a");
7426 aopPut(AOP(result),"a",MSB32-offl);
7428 /* add sign of "a" */
7429 addSign(result, MSB32, sign);
7431 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7432 pic14_emitcode("rrc","a");
7433 aopPut(AOP(result),"a",MSB24-offl);
7435 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7436 pic14_emitcode("rrc","a");
7437 aopPut(AOP(result),"a",MSB16-offl);
7440 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7441 pic14_emitcode("rrc","a");
7442 aopPut(AOP(result),"a",LSB);
7446 /*-----------------------------------------------------------------*/
7447 /* genrshFour - shift four byte by a known amount != 0 */
7448 /*-----------------------------------------------------------------*/
7449 static void genrshFour (operand *result, operand *left,
7450 int shCount, int sign)
7452 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7453 /* if shifting more that 3 bytes */
7454 if(shCount >= 24 ) {
7457 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7459 movLeft2Result(left, MSB32, result, LSB);
7461 addSign(result, MSB16, sign);
7463 else if(shCount >= 16){
7466 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7468 movLeft2Result(left, MSB24, result, LSB);
7469 movLeft2Result(left, MSB32, result, MSB16);
7471 addSign(result, MSB24, sign);
7473 else if(shCount >= 8){
7476 shiftRLong(left, MSB16, result, sign);
7477 else if(shCount == 0){
7478 movLeft2Result(left, MSB16, result, LSB);
7479 movLeft2Result(left, MSB24, result, MSB16);
7480 movLeft2Result(left, MSB32, result, MSB24);
7481 addSign(result, MSB32, sign);
7484 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7485 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7486 /* the last shift is signed */
7487 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7488 addSign(result, MSB32, sign);
7491 else{ /* 1 <= shCount <= 7 */
7493 shiftRLong(left, LSB, result, sign);
7495 shiftRLong(result, LSB, result, sign);
7498 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7499 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7500 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7505 /*-----------------------------------------------------------------*/
7506 /* genRightShiftLiteral - right shifting by known count */
7507 /*-----------------------------------------------------------------*/
7508 static void genRightShiftLiteral (operand *left,
7514 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7517 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7518 freeAsmop(right,NULL,ic,TRUE);
7520 aopOp(left,ic,FALSE);
7521 aopOp(result,ic,FALSE);
7524 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7528 lsize = pic14_getDataSize(left);
7529 res_size = pic14_getDataSize(result);
7530 /* test the LEFT size !!! */
7532 /* I suppose that the left size >= result size */
7535 movLeft2Result(left, lsize, result, res_size);
7538 else if(shCount >= (lsize * 8)){
7541 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7543 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7544 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7549 emitpcode(POC_MOVLW, popGetLit(0));
7550 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7551 emitpcode(POC_MOVLW, popGetLit(0xff));
7553 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7558 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7565 genrshOne (result,left,shCount,sign);
7569 genrshTwo (result,left,shCount,sign);
7573 genrshFour (result,left,shCount,sign);
7581 freeAsmop(left,NULL,ic,TRUE);
7582 freeAsmop(result,NULL,ic,TRUE);
7585 /*-----------------------------------------------------------------*/
7586 /* genSignedRightShift - right shift of signed number */
7587 /*-----------------------------------------------------------------*/
7588 static void genSignedRightShift (iCode *ic)
7590 operand *right, *left, *result;
7593 symbol *tlbl, *tlbl1 ;
7596 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7598 /* we do it the hard way put the shift count in b
7599 and loop thru preserving the sign */
7600 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7602 right = IC_RIGHT(ic);
7604 result = IC_RESULT(ic);
7606 aopOp(right,ic,FALSE);
7607 aopOp(left,ic,FALSE);
7608 aopOp(result,ic,FALSE);
7611 if ( AOP_TYPE(right) == AOP_LIT) {
7612 genRightShiftLiteral (left,right,result,ic,1);
7615 /* shift count is unknown then we have to form
7616 a loop get the loop count in B : Note: we take
7617 only the lower order byte since shifting
7618 more that 32 bits make no sense anyway, ( the
7619 largest size of an object can be only 32 bits ) */
7621 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7622 //pic14_emitcode("inc","b");
7623 //freeAsmop (right,NULL,ic,TRUE);
7624 //aopOp(left,ic,FALSE);
7625 //aopOp(result,ic,FALSE);
7627 /* now move the left to the result if they are not the
7629 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7630 AOP_SIZE(result) > 1) {
7632 size = AOP_SIZE(result);
7636 l = aopGet(AOP(left),offset,FALSE,TRUE);
7637 if (*l == '@' && IS_AOP_PREG(result)) {
7639 pic14_emitcode("mov","a,%s",l);
7640 aopPut(AOP(result),"a",offset);
7642 aopPut(AOP(result),l,offset);
7644 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7645 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7651 /* mov the highest order bit to OVR */
7652 tlbl = newiTempLabel(NULL);
7653 tlbl1= newiTempLabel(NULL);
7655 size = AOP_SIZE(result);
7658 pctemp = popGetTempReg(); /* grab a temporary working register. */
7660 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7662 /* offset should be 0, 1 or 3 */
7663 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7665 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7667 emitpcode(POC_MOVWF, pctemp);
7670 emitpLabel(tlbl->key);
7672 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7673 emitpcode(POC_RRF, popGet(AOP(result),offset));
7676 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7679 emitpcode(POC_DECFSZ, pctemp);
7680 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7681 emitpLabel(tlbl1->key);
7683 popReleaseTempReg(pctemp);
7685 size = AOP_SIZE(result);
7687 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7688 pic14_emitcode("rlc","a");
7689 pic14_emitcode("mov","ov,c");
7690 /* if it is only one byte then */
7692 l = aopGet(AOP(left),0,FALSE,FALSE);
7694 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7695 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7696 pic14_emitcode("mov","c,ov");
7697 pic14_emitcode("rrc","a");
7698 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7699 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7700 aopPut(AOP(result),"a",0);
7704 reAdjustPreg(AOP(result));
7705 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7706 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7707 pic14_emitcode("mov","c,ov");
7709 l = aopGet(AOP(result),offset,FALSE,FALSE);
7711 pic14_emitcode("rrc","a");
7712 aopPut(AOP(result),"a",offset--);
7714 reAdjustPreg(AOP(result));
7715 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7716 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7721 freeAsmop(left,NULL,ic,TRUE);
7722 freeAsmop(result,NULL,ic,TRUE);
7723 freeAsmop(right,NULL,ic,TRUE);
7726 /*-----------------------------------------------------------------*/
7727 /* genRightShift - generate code for right shifting */
7728 /*-----------------------------------------------------------------*/
7729 static void genRightShift (iCode *ic)
7731 operand *right, *left, *result;
7735 symbol *tlbl, *tlbl1 ;
7737 /* if signed then we do it the hard way preserve the
7738 sign bit moving it inwards */
7739 retype = getSpec(operandType(IC_RESULT(ic)));
7740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7742 if (!SPEC_USIGN(retype)) {
7743 genSignedRightShift (ic);
7747 /* signed & unsigned types are treated the same : i.e. the
7748 signed is NOT propagated inwards : quoting from the
7749 ANSI - standard : "for E1 >> E2, is equivalent to division
7750 by 2**E2 if unsigned or if it has a non-negative value,
7751 otherwise the result is implementation defined ", MY definition
7752 is that the sign does not get propagated */
7754 right = IC_RIGHT(ic);
7756 result = IC_RESULT(ic);
7758 aopOp(right,ic,FALSE);
7760 /* if the shift count is known then do it
7761 as efficiently as possible */
7762 if (AOP_TYPE(right) == AOP_LIT) {
7763 genRightShiftLiteral (left,right,result,ic, 0);
7767 /* shift count is unknown then we have to form
7768 a loop get the loop count in B : Note: we take
7769 only the lower order byte since shifting
7770 more that 32 bits make no sense anyway, ( the
7771 largest size of an object can be only 32 bits ) */
7773 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7774 pic14_emitcode("inc","b");
7775 aopOp(left,ic,FALSE);
7776 aopOp(result,ic,FALSE);
7778 /* now move the left to the result if they are not the
7780 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7781 AOP_SIZE(result) > 1) {
7783 size = AOP_SIZE(result);
7786 l = aopGet(AOP(left),offset,FALSE,TRUE);
7787 if (*l == '@' && IS_AOP_PREG(result)) {
7789 pic14_emitcode("mov","a,%s",l);
7790 aopPut(AOP(result),"a",offset);
7792 aopPut(AOP(result),l,offset);
7797 tlbl = newiTempLabel(NULL);
7798 tlbl1= newiTempLabel(NULL);
7799 size = AOP_SIZE(result);
7802 /* if it is only one byte then */
7805 tlbl = newiTempLabel(NULL);
7806 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7807 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7808 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7811 emitpcode(POC_COMFW, popGet(AOP(right),0));
7812 emitpcode(POC_RLF, popGet(AOP(result),0));
7813 emitpLabel(tlbl->key);
7814 emitpcode(POC_RRF, popGet(AOP(result),0));
7815 emitpcode(POC_ADDLW, popGetLit(1));
7817 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7822 reAdjustPreg(AOP(result));
7823 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7824 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7827 l = aopGet(AOP(result),offset,FALSE,FALSE);
7829 pic14_emitcode("rrc","a");
7830 aopPut(AOP(result),"a",offset--);
7832 reAdjustPreg(AOP(result));
7834 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7835 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7838 freeAsmop(left,NULL,ic,TRUE);
7839 freeAsmop (right,NULL,ic,TRUE);
7840 freeAsmop(result,NULL,ic,TRUE);
7843 /*-----------------------------------------------------------------*/
7844 /* genUnpackBits - generates code for unpacking bits */
7845 /*-----------------------------------------------------------------*/
7846 static void genUnpackBits (operand *result, char *rname, int ptype)
7853 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7854 etype = getSpec(operandType(result));
7856 /* read the first byte */
7861 pic14_emitcode("mov","a,@%s",rname);
7865 pic14_emitcode("movx","a,@%s",rname);
7869 pic14_emitcode("movx","a,@dptr");
7873 pic14_emitcode("clr","a");
7874 pic14_emitcode("movc","a","@a+dptr");
7878 pic14_emitcode("lcall","__gptrget");
7882 /* if we have bitdisplacement then it fits */
7883 /* into this byte completely or if length is */
7884 /* less than a byte */
7885 if ((shCnt = SPEC_BSTR(etype)) ||
7886 (SPEC_BLEN(etype) <= 8)) {
7888 /* shift right acc */
7891 pic14_emitcode("anl","a,#0x%02x",
7892 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7893 aopPut(AOP(result),"a",offset);
7897 /* bit field did not fit in a byte */
7898 rlen = SPEC_BLEN(etype) - 8;
7899 aopPut(AOP(result),"a",offset++);
7906 pic14_emitcode("inc","%s",rname);
7907 pic14_emitcode("mov","a,@%s",rname);
7911 pic14_emitcode("inc","%s",rname);
7912 pic14_emitcode("movx","a,@%s",rname);
7916 pic14_emitcode("inc","dptr");
7917 pic14_emitcode("movx","a,@dptr");
7921 pic14_emitcode("clr","a");
7922 pic14_emitcode("inc","dptr");
7923 pic14_emitcode("movc","a","@a+dptr");
7927 pic14_emitcode("inc","dptr");
7928 pic14_emitcode("lcall","__gptrget");
7933 /* if we are done */
7937 aopPut(AOP(result),"a",offset++);
7942 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7943 aopPut(AOP(result),"a",offset);
7950 /*-----------------------------------------------------------------*/
7951 /* genDataPointerGet - generates code when ptr offset is known */
7952 /*-----------------------------------------------------------------*/
7953 static void genDataPointerGet (operand *left,
7957 int size , offset = 0;
7960 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7963 /* optimization - most of the time, left and result are the same
7964 * address, but different types. for the pic code, we could omit
7968 aopOp(result,ic,TRUE);
7970 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7972 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7974 size = AOP_SIZE(result);
7977 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7981 freeAsmop(left,NULL,ic,TRUE);
7982 freeAsmop(result,NULL,ic,TRUE);
7985 /*-----------------------------------------------------------------*/
7986 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7987 /*-----------------------------------------------------------------*/
7988 static void genNearPointerGet (operand *left,
7993 //regs *preg = NULL ;
7995 sym_link *rtype, *retype;
7996 sym_link *ltype = operandType(left);
7999 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8001 rtype = operandType(result);
8002 retype= getSpec(rtype);
8004 aopOp(left,ic,FALSE);
8006 /* if left is rematerialisable and
8007 result is not bit variable type and
8008 the left is pointer to data space i.e
8009 lower 128 bytes of space */
8010 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8011 !IS_BITVAR(retype) &&
8012 DCL_TYPE(ltype) == POINTER) {
8013 //genDataPointerGet (left,result,ic);
8017 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8019 /* if the value is already in a pointer register
8020 then don't need anything more */
8021 if (!AOP_INPREG(AOP(left))) {
8022 /* otherwise get a free pointer register */
8023 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8026 preg = getFreePtr(ic,&aop,FALSE);
8027 pic14_emitcode("mov","%s,%s",
8029 aopGet(AOP(left),0,FALSE,TRUE));
8030 rname = preg->name ;
8034 rname = aopGet(AOP(left),0,FALSE,FALSE);
8036 aopOp (result,ic,FALSE);
8038 /* if bitfield then unpack the bits */
8039 if (IS_BITVAR(retype))
8040 genUnpackBits (result,rname,POINTER);
8042 /* we have can just get the values */
8043 int size = AOP_SIZE(result);
8046 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8048 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8049 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8051 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8052 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8054 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8058 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8060 pic14_emitcode("mov","a,@%s",rname);
8061 aopPut(AOP(result),"a",offset);
8063 sprintf(buffer,"@%s",rname);
8064 aopPut(AOP(result),buffer,offset);
8068 pic14_emitcode("inc","%s",rname);
8073 /* now some housekeeping stuff */
8075 /* we had to allocate for this iCode */
8076 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8077 freeAsmop(NULL,aop,ic,TRUE);
8079 /* we did not allocate which means left
8080 already in a pointer register, then
8081 if size > 0 && this could be used again
8082 we have to point it back to where it
8084 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8085 if (AOP_SIZE(result) > 1 &&
8086 !OP_SYMBOL(left)->remat &&
8087 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8089 int size = AOP_SIZE(result) - 1;
8091 pic14_emitcode("dec","%s",rname);
8096 freeAsmop(left,NULL,ic,TRUE);
8097 freeAsmop(result,NULL,ic,TRUE);
8101 /*-----------------------------------------------------------------*/
8102 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8103 /*-----------------------------------------------------------------*/
8104 static void genPagedPointerGet (operand *left,
8111 sym_link *rtype, *retype;
8113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8115 rtype = operandType(result);
8116 retype= getSpec(rtype);
8118 aopOp(left,ic,FALSE);
8120 /* if the value is already in a pointer register
8121 then don't need anything more */
8122 if (!AOP_INPREG(AOP(left))) {
8123 /* otherwise get a free pointer register */
8125 preg = getFreePtr(ic,&aop,FALSE);
8126 pic14_emitcode("mov","%s,%s",
8128 aopGet(AOP(left),0,FALSE,TRUE));
8129 rname = preg->name ;
8131 rname = aopGet(AOP(left),0,FALSE,FALSE);
8133 freeAsmop(left,NULL,ic,TRUE);
8134 aopOp (result,ic,FALSE);
8136 /* if bitfield then unpack the bits */
8137 if (IS_BITVAR(retype))
8138 genUnpackBits (result,rname,PPOINTER);
8140 /* we have can just get the values */
8141 int size = AOP_SIZE(result);
8146 pic14_emitcode("movx","a,@%s",rname);
8147 aopPut(AOP(result),"a",offset);
8152 pic14_emitcode("inc","%s",rname);
8156 /* now some housekeeping stuff */
8158 /* we had to allocate for this iCode */
8159 freeAsmop(NULL,aop,ic,TRUE);
8161 /* we did not allocate which means left
8162 already in a pointer register, then
8163 if size > 0 && this could be used again
8164 we have to point it back to where it
8166 if (AOP_SIZE(result) > 1 &&
8167 !OP_SYMBOL(left)->remat &&
8168 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8170 int size = AOP_SIZE(result) - 1;
8172 pic14_emitcode("dec","%s",rname);
8177 freeAsmop(result,NULL,ic,TRUE);
8182 /*-----------------------------------------------------------------*/
8183 /* genFarPointerGet - gget value from far space */
8184 /*-----------------------------------------------------------------*/
8185 static void genFarPointerGet (operand *left,
8186 operand *result, iCode *ic)
8189 sym_link *retype = getSpec(operandType(result));
8191 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8193 aopOp(left,ic,FALSE);
8195 /* if the operand is already in dptr
8196 then we do nothing else we move the value to dptr */
8197 if (AOP_TYPE(left) != AOP_STR) {
8198 /* if this is remateriazable */
8199 if (AOP_TYPE(left) == AOP_IMMD)
8200 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8201 else { /* we need to get it byte by byte */
8202 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8203 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8204 if (options.model == MODEL_FLAT24)
8206 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8210 /* so dptr know contains the address */
8211 freeAsmop(left,NULL,ic,TRUE);
8212 aopOp(result,ic,FALSE);
8214 /* if bit then unpack */
8215 if (IS_BITVAR(retype))
8216 genUnpackBits(result,"dptr",FPOINTER);
8218 size = AOP_SIZE(result);
8222 pic14_emitcode("movx","a,@dptr");
8223 aopPut(AOP(result),"a",offset++);
8225 pic14_emitcode("inc","dptr");
8229 freeAsmop(result,NULL,ic,TRUE);
8232 /*-----------------------------------------------------------------*/
8233 /* genCodePointerGet - get value from code space */
8234 /*-----------------------------------------------------------------*/
8235 static void genCodePointerGet (operand *left,
8236 operand *result, iCode *ic)
8239 sym_link *retype = getSpec(operandType(result));
8241 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8243 aopOp(left,ic,FALSE);
8245 /* if the operand is already in dptr
8246 then we do nothing else we move the value to dptr */
8247 if (AOP_TYPE(left) != AOP_STR) {
8248 /* if this is remateriazable */
8249 if (AOP_TYPE(left) == AOP_IMMD)
8250 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8251 else { /* we need to get it byte by byte */
8252 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8253 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8254 if (options.model == MODEL_FLAT24)
8256 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8260 /* so dptr know contains the address */
8261 freeAsmop(left,NULL,ic,TRUE);
8262 aopOp(result,ic,FALSE);
8264 /* if bit then unpack */
8265 if (IS_BITVAR(retype))
8266 genUnpackBits(result,"dptr",CPOINTER);
8268 size = AOP_SIZE(result);
8272 pic14_emitcode("clr","a");
8273 pic14_emitcode("movc","a,@a+dptr");
8274 aopPut(AOP(result),"a",offset++);
8276 pic14_emitcode("inc","dptr");
8280 freeAsmop(result,NULL,ic,TRUE);
8283 /*-----------------------------------------------------------------*/
8284 /* genGenPointerGet - gget value from generic pointer space */
8285 /*-----------------------------------------------------------------*/
8286 static void genGenPointerGet (operand *left,
8287 operand *result, iCode *ic)
8290 sym_link *retype = getSpec(operandType(result));
8292 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8293 aopOp(left,ic,FALSE);
8294 aopOp(result,ic,FALSE);
8297 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8299 /* if the operand is already in dptr
8300 then we do nothing else we move the value to dptr */
8301 // if (AOP_TYPE(left) != AOP_STR) {
8302 /* if this is remateriazable */
8303 if (AOP_TYPE(left) == AOP_IMMD) {
8304 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8305 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8307 else { /* we need to get it byte by byte */
8309 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8310 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8312 size = AOP_SIZE(result);
8316 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8317 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8319 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8324 /* so dptr know contains the address */
8326 /* if bit then unpack */
8327 //if (IS_BITVAR(retype))
8328 // genUnpackBits(result,"dptr",GPOINTER);
8331 freeAsmop(left,NULL,ic,TRUE);
8332 freeAsmop(result,NULL,ic,TRUE);
8336 /*-----------------------------------------------------------------*/
8337 /* genConstPointerGet - get value from const generic pointer space */
8338 /*-----------------------------------------------------------------*/
8339 static void genConstPointerGet (operand *left,
8340 operand *result, iCode *ic)
8342 //sym_link *retype = getSpec(operandType(result));
8343 symbol *albl = newiTempLabel(NULL);
8344 symbol *blbl = newiTempLabel(NULL);
8347 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8348 aopOp(left,ic,FALSE);
8349 aopOp(result,ic,FALSE);
8352 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8354 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8356 emitpcode(POC_CALL,popGetLabel(albl->key));
8357 emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
8358 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8359 emitpLabel(albl->key);
8361 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8363 emitpcode(poc,popGet(AOP(left),1));
8364 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8365 emitpcode(poc,popGet(AOP(left),0));
8366 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8368 emitpLabel(blbl->key);
8370 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8373 freeAsmop(left,NULL,ic,TRUE);
8374 freeAsmop(result,NULL,ic,TRUE);
8377 /*-----------------------------------------------------------------*/
8378 /* genPointerGet - generate code for pointer get */
8379 /*-----------------------------------------------------------------*/
8380 static void genPointerGet (iCode *ic)
8382 operand *left, *result ;
8383 sym_link *type, *etype;
8386 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8389 result = IC_RESULT(ic) ;
8391 /* depending on the type of pointer we need to
8392 move it to the correct pointer register */
8393 type = operandType(left);
8394 etype = getSpec(type);
8396 if (IS_PTR_CONST(type))
8397 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8399 /* if left is of type of pointer then it is simple */
8400 if (IS_PTR(type) && !IS_FUNC(type->next))
8401 p_type = DCL_TYPE(type);
8403 /* we have to go by the storage class */
8404 p_type = PTR_TYPE(SPEC_OCLS(etype));
8406 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8408 if (SPEC_OCLS(etype)->codesp ) {
8409 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8410 //p_type = CPOINTER ;
8413 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8414 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8415 /*p_type = FPOINTER ;*/
8417 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8418 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8419 /* p_type = PPOINTER; */
8421 if (SPEC_OCLS(etype) == idata )
8422 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8423 /* p_type = IPOINTER; */
8425 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8426 /* p_type = POINTER ; */
8429 /* now that we have the pointer type we assign
8430 the pointer values */
8435 genNearPointerGet (left,result,ic);
8439 genPagedPointerGet(left,result,ic);
8443 genFarPointerGet (left,result,ic);
8447 genConstPointerGet (left,result,ic);
8448 //pic14_emitcodePointerGet (left,result,ic);
8452 if (IS_PTR_CONST(type))
8453 genConstPointerGet (left,result,ic);
8455 genGenPointerGet (left,result,ic);
8461 /*-----------------------------------------------------------------*/
8462 /* genPackBits - generates code for packed bit storage */
8463 /*-----------------------------------------------------------------*/
8464 static void genPackBits (sym_link *etype ,
8466 char *rname, int p_type)
8474 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8475 blen = SPEC_BLEN(etype);
8476 bstr = SPEC_BSTR(etype);
8478 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8481 /* if the bit lenth is less than or */
8482 /* it exactly fits a byte then */
8483 if (SPEC_BLEN(etype) <= 8 ) {
8484 shCount = SPEC_BSTR(etype) ;
8486 /* shift left acc */
8489 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8494 pic14_emitcode ("mov","b,a");
8495 pic14_emitcode("mov","a,@%s",rname);
8499 pic14_emitcode ("mov","b,a");
8500 pic14_emitcode("movx","a,@dptr");
8504 pic14_emitcode ("push","b");
8505 pic14_emitcode ("push","acc");
8506 pic14_emitcode ("lcall","__gptrget");
8507 pic14_emitcode ("pop","b");
8511 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8512 ((unsigned char)(0xFF << (blen+bstr)) |
8513 (unsigned char)(0xFF >> (8-bstr)) ) );
8514 pic14_emitcode ("orl","a,b");
8515 if (p_type == GPOINTER)
8516 pic14_emitcode("pop","b");
8522 pic14_emitcode("mov","@%s,a",rname);
8526 pic14_emitcode("movx","@dptr,a");
8530 DEBUGpic14_emitcode(";lcall","__gptrput");
8535 if ( SPEC_BLEN(etype) <= 8 )
8538 pic14_emitcode("inc","%s",rname);
8539 rLen = SPEC_BLEN(etype) ;
8541 /* now generate for lengths greater than one byte */
8544 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8554 pic14_emitcode("mov","@%s,a",rname);
8556 pic14_emitcode("mov","@%s,%s",rname,l);
8561 pic14_emitcode("movx","@dptr,a");
8566 DEBUGpic14_emitcode(";lcall","__gptrput");
8569 pic14_emitcode ("inc","%s",rname);
8574 /* last last was not complete */
8576 /* save the byte & read byte */
8579 pic14_emitcode ("mov","b,a");
8580 pic14_emitcode("mov","a,@%s",rname);
8584 pic14_emitcode ("mov","b,a");
8585 pic14_emitcode("movx","a,@dptr");
8589 pic14_emitcode ("push","b");
8590 pic14_emitcode ("push","acc");
8591 pic14_emitcode ("lcall","__gptrget");
8592 pic14_emitcode ("pop","b");
8596 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8597 pic14_emitcode ("orl","a,b");
8600 if (p_type == GPOINTER)
8601 pic14_emitcode("pop","b");
8606 pic14_emitcode("mov","@%s,a",rname);
8610 pic14_emitcode("movx","@dptr,a");
8614 DEBUGpic14_emitcode(";lcall","__gptrput");
8618 /*-----------------------------------------------------------------*/
8619 /* genDataPointerSet - remat pointer to data space */
8620 /*-----------------------------------------------------------------*/
8621 static void genDataPointerSet(operand *right,
8625 int size, offset = 0 ;
8626 char *l, buffer[256];
8628 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8629 aopOp(right,ic,FALSE);
8631 l = aopGet(AOP(result),0,FALSE,TRUE);
8632 size = AOP_SIZE(right);
8634 if ( AOP_TYPE(result) == AOP_PCODE) {
8635 fprintf(stderr,"genDataPointerSet %s, %d\n",
8636 AOP(result)->aopu.pcop->name,
8637 PCOI(AOP(result)->aopu.pcop)->offset);
8641 // tsd, was l+1 - the underline `_' prefix was being stripped
8644 sprintf(buffer,"(%s + %d)",l,offset);
8645 fprintf(stderr,"oops %s\n",buffer);
8647 sprintf(buffer,"%s",l);
8649 if (AOP_TYPE(right) == AOP_LIT) {
8650 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8651 lit = lit >> (8*offset);
8653 pic14_emitcode("movlw","%d",lit);
8654 pic14_emitcode("movwf","%s",buffer);
8656 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8657 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8658 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8661 pic14_emitcode("clrf","%s",buffer);
8662 //emitpcode(POC_CLRF, popRegFromString(buffer));
8663 emitpcode(POC_CLRF, popGet(AOP(result),0));
8666 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8667 pic14_emitcode("movwf","%s",buffer);
8669 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8670 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8671 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8678 freeAsmop(right,NULL,ic,TRUE);
8679 freeAsmop(result,NULL,ic,TRUE);
8682 /*-----------------------------------------------------------------*/
8683 /* genNearPointerSet - pic14_emitcode for near pointer put */
8684 /*-----------------------------------------------------------------*/
8685 static void genNearPointerSet (operand *right,
8692 sym_link *ptype = operandType(result);
8695 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8696 retype= getSpec(operandType(right));
8698 aopOp(result,ic,FALSE);
8701 /* if the result is rematerializable &
8702 in data space & not a bit variable */
8703 //if (AOP_TYPE(result) == AOP_IMMD &&
8704 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8705 DCL_TYPE(ptype) == POINTER &&
8706 !IS_BITVAR(retype)) {
8707 genDataPointerSet (right,result,ic);
8708 freeAsmop(result,NULL,ic,TRUE);
8712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8713 aopOp(right,ic,FALSE);
8714 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8716 /* if the value is already in a pointer register
8717 then don't need anything more */
8718 if (!AOP_INPREG(AOP(result))) {
8719 /* otherwise get a free pointer register */
8720 //aop = newAsmop(0);
8721 //preg = getFreePtr(ic,&aop,FALSE);
8722 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8723 //pic14_emitcode("mov","%s,%s",
8725 // aopGet(AOP(result),0,FALSE,TRUE));
8726 //rname = preg->name ;
8727 //pic14_emitcode("movwf","fsr");
8728 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8729 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8730 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8731 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8735 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8738 /* if bitfield then unpack the bits */
8739 if (IS_BITVAR(retype)) {
8740 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8741 "The programmer is obviously confused");
8742 //genPackBits (retype,right,rname,POINTER);
8746 /* we have can just get the values */
8747 int size = AOP_SIZE(right);
8750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8752 l = aopGet(AOP(right),offset,FALSE,TRUE);
8755 //pic14_emitcode("mov","@%s,a",rname);
8756 pic14_emitcode("movf","indf,w ;1");
8759 if (AOP_TYPE(right) == AOP_LIT) {
8760 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8762 pic14_emitcode("movlw","%s",l);
8763 pic14_emitcode("movwf","indf ;2");
8765 pic14_emitcode("clrf","indf");
8767 pic14_emitcode("movf","%s,w",l);
8768 pic14_emitcode("movwf","indf ;2");
8770 //pic14_emitcode("mov","@%s,%s",rname,l);
8773 pic14_emitcode("incf","fsr,f ;3");
8774 //pic14_emitcode("inc","%s",rname);
8779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8780 /* now some housekeeping stuff */
8782 /* we had to allocate for this iCode */
8783 freeAsmop(NULL,aop,ic,TRUE);
8785 /* we did not allocate which means left
8786 already in a pointer register, then
8787 if size > 0 && this could be used again
8788 we have to point it back to where it
8790 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8791 if (AOP_SIZE(right) > 1 &&
8792 !OP_SYMBOL(result)->remat &&
8793 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8795 int size = AOP_SIZE(right) - 1;
8797 pic14_emitcode("decf","fsr,f");
8798 //pic14_emitcode("dec","%s",rname);
8802 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8805 freeAsmop(right,NULL,ic,TRUE);
8806 freeAsmop(result,NULL,ic,TRUE);
8809 /*-----------------------------------------------------------------*/
8810 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8811 /*-----------------------------------------------------------------*/
8812 static void genPagedPointerSet (operand *right,
8821 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8823 retype= getSpec(operandType(right));
8825 aopOp(result,ic,FALSE);
8827 /* if the value is already in a pointer register
8828 then don't need anything more */
8829 if (!AOP_INPREG(AOP(result))) {
8830 /* otherwise get a free pointer register */
8832 preg = getFreePtr(ic,&aop,FALSE);
8833 pic14_emitcode("mov","%s,%s",
8835 aopGet(AOP(result),0,FALSE,TRUE));
8836 rname = preg->name ;
8838 rname = aopGet(AOP(result),0,FALSE,FALSE);
8840 freeAsmop(result,NULL,ic,TRUE);
8841 aopOp (right,ic,FALSE);
8843 /* if bitfield then unpack the bits */
8844 if (IS_BITVAR(retype))
8845 genPackBits (retype,right,rname,PPOINTER);
8847 /* we have can just get the values */
8848 int size = AOP_SIZE(right);
8852 l = aopGet(AOP(right),offset,FALSE,TRUE);
8855 pic14_emitcode("movx","@%s,a",rname);
8858 pic14_emitcode("inc","%s",rname);
8864 /* now some housekeeping stuff */
8866 /* we had to allocate for this iCode */
8867 freeAsmop(NULL,aop,ic,TRUE);
8869 /* we did not allocate which means left
8870 already in a pointer register, then
8871 if size > 0 && this could be used again
8872 we have to point it back to where it
8874 if (AOP_SIZE(right) > 1 &&
8875 !OP_SYMBOL(result)->remat &&
8876 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8878 int size = AOP_SIZE(right) - 1;
8880 pic14_emitcode("dec","%s",rname);
8885 freeAsmop(right,NULL,ic,TRUE);
8890 /*-----------------------------------------------------------------*/
8891 /* genFarPointerSet - set value from far space */
8892 /*-----------------------------------------------------------------*/
8893 static void genFarPointerSet (operand *right,
8894 operand *result, iCode *ic)
8897 sym_link *retype = getSpec(operandType(right));
8899 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8900 aopOp(result,ic,FALSE);
8902 /* if the operand is already in dptr
8903 then we do nothing else we move the value to dptr */
8904 if (AOP_TYPE(result) != AOP_STR) {
8905 /* if this is remateriazable */
8906 if (AOP_TYPE(result) == AOP_IMMD)
8907 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8908 else { /* we need to get it byte by byte */
8909 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8910 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8911 if (options.model == MODEL_FLAT24)
8913 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8917 /* so dptr know contains the address */
8918 freeAsmop(result,NULL,ic,TRUE);
8919 aopOp(right,ic,FALSE);
8921 /* if bit then unpack */
8922 if (IS_BITVAR(retype))
8923 genPackBits(retype,right,"dptr",FPOINTER);
8925 size = AOP_SIZE(right);
8929 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8931 pic14_emitcode("movx","@dptr,a");
8933 pic14_emitcode("inc","dptr");
8937 freeAsmop(right,NULL,ic,TRUE);
8940 /*-----------------------------------------------------------------*/
8941 /* genGenPointerSet - set value from generic pointer space */
8942 /*-----------------------------------------------------------------*/
8943 static void genGenPointerSet (operand *right,
8944 operand *result, iCode *ic)
8947 sym_link *retype = getSpec(operandType(right));
8949 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8951 aopOp(result,ic,FALSE);
8952 aopOp(right,ic,FALSE);
8953 size = AOP_SIZE(right);
8955 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8957 /* if the operand is already in dptr
8958 then we do nothing else we move the value to dptr */
8959 if (AOP_TYPE(result) != AOP_STR) {
8960 /* if this is remateriazable */
8961 if (AOP_TYPE(result) == AOP_IMMD) {
8962 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8963 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8965 else { /* we need to get it byte by byte */
8966 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8967 size = AOP_SIZE(right);
8970 /* hack hack! see if this the FSR. If so don't load W */
8971 if(AOP_TYPE(right) != AOP_ACC) {
8974 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8975 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8977 if(AOP_SIZE(result) > 1) {
8978 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8979 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8980 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8985 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8987 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8988 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8992 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8993 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8996 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9003 if(aopIdx(AOP(result),0) != 4) {
9005 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9009 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9014 /* so dptr know contains the address */
9017 /* if bit then unpack */
9018 if (IS_BITVAR(retype))
9019 genPackBits(retype,right,"dptr",GPOINTER);
9021 size = AOP_SIZE(right);
9024 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9028 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9029 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9031 if (AOP_TYPE(right) == AOP_LIT)
9032 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9034 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9036 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9043 freeAsmop(right,NULL,ic,TRUE);
9044 freeAsmop(result,NULL,ic,TRUE);
9047 /*-----------------------------------------------------------------*/
9048 /* genPointerSet - stores the value into a pointer location */
9049 /*-----------------------------------------------------------------*/
9050 static void genPointerSet (iCode *ic)
9052 operand *right, *result ;
9053 sym_link *type, *etype;
9056 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9058 right = IC_RIGHT(ic);
9059 result = IC_RESULT(ic) ;
9061 /* depending on the type of pointer we need to
9062 move it to the correct pointer register */
9063 type = operandType(result);
9064 etype = getSpec(type);
9065 /* if left is of type of pointer then it is simple */
9066 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9067 p_type = DCL_TYPE(type);
9070 /* we have to go by the storage class */
9071 p_type = PTR_TYPE(SPEC_OCLS(etype));
9073 /* if (SPEC_OCLS(etype)->codesp ) { */
9074 /* p_type = CPOINTER ; */
9077 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9078 /* p_type = FPOINTER ; */
9080 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9081 /* p_type = PPOINTER ; */
9083 /* if (SPEC_OCLS(etype) == idata ) */
9084 /* p_type = IPOINTER ; */
9086 /* p_type = POINTER ; */
9089 /* now that we have the pointer type we assign
9090 the pointer values */
9095 genNearPointerSet (right,result,ic);
9099 genPagedPointerSet (right,result,ic);
9103 genFarPointerSet (right,result,ic);
9107 genGenPointerSet (right,result,ic);
9111 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9112 "genPointerSet: illegal pointer type");
9116 /*-----------------------------------------------------------------*/
9117 /* genIfx - generate code for Ifx statement */
9118 /*-----------------------------------------------------------------*/
9119 static void genIfx (iCode *ic, iCode *popIc)
9121 operand *cond = IC_COND(ic);
9124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9126 aopOp(cond,ic,FALSE);
9128 /* get the value into acc */
9129 if (AOP_TYPE(cond) != AOP_CRY)
9130 pic14_toBoolean(cond);
9133 /* the result is now in the accumulator */
9134 freeAsmop(cond,NULL,ic,TRUE);
9136 /* if there was something to be popped then do it */
9140 /* if the condition is a bit variable */
9141 if (isbit && IS_ITEMP(cond) &&
9143 genIfxJump(ic,SPIL_LOC(cond)->rname);
9144 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9147 if (isbit && !IS_ITEMP(cond))
9148 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9156 /*-----------------------------------------------------------------*/
9157 /* genAddrOf - generates code for address of */
9158 /*-----------------------------------------------------------------*/
9159 static void genAddrOf (iCode *ic)
9161 operand *right, *result, *left;
9164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9167 //aopOp(IC_RESULT(ic),ic,FALSE);
9169 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9170 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9171 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9173 DEBUGpic14_AopType(__LINE__,left,right,result);
9175 size = AOP_SIZE(IC_RESULT(ic));
9179 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9180 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9184 freeAsmop(left,NULL,ic,FALSE);
9185 freeAsmop(result,NULL,ic,TRUE);
9190 /*-----------------------------------------------------------------*/
9191 /* genFarFarAssign - assignment when both are in far space */
9192 /*-----------------------------------------------------------------*/
9193 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9195 int size = AOP_SIZE(right);
9198 /* first push the right side on to the stack */
9200 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9202 pic14_emitcode ("push","acc");
9205 freeAsmop(right,NULL,ic,FALSE);
9206 /* now assign DPTR to result */
9207 aopOp(result,ic,FALSE);
9208 size = AOP_SIZE(result);
9210 pic14_emitcode ("pop","acc");
9211 aopPut(AOP(result),"a",--offset);
9213 freeAsmop(result,NULL,ic,FALSE);
9218 /*-----------------------------------------------------------------*/
9219 /* genAssign - generate code for assignment */
9220 /*-----------------------------------------------------------------*/
9221 static void genAssign (iCode *ic)
9223 operand *result, *right;
9224 int size, offset,know_W;
9225 unsigned long lit = 0L;
9227 result = IC_RESULT(ic);
9228 right = IC_RIGHT(ic) ;
9230 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9232 /* if they are the same */
9233 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9236 aopOp(right,ic,FALSE);
9237 aopOp(result,ic,TRUE);
9239 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9241 /* if they are the same registers */
9242 if (pic14_sameRegs(AOP(right),AOP(result)))
9245 /* if the result is a bit */
9246 if (AOP_TYPE(result) == AOP_CRY) {
9248 /* if the right size is a literal then
9249 we know what the value is */
9250 if (AOP_TYPE(right) == AOP_LIT) {
9252 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9253 popGet(AOP(result),0));
9255 if (((int) operandLitValue(right)))
9256 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9257 AOP(result)->aopu.aop_dir,
9258 AOP(result)->aopu.aop_dir);
9260 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9261 AOP(result)->aopu.aop_dir,
9262 AOP(result)->aopu.aop_dir);
9266 /* the right is also a bit variable */
9267 if (AOP_TYPE(right) == AOP_CRY) {
9268 emitpcode(POC_BCF, popGet(AOP(result),0));
9269 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9270 emitpcode(POC_BSF, popGet(AOP(result),0));
9272 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9273 AOP(result)->aopu.aop_dir,
9274 AOP(result)->aopu.aop_dir);
9275 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9276 AOP(right)->aopu.aop_dir,
9277 AOP(right)->aopu.aop_dir);
9278 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9279 AOP(result)->aopu.aop_dir,
9280 AOP(result)->aopu.aop_dir);
9285 emitpcode(POC_BCF, popGet(AOP(result),0));
9286 pic14_toBoolean(right);
9288 emitpcode(POC_BSF, popGet(AOP(result),0));
9289 //aopPut(AOP(result),"a",0);
9293 /* bit variables done */
9295 size = AOP_SIZE(result);
9297 if(AOP_TYPE(right) == AOP_LIT)
9298 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9300 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9302 if(aopIdx(AOP(result),0) == 4) {
9303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9304 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9305 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9308 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9314 if(AOP_TYPE(right) == AOP_LIT) {
9316 if(know_W != (int)(lit&0xff))
9317 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9319 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9321 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9325 } else if (AOP_TYPE(right) == AOP_CRY) {
9326 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9328 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9329 emitpcode(POC_INCF, popGet(AOP(result),0));
9332 mov2w (AOP(right), offset);
9333 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9341 freeAsmop (right,NULL,ic,FALSE);
9342 freeAsmop (result,NULL,ic,TRUE);
9345 /*-----------------------------------------------------------------*/
9346 /* genJumpTab - genrates code for jump table */
9347 /*-----------------------------------------------------------------*/
9348 static void genJumpTab (iCode *ic)
9353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9355 aopOp(IC_JTCOND(ic),ic,FALSE);
9356 /* get the condition into accumulator */
9357 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9359 /* multiply by three */
9360 pic14_emitcode("add","a,acc");
9361 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9363 jtab = newiTempLabel(NULL);
9364 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9365 pic14_emitcode("jmp","@a+dptr");
9366 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9368 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9369 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9370 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9371 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9373 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9374 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9375 emitpLabel(jtab->key);
9377 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9379 /* now generate the jump labels */
9380 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9381 jtab = setNextItem(IC_JTLABELS(ic))) {
9382 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9383 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9389 /*-----------------------------------------------------------------*/
9390 /* genMixedOperation - gen code for operators between mixed types */
9391 /*-----------------------------------------------------------------*/
9393 TSD - Written for the PIC port - but this unfortunately is buggy.
9394 This routine is good in that it is able to efficiently promote
9395 types to different (larger) sizes. Unfortunately, the temporary
9396 variables that are optimized out by this routine are sometimes
9397 used in other places. So until I know how to really parse the
9398 iCode tree, I'm going to not be using this routine :(.
9400 static int genMixedOperation (iCode *ic)
9403 operand *result = IC_RESULT(ic);
9404 sym_link *ctype = operandType(IC_LEFT(ic));
9405 operand *right = IC_RIGHT(ic);
9411 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9413 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9419 nextright = IC_RIGHT(nextic);
9420 nextleft = IC_LEFT(nextic);
9421 nextresult = IC_RESULT(nextic);
9423 aopOp(right,ic,FALSE);
9424 aopOp(result,ic,FALSE);
9425 aopOp(nextright, nextic, FALSE);
9426 aopOp(nextleft, nextic, FALSE);
9427 aopOp(nextresult, nextic, FALSE);
9429 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9435 pic14_emitcode(";remove right +","");
9437 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9443 pic14_emitcode(";remove left +","");
9447 big = AOP_SIZE(nextleft);
9448 small = AOP_SIZE(nextright);
9450 switch(nextic->op) {
9453 pic14_emitcode(";optimize a +","");
9454 /* if unsigned or not an integral type */
9455 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9456 pic14_emitcode(";add a bit to something","");
9459 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9461 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9462 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9463 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9465 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9473 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9474 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9475 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9478 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9480 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9481 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9482 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9483 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9484 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9487 pic14_emitcode("rlf","known_zero,w");
9494 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9495 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9496 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9498 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9508 freeAsmop(right,NULL,ic,TRUE);
9509 freeAsmop(result,NULL,ic,TRUE);
9510 freeAsmop(nextright,NULL,ic,TRUE);
9511 freeAsmop(nextleft,NULL,ic,TRUE);
9513 nextic->generated = 1;
9520 /*-----------------------------------------------------------------*/
9521 /* genCast - gen code for casting */
9522 /*-----------------------------------------------------------------*/
9523 static void genCast (iCode *ic)
9525 operand *result = IC_RESULT(ic);
9526 sym_link *ctype = operandType(IC_LEFT(ic));
9527 sym_link *rtype = operandType(IC_RIGHT(ic));
9528 operand *right = IC_RIGHT(ic);
9531 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9532 /* if they are equivalent then do nothing */
9533 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9536 aopOp(right,ic,FALSE) ;
9537 aopOp(result,ic,FALSE);
9539 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9541 /* if the result is a bit */
9542 if (AOP_TYPE(result) == AOP_CRY) {
9543 /* if the right size is a literal then
9544 we know what the value is */
9545 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9546 if (AOP_TYPE(right) == AOP_LIT) {
9548 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9549 popGet(AOP(result),0));
9551 if (((int) operandLitValue(right)))
9552 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9553 AOP(result)->aopu.aop_dir,
9554 AOP(result)->aopu.aop_dir);
9556 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9557 AOP(result)->aopu.aop_dir,
9558 AOP(result)->aopu.aop_dir);
9563 /* the right is also a bit variable */
9564 if (AOP_TYPE(right) == AOP_CRY) {
9567 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9569 pic14_emitcode("clrc","");
9570 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9571 AOP(right)->aopu.aop_dir,
9572 AOP(right)->aopu.aop_dir);
9573 aopPut(AOP(result),"c",0);
9578 if (AOP_TYPE(right) == AOP_REG) {
9579 emitpcode(POC_BCF, popGet(AOP(result),0));
9580 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9581 emitpcode(POC_BSF, popGet(AOP(result),0));
9583 pic14_toBoolean(right);
9584 aopPut(AOP(result),"a",0);
9588 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9590 size = AOP_SIZE(result);
9592 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9594 emitpcode(POC_CLRF, popGet(AOP(result),0));
9595 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9596 emitpcode(POC_INCF, popGet(AOP(result),0));
9599 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9604 /* if they are the same size : or less */
9605 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9607 /* if they are in the same place */
9608 if (pic14_sameRegs(AOP(right),AOP(result)))
9611 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9612 if (IS_PTR_CONST(rtype))
9613 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9614 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9615 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9617 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9618 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9619 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9620 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9621 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9622 if(AOP_SIZE(result) <2)
9623 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9627 /* if they in different places then copy */
9628 size = AOP_SIZE(result);
9631 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9632 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9634 //aopPut(AOP(result),
9635 // aopGet(AOP(right),offset,FALSE,FALSE),
9645 /* if the result is of type pointer */
9646 if (IS_PTR(ctype)) {
9649 sym_link *type = operandType(right);
9650 sym_link *etype = getSpec(type);
9651 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9653 /* pointer to generic pointer */
9654 if (IS_GENPTR(ctype)) {
9658 p_type = DCL_TYPE(type);
9660 /* we have to go by the storage class */
9661 p_type = PTR_TYPE(SPEC_OCLS(etype));
9663 /* if (SPEC_OCLS(etype)->codesp ) */
9664 /* p_type = CPOINTER ; */
9666 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9667 /* p_type = FPOINTER ; */
9669 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9670 /* p_type = PPOINTER; */
9672 /* if (SPEC_OCLS(etype) == idata ) */
9673 /* p_type = IPOINTER ; */
9675 /* p_type = POINTER ; */
9678 /* the first two bytes are known */
9679 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9680 size = GPTRSIZE - 1;
9683 if(offset < AOP_SIZE(right)) {
9684 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9685 if ((AOP_TYPE(right) == AOP_PCODE) &&
9686 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9687 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9688 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9691 aopGet(AOP(right),offset,FALSE,FALSE),
9695 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9698 /* the last byte depending on type */
9702 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9705 pic14_emitcode(";BUG!? ","%d",__LINE__);
9709 pic14_emitcode(";BUG!? ","%d",__LINE__);
9713 pic14_emitcode(";BUG!? ","%d",__LINE__);
9718 /* this should never happen */
9719 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9720 "got unknown pointer type");
9723 //aopPut(AOP(result),l, GPTRSIZE - 1);
9727 /* just copy the pointers */
9728 size = AOP_SIZE(result);
9732 aopGet(AOP(right),offset,FALSE,FALSE),
9741 /* so we now know that the size of destination is greater
9742 than the size of the source.
9743 Now, if the next iCode is an operator then we might be
9744 able to optimize the operation without performing a cast.
9746 if(genMixedOperation(ic))
9749 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9751 /* we move to result for the size of source */
9752 size = AOP_SIZE(right);
9755 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9756 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9760 /* now depending on the sign of the destination */
9761 size = AOP_SIZE(result) - AOP_SIZE(right);
9762 /* if unsigned or not an integral type */
9763 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9765 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9767 /* we need to extend the sign :{ */
9770 /* Save one instruction of casting char to int */
9771 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9772 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9773 emitpcode(POC_DECF, popGet(AOP(result),offset));
9775 emitpcodeNULLop(POC_CLRW);
9778 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9780 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9782 emitpcode(POC_MOVLW, popGetLit(0xff));
9785 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9790 freeAsmop(right,NULL,ic,TRUE);
9791 freeAsmop(result,NULL,ic,TRUE);
9795 /*-----------------------------------------------------------------*/
9796 /* genDjnz - generate decrement & jump if not zero instrucion */
9797 /*-----------------------------------------------------------------*/
9798 static int genDjnz (iCode *ic, iCode *ifx)
9801 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9806 /* if the if condition has a false label
9807 then we cannot save */
9811 /* if the minus is not of the form
9813 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9814 !IS_OP_LITERAL(IC_RIGHT(ic)))
9817 if (operandLitValue(IC_RIGHT(ic)) != 1)
9820 /* if the size of this greater than one then no
9822 if (getSize(operandType(IC_RESULT(ic))) > 1)
9825 /* otherwise we can save BIG */
9826 lbl = newiTempLabel(NULL);
9827 lbl1= newiTempLabel(NULL);
9829 aopOp(IC_RESULT(ic),ic,FALSE);
9831 if (IS_AOP_PREG(IC_RESULT(ic))) {
9832 pic14_emitcode("dec","%s",
9833 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9834 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9835 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9839 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9840 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9842 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9843 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9846 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9847 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9848 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9849 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9852 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9857 /*-----------------------------------------------------------------*/
9858 /* genReceive - generate code for a receive iCode */
9859 /*-----------------------------------------------------------------*/
9860 static void genReceive (iCode *ic)
9862 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9864 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9865 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9866 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9868 int size = getSize(operandType(IC_RESULT(ic)));
9869 int offset = fReturnSizePic - size;
9871 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9872 fReturn[fReturnSizePic - offset - 1] : "acc"));
9875 aopOp(IC_RESULT(ic),ic,FALSE);
9876 size = AOP_SIZE(IC_RESULT(ic));
9879 pic14_emitcode ("pop","acc");
9880 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9885 aopOp(IC_RESULT(ic),ic,FALSE);
9887 assignResultValue(IC_RESULT(ic));
9890 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9893 /*-----------------------------------------------------------------*/
9894 /* genDummyRead - generate code for dummy read of volatiles */
9895 /*-----------------------------------------------------------------*/
9897 genDummyRead (iCode * ic)
9899 pic14_emitcode ("; genDummyRead","");
9900 pic14_emitcode ("; not implemented","");
9905 /*-----------------------------------------------------------------*/
9906 /* genpic14Code - generate code for pic14 based controllers */
9907 /*-----------------------------------------------------------------*/
9909 * At this point, ralloc.c has gone through the iCode and attempted
9910 * to optimize in a way suitable for a PIC. Now we've got to generate
9911 * PIC instructions that correspond to the iCode.
9913 * Once the instructions are generated, we'll pass through both the
9914 * peep hole optimizer and the pCode optimizer.
9915 *-----------------------------------------------------------------*/
9917 void genpic14Code (iCode *lic)
9922 lineHead = lineCurr = NULL;
9924 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9927 /* if debug information required */
9928 if (options.debug && currFunc) {
9930 debugFile->writeFunction(currFunc);
9932 if (IS_STATIC(currFunc->etype)) {
9933 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9934 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9936 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9937 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9944 for (ic = lic ; ic ; ic = ic->next ) {
9946 DEBUGpic14_emitcode(";ic","");
9947 if ( cln != ic->lineno ) {
9948 if ( options.debug ) {
9950 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9951 FileBaseName(ic->filename),ic->lineno,
9952 ic->level,ic->block);
9956 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9957 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9958 printCLine(ic->filename, ic->lineno));
9960 if (!options.noCcodeInAsm) {
9962 newpCodeCSource(ic->lineno,
9964 printCLine(ic->filename, ic->lineno)));
9970 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9972 /* if the result is marked as
9973 spilt and rematerializable or code for
9974 this has already been generated then
9976 if (resultRemat(ic) || ic->generated )
9979 /* depending on the operation */
9998 /* IPOP happens only when trying to restore a
9999 spilt live range, if there is an ifx statement
10000 following this pop then the if statement might
10001 be using some of the registers being popped which
10002 would destory the contents of the register so
10003 we need to check for this condition and handle it */
10005 ic->next->op == IFX &&
10006 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10007 genIfx (ic->next,ic);
10025 genEndFunction (ic);
10045 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10062 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10066 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10073 /* note these two are xlated by algebraic equivalence
10074 during parsing SDCC.y */
10075 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10076 "got '>=' or '<=' shouldn't have come here");
10080 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10092 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10096 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10100 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10124 genRightShift (ic);
10127 case GET_VALUE_AT_ADDRESS:
10132 if (POINTER_SET(ic))
10159 addSet(&_G.sendSet,ic);
10162 case DUMMY_READ_VOLATILE:
10172 /* now we are ready to call the
10173 peep hole optimizer */
10174 if (!options.nopeep) {
10175 peepHole (&lineHead);
10177 /* now do the actual printing */
10178 printLine (lineHead,codeOutFile);
10181 DFPRINTF((stderr,"printing pBlock\n\n"));
10182 printpBlock(stdout,pb);