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)
1735 /*-----------------------------------------------------------------*/
1736 /* genNotFloat - generates not for float operations */
1737 /*-----------------------------------------------------------------*/
1738 static void genNotFloat (operand *op, operand *res)
1744 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1745 /* we will put 127 in the first byte of
1747 aopPut(AOP(res),"#127",0);
1748 size = AOP_SIZE(op) - 1;
1751 l = aopGet(op->aop,offset++,FALSE,FALSE);
1755 pic14_emitcode("orl","a,%s",
1757 offset++,FALSE,FALSE));
1759 tlbl = newiTempLabel(NULL);
1761 tlbl = newiTempLabel(NULL);
1762 aopPut(res->aop,one,1);
1763 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1764 aopPut(res->aop,zero,1);
1765 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1767 size = res->aop->size - 2;
1769 /* put zeros in the rest */
1771 aopPut(res->aop,zero,offset++);
1775 /*-----------------------------------------------------------------*/
1776 /* opIsGptr: returns non-zero if the passed operand is */
1777 /* a generic pointer type. */
1778 /*-----------------------------------------------------------------*/
1779 static int opIsGptr(operand *op)
1781 sym_link *type = operandType(op);
1783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1784 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_getDataSize - get the operand data size */
1794 /*-----------------------------------------------------------------*/
1795 int pic14_getDataSize(operand *op)
1797 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1800 return AOP_SIZE(op);
1802 // tsd- in the pic port, the genptr size is 1, so this code here
1803 // fails. ( in the 8051 port, the size was 4).
1806 size = AOP_SIZE(op);
1807 if (size == GPTRSIZE)
1809 sym_link *type = operandType(op);
1810 if (IS_GENPTR(type))
1812 /* generic pointer; arithmetic operations
1813 * should ignore the high byte (pointer type).
1816 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1823 /*-----------------------------------------------------------------*/
1824 /* pic14_outAcc - output Acc */
1825 /*-----------------------------------------------------------------*/
1826 void pic14_outAcc(operand *result)
1829 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1830 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1833 size = pic14_getDataSize(result);
1835 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1838 /* unsigned or positive */
1840 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1845 /*-----------------------------------------------------------------*/
1846 /* pic14_outBitC - output a bit C */
1847 /*-----------------------------------------------------------------*/
1848 void pic14_outBitC(operand *result)
1851 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1852 /* if the result is bit */
1853 if (AOP_TYPE(result) == AOP_CRY)
1854 aopPut(AOP(result),"c",0);
1856 pic14_emitcode("clr","a ; %d", __LINE__);
1857 pic14_emitcode("rlc","a");
1858 pic14_outAcc(result);
1862 /*-----------------------------------------------------------------*/
1863 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1864 /*-----------------------------------------------------------------*/
1865 void pic14_toBoolean(operand *oper)
1867 int size = AOP_SIZE(oper) - 1;
1870 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1872 if ( AOP_TYPE(oper) != AOP_ACC) {
1873 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1876 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1881 /*-----------------------------------------------------------------*/
1882 /* genNot - generate code for ! operation */
1883 /*-----------------------------------------------------------------*/
1884 static void genNot (iCode *ic)
1887 sym_link *optype = operandType(IC_LEFT(ic));
1890 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1891 /* assign asmOps to operand & result */
1892 aopOp (IC_LEFT(ic),ic,FALSE);
1893 aopOp (IC_RESULT(ic),ic,TRUE);
1895 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1896 /* if in bit space then a special case */
1897 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1898 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1899 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1900 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1902 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1903 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1904 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1909 /* if type float then do float */
1910 if (IS_FLOAT(optype)) {
1911 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1915 size = AOP_SIZE(IC_RESULT(ic));
1917 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1918 emitpcode(POC_ANDLW,popGetLit(1));
1919 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1922 pic14_toBoolean(IC_LEFT(ic));
1924 tlbl = newiTempLabel(NULL);
1925 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1926 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1927 pic14_outBitC(IC_RESULT(ic));
1930 /* release the aops */
1931 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1932 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1936 /*-----------------------------------------------------------------*/
1937 /* genCpl - generate code for complement */
1938 /*-----------------------------------------------------------------*/
1939 static void genCpl (iCode *ic)
1941 operand *left, *result;
1945 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1946 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1947 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1949 /* if both are in bit space then
1951 if (AOP_TYPE(result) == AOP_CRY &&
1952 AOP_TYPE(left) == AOP_CRY ) {
1954 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1955 pic14_emitcode("cpl","c");
1956 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1960 size = AOP_SIZE(result);
1963 if(AOP_TYPE(left) == AOP_ACC)
1964 emitpcode(POC_XORLW, popGetLit(0xff));
1966 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1968 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1974 /* release the aops */
1975 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1976 freeAsmop(result,NULL,ic,TRUE);
1979 /*-----------------------------------------------------------------*/
1980 /* genUminusFloat - unary minus for floating points */
1981 /*-----------------------------------------------------------------*/
1982 static void genUminusFloat(operand *op,operand *result)
1984 int size ,offset =0 ;
1987 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1988 /* for this we just need to flip the
1989 first it then copy the rest in place */
1990 size = AOP_SIZE(op) - 1;
1991 l = aopGet(AOP(op),3,FALSE,FALSE);
1995 pic14_emitcode("cpl","acc.7");
1996 aopPut(AOP(result),"a",3);
2000 aopGet(AOP(op),offset,FALSE,FALSE),
2006 /*-----------------------------------------------------------------*/
2007 /* genUminus - unary minus code generation */
2008 /*-----------------------------------------------------------------*/
2009 static void genUminus (iCode *ic)
2012 sym_link *optype, *rtype;
2015 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2017 aopOp(IC_LEFT(ic),ic,FALSE);
2018 aopOp(IC_RESULT(ic),ic,TRUE);
2020 /* if both in bit space then special
2022 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
2023 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2025 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
2026 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
2027 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
2032 optype = operandType(IC_LEFT(ic));
2033 rtype = operandType(IC_RESULT(ic));
2035 /* if float then do float stuff */
2036 if (IS_FLOAT(optype)) {
2037 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2041 /* otherwise subtract from zero by taking the 2's complement */
2042 size = AOP_SIZE(IC_LEFT(ic));
2044 for(i=0; i<size; i++) {
2045 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2046 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2048 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2049 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2053 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2054 for(i=1; i<size; i++) {
2056 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2060 /* release the aops */
2061 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2062 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2065 /*-----------------------------------------------------------------*/
2066 /* saveRegisters - will look for a call and save the registers */
2067 /*-----------------------------------------------------------------*/
2068 static void saveRegisters(iCode *lic)
2075 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2077 for (ic = lic ; ic ; ic = ic->next)
2078 if (ic->op == CALL || ic->op == PCALL)
2082 fprintf(stderr,"found parameter push with no function call\n");
2086 /* if the registers have been saved already then
2088 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2091 /* find the registers in use at this time
2092 and push them away to safety */
2093 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2097 if (options.useXstack) {
2098 if (bitVectBitValue(rsave,R0_IDX))
2099 pic14_emitcode("mov","b,r0");
2100 pic14_emitcode("mov","r0,%s",spname);
2101 for (i = 0 ; i < pic14_nRegs ; i++) {
2102 if (bitVectBitValue(rsave,i)) {
2104 pic14_emitcode("mov","a,b");
2106 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2107 pic14_emitcode("movx","@r0,a");
2108 pic14_emitcode("inc","r0");
2111 pic14_emitcode("mov","%s,r0",spname);
2112 if (bitVectBitValue(rsave,R0_IDX))
2113 pic14_emitcode("mov","r0,b");
2115 //for (i = 0 ; i < pic14_nRegs ; i++) {
2116 // if (bitVectBitValue(rsave,i))
2117 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2120 dtype = operandType(IC_LEFT(ic));
2121 if (currFunc && dtype &&
2122 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2123 IFFUNC_ISISR(currFunc->type) &&
2126 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2129 /*-----------------------------------------------------------------*/
2130 /* unsaveRegisters - pop the pushed registers */
2131 /*-----------------------------------------------------------------*/
2132 static void unsaveRegisters (iCode *ic)
2137 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2138 /* find the registers in use at this time
2139 and push them away to safety */
2140 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2143 if (options.useXstack) {
2144 pic14_emitcode("mov","r0,%s",spname);
2145 for (i = pic14_nRegs ; i >= 0 ; i--) {
2146 if (bitVectBitValue(rsave,i)) {
2147 pic14_emitcode("dec","r0");
2148 pic14_emitcode("movx","a,@r0");
2150 pic14_emitcode("mov","b,a");
2152 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2156 pic14_emitcode("mov","%s,r0",spname);
2157 if (bitVectBitValue(rsave,R0_IDX))
2158 pic14_emitcode("mov","r0,b");
2160 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2161 // if (bitVectBitValue(rsave,i))
2162 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2168 /*-----------------------------------------------------------------*/
2170 /*-----------------------------------------------------------------*/
2171 static void pushSide(operand * oper, int size)
2175 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2177 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2178 if (AOP_TYPE(oper) != AOP_REG &&
2179 AOP_TYPE(oper) != AOP_DIR &&
2181 pic14_emitcode("mov","a,%s",l);
2182 pic14_emitcode("push","acc");
2184 pic14_emitcode("push","%s",l);
2189 /*-----------------------------------------------------------------*/
2190 /* assignResultValue - */
2191 /*-----------------------------------------------------------------*/
2192 static void assignResultValue(operand * oper)
2194 int size = AOP_SIZE(oper);
2196 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2198 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2200 if(!GpsuedoStkPtr) {
2201 /* The last byte in the assignment is in W */
2203 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2205 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2209 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2211 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2216 /*-----------------------------------------------------------------*/
2217 /* genIpush - genrate code for pushing this gets a little complex */
2218 /*-----------------------------------------------------------------*/
2219 static void genIpush (iCode *ic)
2222 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2224 int size, offset = 0 ;
2228 /* if this is not a parm push : ie. it is spill push
2229 and spill push is always done on the local stack */
2230 if (!ic->parmPush) {
2232 /* and the item is spilt then do nothing */
2233 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2236 aopOp(IC_LEFT(ic),ic,FALSE);
2237 size = AOP_SIZE(IC_LEFT(ic));
2238 /* push it on the stack */
2240 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2245 pic14_emitcode("push","%s",l);
2250 /* this is a paramter push: in this case we call
2251 the routine to find the call and save those
2252 registers that need to be saved */
2255 /* then do the push */
2256 aopOp(IC_LEFT(ic),ic,FALSE);
2259 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2260 size = AOP_SIZE(IC_LEFT(ic));
2263 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2264 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2265 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2267 pic14_emitcode("mov","a,%s",l);
2268 pic14_emitcode("push","acc");
2270 pic14_emitcode("push","%s",l);
2273 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2277 /*-----------------------------------------------------------------*/
2278 /* genIpop - recover the registers: can happen only for spilling */
2279 /*-----------------------------------------------------------------*/
2280 static void genIpop (iCode *ic)
2282 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2287 /* if the temp was not pushed then */
2288 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2291 aopOp(IC_LEFT(ic),ic,FALSE);
2292 size = AOP_SIZE(IC_LEFT(ic));
2295 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2298 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2302 /*-----------------------------------------------------------------*/
2303 /* unsaverbank - restores the resgister bank from stack */
2304 /*-----------------------------------------------------------------*/
2305 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2307 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2313 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2315 if (options.useXstack) {
2317 r = getFreePtr(ic,&aop,FALSE);
2320 pic14_emitcode("mov","%s,_spx",r->name);
2321 pic14_emitcode("movx","a,@%s",r->name);
2322 pic14_emitcode("mov","psw,a");
2323 pic14_emitcode("dec","%s",r->name);
2326 pic14_emitcode ("pop","psw");
2329 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2330 if (options.useXstack) {
2331 pic14_emitcode("movx","a,@%s",r->name);
2332 //pic14_emitcode("mov","(%s+%d),a",
2333 // regspic14[i].base,8*bank+regspic14[i].offset);
2334 pic14_emitcode("dec","%s",r->name);
2337 pic14_emitcode("pop",""); //"(%s+%d)",
2338 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2341 if (options.useXstack) {
2343 pic14_emitcode("mov","_spx,%s",r->name);
2344 freeAsmop(NULL,aop,ic,TRUE);
2350 /*-----------------------------------------------------------------*/
2351 /* saverbank - saves an entire register bank on the stack */
2352 /*-----------------------------------------------------------------*/
2353 static void saverbank (int bank, iCode *ic, bool pushPsw)
2355 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2362 if (options.useXstack) {
2365 r = getFreePtr(ic,&aop,FALSE);
2366 pic14_emitcode("mov","%s,_spx",r->name);
2370 for (i = 0 ; i < pic14_nRegs ;i++) {
2371 if (options.useXstack) {
2372 pic14_emitcode("inc","%s",r->name);
2373 //pic14_emitcode("mov","a,(%s+%d)",
2374 // regspic14[i].base,8*bank+regspic14[i].offset);
2375 pic14_emitcode("movx","@%s,a",r->name);
2377 pic14_emitcode("push","");// "(%s+%d)",
2378 //regspic14[i].base,8*bank+regspic14[i].offset);
2382 if (options.useXstack) {
2383 pic14_emitcode("mov","a,psw");
2384 pic14_emitcode("movx","@%s,a",r->name);
2385 pic14_emitcode("inc","%s",r->name);
2386 pic14_emitcode("mov","_spx,%s",r->name);
2387 freeAsmop (NULL,aop,ic,TRUE);
2390 pic14_emitcode("push","psw");
2392 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2398 /*-----------------------------------------------------------------*/
2399 /* genCall - generates a call statement */
2400 /*-----------------------------------------------------------------*/
2401 static void genCall (iCode *ic)
2405 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2407 /* if caller saves & we have not saved then */
2411 /* if we are calling a function that is not using
2412 the same register bank then we need to save the
2413 destination registers on the stack */
2414 dtype = operandType(IC_LEFT(ic));
2415 if (currFunc && dtype &&
2416 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2417 IFFUNC_ISISR(currFunc->type) &&
2420 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2422 /* if send set is not empty the assign */
2425 /* For the Pic port, there is no data stack.
2426 * So parameters passed to functions are stored
2427 * in registers. (The pCode optimizer will get
2428 * rid of most of these :).
2430 int psuedoStkPtr=-1;
2431 int firstTimeThruLoop = 1;
2433 _G.sendSet = reverseSet(_G.sendSet);
2435 /* First figure how many parameters are getting passed */
2436 for (sic = setFirstItem(_G.sendSet) ; sic ;
2437 sic = setNextItem(_G.sendSet)) {
2439 aopOp(IC_LEFT(sic),sic,FALSE);
2440 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2441 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2444 for (sic = setFirstItem(_G.sendSet) ; sic ;
2445 sic = setNextItem(_G.sendSet)) {
2446 int size, offset = 0;
2448 aopOp(IC_LEFT(sic),sic,FALSE);
2449 size = AOP_SIZE(IC_LEFT(sic));
2452 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2453 AopType(AOP_TYPE(IC_LEFT(sic))));
2455 if(!firstTimeThruLoop) {
2456 /* If this is not the first time we've been through the loop
2457 * then we need to save the parameter in a temporary
2458 * register. The last byte of the last parameter is
2460 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2463 firstTimeThruLoop=0;
2465 //if (strcmp(l,fReturn[offset])) {
2466 mov2w (AOP(IC_LEFT(sic)), offset);
2468 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2469 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2470 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2472 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2477 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2482 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2483 OP_SYMBOL(IC_LEFT(ic))->rname :
2484 OP_SYMBOL(IC_LEFT(ic))->name));
2487 /* if we need assign a result value */
2488 if ((IS_ITEMP(IC_RESULT(ic)) &&
2489 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2490 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2491 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2494 aopOp(IC_RESULT(ic),ic,FALSE);
2497 assignResultValue(IC_RESULT(ic));
2499 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2500 AopType(AOP_TYPE(IC_RESULT(ic))));
2502 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2505 /* adjust the stack for parameters if
2507 if (ic->parmBytes) {
2509 if (ic->parmBytes > 3) {
2510 pic14_emitcode("mov","a,%s",spname);
2511 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2512 pic14_emitcode("mov","%s,a",spname);
2514 for ( i = 0 ; i < ic->parmBytes ;i++)
2515 pic14_emitcode("dec","%s",spname);
2519 /* if register bank was saved then pop them */
2521 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2523 /* if we hade saved some registers then unsave them */
2524 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2525 unsaveRegisters (ic);
2530 /*-----------------------------------------------------------------*/
2531 /* genPcall - generates a call by pointer statement */
2532 /*-----------------------------------------------------------------*/
2533 static void genPcall (iCode *ic)
2536 symbol *albl = newiTempLabel(NULL);
2537 symbol *blbl = newiTempLabel(NULL);
2541 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2542 /* if caller saves & we have not saved then */
2546 /* if we are calling a function that is not using
2547 the same register bank then we need to save the
2548 destination registers on the stack */
2549 dtype = operandType(IC_LEFT(ic));
2550 if (currFunc && dtype &&
2551 IFFUNC_ISISR(currFunc->type) &&
2552 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2553 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2556 aopOp(left,ic,FALSE);
2557 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2559 pushSide(IC_LEFT(ic), FPTRSIZE);
2561 /* if send set is not empty, assign parameters */
2564 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2565 /* no way to pass args - W always gets used to make the call */
2567 /* first idea - factor out a common helper function and call it.
2568 But don't know how to get it generated only once in its own block
2570 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2573 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2574 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2575 buffer = Safe_calloc(1,strlen(rname)+16);
2576 sprintf(buffer, "%s_goto_helper", rname);
2577 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2581 emitpcode(POC_CALL,popGetLabel(albl->key));
2582 emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
2583 emitpcode(POC_GOTO,popGetLabel(blbl->key));
2584 emitpLabel(albl->key);
2586 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2588 emitpcode(poc,popGet(AOP(left),1));
2589 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2590 emitpcode(poc,popGet(AOP(left),0));
2591 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2593 emitpLabel(blbl->key);
2595 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2597 /* if we need to assign a result value */
2598 if ((IS_ITEMP(IC_RESULT(ic)) &&
2599 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2600 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2601 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2604 aopOp(IC_RESULT(ic),ic,FALSE);
2607 assignResultValue(IC_RESULT(ic));
2609 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2612 /* if register bank was saved then unsave them */
2613 if (currFunc && dtype &&
2614 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2615 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2617 /* if we hade saved some registers then
2620 unsaveRegisters (ic);
2624 /*-----------------------------------------------------------------*/
2625 /* resultRemat - result is rematerializable */
2626 /*-----------------------------------------------------------------*/
2627 static int resultRemat (iCode *ic)
2629 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2630 if (SKIP_IC(ic) || ic->op == IFX)
2633 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2634 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2635 if (sym->remat && !POINTER_SET(ic))
2642 #if defined(__BORLANDC__) || defined(_MSC_VER)
2643 #define STRCASECMP stricmp
2645 #define STRCASECMP strcasecmp
2649 /*-----------------------------------------------------------------*/
2650 /* inExcludeList - return 1 if the string is in exclude Reg list */
2651 /*-----------------------------------------------------------------*/
2652 static bool inExcludeList(char *s)
2654 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2657 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2658 if (options.excludeRegs[i] &&
2659 STRCASECMP(options.excludeRegs[i],"none") == 0)
2662 for ( i = 0 ; options.excludeRegs[i]; i++) {
2663 if (options.excludeRegs[i] &&
2664 STRCASECMP(s,options.excludeRegs[i]) == 0)
2671 /*-----------------------------------------------------------------*/
2672 /* genFunction - generated code for function entry */
2673 /*-----------------------------------------------------------------*/
2674 static void genFunction (iCode *ic)
2679 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2681 labelOffset += (max_key+4);
2685 /* create the function header */
2686 pic14_emitcode(";","-----------------------------------------");
2687 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2688 pic14_emitcode(";","-----------------------------------------");
2690 pic14_emitcode("","%s:",sym->rname);
2691 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2693 ftype = operandType(IC_LEFT(ic));
2695 /* if critical function then turn interrupts off */
2696 if (IFFUNC_ISCRITICAL(ftype))
2697 pic14_emitcode("clr","ea");
2699 /* here we need to generate the equates for the
2700 register bank if required */
2702 if (FUNC_REGBANK(ftype) != rbank) {
2705 rbank = FUNC_REGBANK(ftype);
2706 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2707 if (strcmp(regspic14[i].base,"0") == 0)
2708 pic14_emitcode("","%s = 0x%02x",
2710 8*rbank+regspic14[i].offset);
2712 pic14_emitcode ("","%s = %s + 0x%02x",
2715 8*rbank+regspic14[i].offset);
2720 /* if this is an interrupt service routine */
2721 if (IFFUNC_ISISR(sym->type)) {
2722 /* already done in pic14createInterruptVect() - delete me
2723 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2724 emitpcodeNULLop(POC_NOP);
2725 emitpcodeNULLop(POC_NOP);
2726 emitpcodeNULLop(POC_NOP);
2728 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2729 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2730 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2731 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2732 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2733 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2734 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* durring an interrupt PCLATH must be cleared before a goto or call statement */
2736 pBlockConvert2ISR(pb);
2738 if (!inExcludeList("acc"))
2739 pic14_emitcode ("push","acc");
2740 if (!inExcludeList("b"))
2741 pic14_emitcode ("push","b");
2742 if (!inExcludeList("dpl"))
2743 pic14_emitcode ("push","dpl");
2744 if (!inExcludeList("dph"))
2745 pic14_emitcode ("push","dph");
2746 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2748 pic14_emitcode ("push", "dpx");
2749 /* Make sure we're using standard DPTR */
2750 pic14_emitcode ("push", "dps");
2751 pic14_emitcode ("mov", "dps, #0x00");
2752 if (options.stack10bit)
2754 /* This ISR could conceivably use DPTR2. Better save it. */
2755 pic14_emitcode ("push", "dpl1");
2756 pic14_emitcode ("push", "dph1");
2757 pic14_emitcode ("push", "dpx1");
2760 /* if this isr has no bank i.e. is going to
2761 run with bank 0 , then we need to save more
2763 if (!FUNC_REGBANK(sym->type)) {
2765 /* if this function does not call any other
2766 function then we can be economical and
2767 save only those registers that are used */
2768 if (! IFFUNC_HASFCALL(sym->type)) {
2771 /* if any registers used */
2772 if (sym->regsUsed) {
2773 /* save the registers used */
2774 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2775 if (bitVectBitValue(sym->regsUsed,i) ||
2776 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2777 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2782 /* this function has a function call cannot
2783 determines register usage so we will have the
2785 saverbank(0,ic,FALSE);
2790 /* if callee-save to be used for this function
2791 then save the registers being used in this function */
2792 if (IFFUNC_CALLEESAVES(sym->type)) {
2795 /* if any registers used */
2796 if (sym->regsUsed) {
2797 /* save the registers used */
2798 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2799 if (bitVectBitValue(sym->regsUsed,i) ||
2800 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2801 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2809 /* set the register bank to the desired value */
2810 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2811 pic14_emitcode("push","psw");
2812 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2815 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2817 if (options.useXstack) {
2818 pic14_emitcode("mov","r0,%s",spname);
2819 pic14_emitcode("mov","a,_bp");
2820 pic14_emitcode("movx","@r0,a");
2821 pic14_emitcode("inc","%s",spname);
2825 /* set up the stack */
2826 pic14_emitcode ("push","_bp"); /* save the callers stack */
2828 pic14_emitcode ("mov","_bp,%s",spname);
2831 /* adjust the stack for the function */
2836 werror(W_STACK_OVERFLOW,sym->name);
2838 if (i > 3 && sym->recvSize < 4) {
2840 pic14_emitcode ("mov","a,sp");
2841 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2842 pic14_emitcode ("mov","sp,a");
2847 pic14_emitcode("inc","sp");
2852 pic14_emitcode ("mov","a,_spx");
2853 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2854 pic14_emitcode ("mov","_spx,a");
2859 /*-----------------------------------------------------------------*/
2860 /* genEndFunction - generates epilogue for functions */
2861 /*-----------------------------------------------------------------*/
2862 static void genEndFunction (iCode *ic)
2864 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2868 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2870 pic14_emitcode ("mov","%s,_bp",spname);
2873 /* if use external stack but some variables were
2874 added to the local stack then decrement the
2876 if (options.useXstack && sym->stack) {
2877 pic14_emitcode("mov","a,sp");
2878 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2879 pic14_emitcode("mov","sp,a");
2883 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2884 if (options.useXstack) {
2885 pic14_emitcode("mov","r0,%s",spname);
2886 pic14_emitcode("movx","a,@r0");
2887 pic14_emitcode("mov","_bp,a");
2888 pic14_emitcode("dec","%s",spname);
2892 pic14_emitcode ("pop","_bp");
2896 /* restore the register bank */
2897 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2898 pic14_emitcode ("pop","psw");
2900 if (IFFUNC_ISISR(sym->type)) {
2902 /* now we need to restore the registers */
2903 /* if this isr has no bank i.e. is going to
2904 run with bank 0 , then we need to save more
2906 if (!FUNC_REGBANK(sym->type)) {
2908 /* if this function does not call any other
2909 function then we can be economical and
2910 save only those registers that are used */
2911 if (! IFFUNC_HASFCALL(sym->type)) {
2914 /* if any registers used */
2915 if (sym->regsUsed) {
2916 /* save the registers used */
2917 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2918 if (bitVectBitValue(sym->regsUsed,i) ||
2919 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2920 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2925 /* this function has a function call cannot
2926 determines register usage so we will have the
2928 unsaverbank(0,ic,FALSE);
2932 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2934 if (options.stack10bit)
2936 pic14_emitcode ("pop", "dpx1");
2937 pic14_emitcode ("pop", "dph1");
2938 pic14_emitcode ("pop", "dpl1");
2940 pic14_emitcode ("pop", "dps");
2941 pic14_emitcode ("pop", "dpx");
2943 if (!inExcludeList("dph"))
2944 pic14_emitcode ("pop","dph");
2945 if (!inExcludeList("dpl"))
2946 pic14_emitcode ("pop","dpl");
2947 if (!inExcludeList("b"))
2948 pic14_emitcode ("pop","b");
2949 if (!inExcludeList("acc"))
2950 pic14_emitcode ("pop","acc");
2952 if (IFFUNC_ISCRITICAL(sym->type))
2953 pic14_emitcode("setb","ea");
2956 /* if debug then send end of function */
2957 /* if (options.debug && currFunc) { */
2960 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2961 FileBaseName(ic->filename),currFunc->lastLine,
2962 ic->level,ic->block);
2963 if (IS_STATIC(currFunc->etype))
2964 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2966 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2970 pic14_emitcode ("reti","");
2971 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2972 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2973 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2974 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2975 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2976 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2977 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2978 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2979 emitpcodeNULLop(POC_RETFIE);
2982 if (IFFUNC_ISCRITICAL(sym->type))
2983 pic14_emitcode("setb","ea");
2985 if (IFFUNC_CALLEESAVES(sym->type)) {
2988 /* if any registers used */
2989 if (sym->regsUsed) {
2990 /* save the registers used */
2991 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2992 if (bitVectBitValue(sym->regsUsed,i) ||
2993 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2994 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
3000 /* if debug then send end of function */
3003 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
3004 FileBaseName(ic->filename),currFunc->lastLine,
3005 ic->level,ic->block);
3006 if (IS_STATIC(currFunc->etype))
3007 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
3009 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
3013 pic14_emitcode ("return","");
3014 emitpcodeNULLop(POC_RETURN);
3016 /* Mark the end of a function */
3017 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
3022 /*-----------------------------------------------------------------*/
3023 /* genRet - generate code for return statement */
3024 /*-----------------------------------------------------------------*/
3025 static void genRet (iCode *ic)
3027 int size,offset = 0 , pushed = 0;
3029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3030 /* if we have no return value then
3031 just generate the "ret" */
3035 /* we have something to return then
3036 move the return value into place */
3037 aopOp(IC_LEFT(ic),ic,FALSE);
3038 size = AOP_SIZE(IC_LEFT(ic));
3042 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3044 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3046 pic14_emitcode("push","%s",l);
3049 l = aopGet(AOP(IC_LEFT(ic)),offset,
3051 if (strcmp(fReturn[offset],l)) {
3052 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
3053 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3054 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3055 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3056 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3058 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3061 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3071 if (strcmp(fReturn[pushed],"a"))
3072 pic14_emitcode("pop",fReturn[pushed]);
3074 pic14_emitcode("pop","acc");
3077 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3080 /* generate a jump to the return label
3081 if the next is not the return statement */
3082 if (!(ic->next && ic->next->op == LABEL &&
3083 IC_LABEL(ic->next) == returnLabel)) {
3085 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3086 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3091 /*-----------------------------------------------------------------*/
3092 /* genLabel - generates a label */
3093 /*-----------------------------------------------------------------*/
3094 static void genLabel (iCode *ic)
3096 /* special case never generate */
3097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3098 if (IC_LABEL(ic) == entryLabel)
3101 emitpLabel(IC_LABEL(ic)->key);
3102 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3105 /*-----------------------------------------------------------------*/
3106 /* genGoto - generates a goto */
3107 /*-----------------------------------------------------------------*/
3109 static void genGoto (iCode *ic)
3111 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3112 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3116 /*-----------------------------------------------------------------*/
3117 /* genMultbits :- multiplication of bits */
3118 /*-----------------------------------------------------------------*/
3119 static void genMultbits (operand *left,
3123 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3125 if(!pic14_sameRegs(AOP(result),AOP(right)))
3126 emitpcode(POC_BSF, popGet(AOP(result),0));
3128 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3129 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3130 emitpcode(POC_BCF, popGet(AOP(result),0));
3135 /*-----------------------------------------------------------------*/
3136 /* genMultOneByte : 8 bit multiplication & division */
3137 /*-----------------------------------------------------------------*/
3138 static void genMultOneByte (operand *left,
3142 sym_link *opetype = operandType(result);
3147 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3148 DEBUGpic14_AopType(__LINE__,left,right,result);
3149 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3151 /* (if two literals, the value is computed before) */
3152 /* if one literal, literal on the right */
3153 if (AOP_TYPE(left) == AOP_LIT){
3159 size = AOP_SIZE(result);
3162 if (AOP_TYPE(right) == AOP_LIT){
3163 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3164 aopGet(AOP(right),0,FALSE,FALSE),
3165 aopGet(AOP(left),0,FALSE,FALSE),
3166 aopGet(AOP(result),0,FALSE,FALSE));
3167 pic14_emitcode("call","genMultLit");
3169 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3170 aopGet(AOP(right),0,FALSE,FALSE),
3171 aopGet(AOP(left),0,FALSE,FALSE),
3172 aopGet(AOP(result),0,FALSE,FALSE));
3173 pic14_emitcode("call","genMult8X8_8");
3176 genMult8X8_8 (left, right,result);
3179 /* signed or unsigned */
3180 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3181 //l = aopGet(AOP(left),0,FALSE,FALSE);
3183 //pic14_emitcode("mul","ab");
3184 /* if result size = 1, mul signed = mul unsigned */
3185 //aopPut(AOP(result),"a",0);
3187 } else { // (size > 1)
3189 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3190 aopGet(AOP(right),0,FALSE,FALSE),
3191 aopGet(AOP(left),0,FALSE,FALSE),
3192 aopGet(AOP(result),0,FALSE,FALSE));
3194 if (SPEC_USIGN(opetype)){
3195 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3196 genUMult8X8_16 (left, right, result, NULL);
3199 /* for filling the MSBs */
3200 emitpcode(POC_CLRF, popGet(AOP(result),2));
3201 emitpcode(POC_CLRF, popGet(AOP(result),3));
3205 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3207 pic14_emitcode("mov","a,b");
3209 /* adjust the MSB if left or right neg */
3211 /* if one literal */
3212 if (AOP_TYPE(right) == AOP_LIT){
3213 pic14_emitcode("multiply ","right is a lit");
3214 /* AND literal negative */
3215 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3216 /* adjust MSB (c==0 after mul) */
3217 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3221 genSMult8X8_16 (left, right, result, NULL);
3225 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3227 pic14_emitcode("rlc","a");
3228 pic14_emitcode("subb","a,acc");
3236 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3237 //aopPut(AOP(result),"a",offset++);
3241 /*-----------------------------------------------------------------*/
3242 /* genMult - generates code for multiplication */
3243 /*-----------------------------------------------------------------*/
3244 static void genMult (iCode *ic)
3246 operand *left = IC_LEFT(ic);
3247 operand *right = IC_RIGHT(ic);
3248 operand *result= IC_RESULT(ic);
3250 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3251 /* assign the amsops */
3252 aopOp (left,ic,FALSE);
3253 aopOp (right,ic,FALSE);
3254 aopOp (result,ic,TRUE);
3256 DEBUGpic14_AopType(__LINE__,left,right,result);
3258 /* special cases first */
3260 if (AOP_TYPE(left) == AOP_CRY &&
3261 AOP_TYPE(right)== AOP_CRY) {
3262 genMultbits(left,right,result);
3266 /* if both are of size == 1 */
3267 if (AOP_SIZE(left) == 1 &&
3268 AOP_SIZE(right) == 1 ) {
3269 genMultOneByte(left,right,result);
3273 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3275 /* should have been converted to function call */
3279 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3280 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3281 freeAsmop(result,NULL,ic,TRUE);
3284 /*-----------------------------------------------------------------*/
3285 /* genDivbits :- division of bits */
3286 /*-----------------------------------------------------------------*/
3287 static void genDivbits (operand *left,
3294 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3295 /* the result must be bit */
3296 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3297 l = aopGet(AOP(left),0,FALSE,FALSE);
3301 pic14_emitcode("div","ab");
3302 pic14_emitcode("rrc","a");
3303 aopPut(AOP(result),"c",0);
3306 /*-----------------------------------------------------------------*/
3307 /* genDivOneByte : 8 bit division */
3308 /*-----------------------------------------------------------------*/
3309 static void genDivOneByte (operand *left,
3313 sym_link *opetype = operandType(result);
3318 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3319 size = AOP_SIZE(result) - 1;
3321 /* signed or unsigned */
3322 if (SPEC_USIGN(opetype)) {
3323 /* unsigned is easy */
3324 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3325 l = aopGet(AOP(left),0,FALSE,FALSE);
3327 pic14_emitcode("div","ab");
3328 aopPut(AOP(result),"a",0);
3330 aopPut(AOP(result),zero,offset++);
3334 /* signed is a little bit more difficult */
3336 /* save the signs of the operands */
3337 l = aopGet(AOP(left),0,FALSE,FALSE);
3339 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3340 pic14_emitcode("push","acc"); /* save it on the stack */
3342 /* now sign adjust for both left & right */
3343 l = aopGet(AOP(right),0,FALSE,FALSE);
3345 lbl = newiTempLabel(NULL);
3346 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3347 pic14_emitcode("cpl","a");
3348 pic14_emitcode("inc","a");
3349 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3350 pic14_emitcode("mov","b,a");
3352 /* sign adjust left side */
3353 l = aopGet(AOP(left),0,FALSE,FALSE);
3356 lbl = newiTempLabel(NULL);
3357 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3358 pic14_emitcode("cpl","a");
3359 pic14_emitcode("inc","a");
3360 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3362 /* now the division */
3363 pic14_emitcode("div","ab");
3364 /* we are interested in the lower order
3366 pic14_emitcode("mov","b,a");
3367 lbl = newiTempLabel(NULL);
3368 pic14_emitcode("pop","acc");
3369 /* if there was an over flow we don't
3370 adjust the sign of the result */
3371 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3372 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3374 pic14_emitcode("clr","a");
3375 pic14_emitcode("subb","a,b");
3376 pic14_emitcode("mov","b,a");
3377 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3379 /* now we are done */
3380 aopPut(AOP(result),"b",0);
3382 pic14_emitcode("mov","c,b.7");
3383 pic14_emitcode("subb","a,acc");
3386 aopPut(AOP(result),"a",offset++);
3390 /*-----------------------------------------------------------------*/
3391 /* genDiv - generates code for division */
3392 /*-----------------------------------------------------------------*/
3393 static void genDiv (iCode *ic)
3395 operand *left = IC_LEFT(ic);
3396 operand *right = IC_RIGHT(ic);
3397 operand *result= IC_RESULT(ic);
3399 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3400 /* assign the amsops */
3401 aopOp (left,ic,FALSE);
3402 aopOp (right,ic,FALSE);
3403 aopOp (result,ic,TRUE);
3405 /* special cases first */
3407 if (AOP_TYPE(left) == AOP_CRY &&
3408 AOP_TYPE(right)== AOP_CRY) {
3409 genDivbits(left,right,result);
3413 /* if both are of size == 1 */
3414 if (AOP_SIZE(left) == 1 &&
3415 AOP_SIZE(right) == 1 ) {
3416 genDivOneByte(left,right,result);
3420 /* should have been converted to function call */
3423 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3424 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3425 freeAsmop(result,NULL,ic,TRUE);
3428 /*-----------------------------------------------------------------*/
3429 /* genModbits :- modulus of bits */
3430 /*-----------------------------------------------------------------*/
3431 static void genModbits (operand *left,
3438 /* the result must be bit */
3439 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3440 l = aopGet(AOP(left),0,FALSE,FALSE);
3444 pic14_emitcode("div","ab");
3445 pic14_emitcode("mov","a,b");
3446 pic14_emitcode("rrc","a");
3447 aopPut(AOP(result),"c",0);
3450 /*-----------------------------------------------------------------*/
3451 /* genModOneByte : 8 bit modulus */
3452 /*-----------------------------------------------------------------*/
3453 static void genModOneByte (operand *left,
3457 sym_link *opetype = operandType(result);
3461 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3462 /* signed or unsigned */
3463 if (SPEC_USIGN(opetype)) {
3464 /* unsigned is easy */
3465 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3466 l = aopGet(AOP(left),0,FALSE,FALSE);
3468 pic14_emitcode("div","ab");
3469 aopPut(AOP(result),"b",0);
3473 /* signed is a little bit more difficult */
3475 /* save the signs of the operands */
3476 l = aopGet(AOP(left),0,FALSE,FALSE);
3479 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3480 pic14_emitcode("push","acc"); /* save it on the stack */
3482 /* now sign adjust for both left & right */
3483 l = aopGet(AOP(right),0,FALSE,FALSE);
3486 lbl = newiTempLabel(NULL);
3487 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3488 pic14_emitcode("cpl","a");
3489 pic14_emitcode("inc","a");
3490 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3491 pic14_emitcode("mov","b,a");
3493 /* sign adjust left side */
3494 l = aopGet(AOP(left),0,FALSE,FALSE);
3497 lbl = newiTempLabel(NULL);
3498 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3499 pic14_emitcode("cpl","a");
3500 pic14_emitcode("inc","a");
3501 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3503 /* now the multiplication */
3504 pic14_emitcode("div","ab");
3505 /* we are interested in the lower order
3507 lbl = newiTempLabel(NULL);
3508 pic14_emitcode("pop","acc");
3509 /* if there was an over flow we don't
3510 adjust the sign of the result */
3511 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3512 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3514 pic14_emitcode("clr","a");
3515 pic14_emitcode("subb","a,b");
3516 pic14_emitcode("mov","b,a");
3517 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3519 /* now we are done */
3520 aopPut(AOP(result),"b",0);
3524 /*-----------------------------------------------------------------*/
3525 /* genMod - generates code for division */
3526 /*-----------------------------------------------------------------*/
3527 static void genMod (iCode *ic)
3529 operand *left = IC_LEFT(ic);
3530 operand *right = IC_RIGHT(ic);
3531 operand *result= IC_RESULT(ic);
3533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3534 /* assign the amsops */
3535 aopOp (left,ic,FALSE);
3536 aopOp (right,ic,FALSE);
3537 aopOp (result,ic,TRUE);
3539 /* special cases first */
3541 if (AOP_TYPE(left) == AOP_CRY &&
3542 AOP_TYPE(right)== AOP_CRY) {
3543 genModbits(left,right,result);
3547 /* if both are of size == 1 */
3548 if (AOP_SIZE(left) == 1 &&
3549 AOP_SIZE(right) == 1 ) {
3550 genModOneByte(left,right,result);
3554 /* should have been converted to function call */
3558 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3559 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3560 freeAsmop(result,NULL,ic,TRUE);
3563 /*-----------------------------------------------------------------*/
3564 /* genIfxJump :- will create a jump depending on the ifx */
3565 /*-----------------------------------------------------------------*/
3567 note: May need to add parameter to indicate when a variable is in bit space.
3569 static void genIfxJump (iCode *ic, char *jval)
3572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3573 /* if true label then we jump if condition
3575 if ( IC_TRUE(ic) ) {
3577 if(strcmp(jval,"a") == 0)
3579 else if (strcmp(jval,"c") == 0)
3582 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3583 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3586 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3587 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3591 /* false label is present */
3592 if(strcmp(jval,"a") == 0)
3594 else if (strcmp(jval,"c") == 0)
3597 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3598 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3601 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3602 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3607 /* mark the icode as generated */
3611 /*-----------------------------------------------------------------*/
3613 /*-----------------------------------------------------------------*/
3614 static void genSkip(iCode *ifx,int status_bit)
3619 if ( IC_TRUE(ifx) ) {
3620 switch(status_bit) {
3635 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3636 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3640 switch(status_bit) {
3654 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3655 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3661 /*-----------------------------------------------------------------*/
3663 /*-----------------------------------------------------------------*/
3664 static void genSkipc(resolvedIfx *rifx)
3674 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3675 rifx->generated = 1;
3678 /*-----------------------------------------------------------------*/
3680 /*-----------------------------------------------------------------*/
3681 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3686 if( (rifx->condition ^ invert_condition) & 1)
3691 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3692 rifx->generated = 1;
3695 /*-----------------------------------------------------------------*/
3697 /*-----------------------------------------------------------------*/
3698 static void genSkipz(iCode *ifx, int condition)
3709 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3711 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3714 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3716 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3719 /*-----------------------------------------------------------------*/
3721 /*-----------------------------------------------------------------*/
3722 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3728 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3730 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3733 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3734 rifx->generated = 1;
3738 /*-----------------------------------------------------------------*/
3739 /* genChkZeroes :- greater or less than comparison */
3740 /* For each byte in a literal that is zero, inclusive or the */
3741 /* the corresponding byte in the operand with W */
3742 /* returns true if any of the bytes are zero */
3743 /*-----------------------------------------------------------------*/
3744 static int genChkZeroes(operand *op, int lit, int size)
3751 i = (lit >> (size*8)) & 0xff;
3755 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3757 emitpcode(POC_IORFW, popGet(AOP(op),size));
3766 /*-----------------------------------------------------------------*/
3767 /* genCmp :- greater or less than comparison */
3768 /*-----------------------------------------------------------------*/
3769 static void genCmp (operand *left,operand *right,
3770 operand *result, iCode *ifx, int sign)
3772 int size; //, offset = 0 ;
3773 unsigned long lit = 0L,i = 0;
3774 resolvedIfx rFalseIfx;
3775 // resolvedIfx rTrueIfx;
3777 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3780 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3781 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3785 resolveIfx(&rFalseIfx,ifx);
3786 truelbl = newiTempLabel(NULL);
3787 size = max(AOP_SIZE(left),AOP_SIZE(right));
3789 DEBUGpic14_AopType(__LINE__,left,right,result);
3793 /* if literal is on the right then swap with left */
3794 if ((AOP_TYPE(right) == AOP_LIT)) {
3795 operand *tmp = right ;
3796 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3797 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3800 lit = (lit - 1) & mask;
3803 rFalseIfx.condition ^= 1;
3806 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3807 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3811 //if(IC_TRUE(ifx) == NULL)
3812 /* if left & right are bit variables */
3813 if (AOP_TYPE(left) == AOP_CRY &&
3814 AOP_TYPE(right) == AOP_CRY ) {
3815 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3816 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3818 /* subtract right from left if at the
3819 end the carry flag is set then we know that
3820 left is greater than right */
3824 symbol *lbl = newiTempLabel(NULL);
3827 if(AOP_TYPE(right) == AOP_LIT) {
3829 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3831 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3838 genSkipCond(&rFalseIfx,left,size-1,7);
3840 /* no need to compare to 0...*/
3841 /* NOTE: this is a de-generate compare that most certainly
3842 * creates some dead code. */
3843 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3845 if(ifx) ifx->generated = 1;
3852 //i = (lit >> (size*8)) & 0xff;
3853 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3855 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3857 i = ((0-lit) & 0xff);
3860 /* lit is 0x7f, all signed chars are less than
3861 * this except for 0x7f itself */
3862 emitpcode(POC_XORLW, popGetLit(0x7f));
3863 genSkipz2(&rFalseIfx,0);
3865 emitpcode(POC_ADDLW, popGetLit(0x80));
3866 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3867 genSkipc(&rFalseIfx);
3872 genSkipz2(&rFalseIfx,1);
3874 emitpcode(POC_ADDLW, popGetLit(i));
3875 genSkipc(&rFalseIfx);
3879 if(ifx) ifx->generated = 1;
3883 /* chars are out of the way. now do ints and longs */
3886 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3893 genSkipCond(&rFalseIfx,left,size,7);
3894 if(ifx) ifx->generated = 1;
3899 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3901 //rFalseIfx.condition ^= 1;
3902 //genSkipCond(&rFalseIfx,left,size,7);
3903 //rFalseIfx.condition ^= 1;
3905 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3906 if(rFalseIfx.condition)
3907 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3909 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3911 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3912 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3913 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3916 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3918 if(rFalseIfx.condition) {
3920 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3926 genSkipc(&rFalseIfx);
3927 emitpLabel(truelbl->key);
3928 if(ifx) ifx->generated = 1;
3935 if( (lit & 0xff) == 0) {
3936 /* lower byte is zero */
3937 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3938 i = ((lit >> 8) & 0xff) ^0x80;
3939 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3940 emitpcode(POC_ADDLW, popGetLit( 0x80));
3941 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3942 genSkipc(&rFalseIfx);
3945 if(ifx) ifx->generated = 1;
3950 /* Special cases for signed longs */
3951 if( (lit & 0xffffff) == 0) {
3952 /* lower byte is zero */
3953 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3954 i = ((lit >> 8*3) & 0xff) ^0x80;
3955 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3956 emitpcode(POC_ADDLW, popGetLit( 0x80));
3957 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3958 genSkipc(&rFalseIfx);
3961 if(ifx) ifx->generated = 1;
3969 if(lit & (0x80 << (size*8))) {
3970 /* lit is negative */
3971 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3973 //genSkipCond(&rFalseIfx,left,size,7);
3975 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3977 if(rFalseIfx.condition)
3978 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3980 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3984 /* lit is positive */
3985 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3986 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3987 if(rFalseIfx.condition)
3988 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3990 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3995 This works, but is only good for ints.
3996 It also requires a "known zero" register.
3997 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3998 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3999 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
4000 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
4001 emitpcode(POC_ADDFW, popGet(AOP(left),1));
4002 genSkipc(&rFalseIfx);
4004 emitpLabel(truelbl->key);
4005 if(ifx) ifx->generated = 1;
4009 /* There are no more special cases, so perform a general compare */
4011 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
4012 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4016 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
4018 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4020 //rFalseIfx.condition ^= 1;
4021 genSkipc(&rFalseIfx);
4023 emitpLabel(truelbl->key);
4025 if(ifx) ifx->generated = 1;
4032 /* sign is out of the way. So now do an unsigned compare */
4033 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4036 /* General case - compare to an unsigned literal on the right.*/
4038 i = (lit >> (size*8)) & 0xff;
4039 emitpcode(POC_MOVLW, popGetLit(i));
4040 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4042 i = (lit >> (size*8)) & 0xff;
4045 emitpcode(POC_MOVLW, popGetLit(i));
4047 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4049 /* this byte of the lit is zero,
4050 *if it's not the last then OR in the variable */
4052 emitpcode(POC_IORFW, popGet(AOP(left),size));
4057 emitpLabel(lbl->key);
4058 //if(emitFinalCheck)
4059 genSkipc(&rFalseIfx);
4061 emitpLabel(truelbl->key);
4063 if(ifx) ifx->generated = 1;
4070 if(AOP_TYPE(left) == AOP_LIT) {
4071 //symbol *lbl = newiTempLabel(NULL);
4073 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4076 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4079 if((lit == 0) && (sign == 0)){
4082 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4084 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4086 genSkipz2(&rFalseIfx,0);
4087 if(ifx) ifx->generated = 1;
4094 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4095 /* degenerate compare can never be true */
4096 if(rFalseIfx.condition == 0)
4097 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4099 if(ifx) ifx->generated = 1;
4104 /* signed comparisons to a literal byte */
4106 int lp1 = (lit+1) & 0xff;
4108 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4111 rFalseIfx.condition ^= 1;
4112 genSkipCond(&rFalseIfx,right,0,7);
4115 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4116 emitpcode(POC_XORLW, popGetLit(0x7f));
4117 genSkipz2(&rFalseIfx,1);
4120 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4121 emitpcode(POC_ADDLW, popGetLit(0x80));
4122 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4123 rFalseIfx.condition ^= 1;
4124 genSkipc(&rFalseIfx);
4127 if(ifx) ifx->generated = 1;
4129 /* unsigned comparisons to a literal byte */
4131 switch(lit & 0xff ) {
4133 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4134 genSkipz2(&rFalseIfx,0);
4135 if(ifx) ifx->generated = 1;
4138 rFalseIfx.condition ^= 1;
4139 genSkipCond(&rFalseIfx,right,0,7);
4140 if(ifx) ifx->generated = 1;
4144 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4145 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4146 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4147 rFalseIfx.condition ^= 1;
4148 if (AOP_TYPE(result) == AOP_CRY) {
4149 genSkipc(&rFalseIfx);
4150 if(ifx) ifx->generated = 1;
4152 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4153 emitpcode(POC_CLRF, popGet(AOP(result),0));
4154 emitpcode(POC_RLF, popGet(AOP(result),0));
4155 emitpcode(POC_MOVLW, popGetLit(0x01));
4156 emitpcode(POC_XORWF, popGet(AOP(result),0));
4167 /* Size is greater than 1 */
4175 /* this means lit = 0xffffffff, or -1 */
4178 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4179 rFalseIfx.condition ^= 1;
4180 genSkipCond(&rFalseIfx,right,size,7);
4181 if(ifx) ifx->generated = 1;
4188 if(rFalseIfx.condition) {
4189 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4190 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4193 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4195 emitpcode(POC_IORFW, popGet(AOP(right),size));
4199 if(rFalseIfx.condition) {
4200 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4201 emitpLabel(truelbl->key);
4203 rFalseIfx.condition ^= 1;
4204 genSkipCond(&rFalseIfx,right,s,7);
4207 if(ifx) ifx->generated = 1;
4211 if((size == 1) && (0 == (lp1&0xff))) {
4212 /* lower byte of signed word is zero */
4213 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4214 i = ((lp1 >> 8) & 0xff) ^0x80;
4215 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4216 emitpcode(POC_ADDLW, popGetLit( 0x80));
4217 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4218 rFalseIfx.condition ^= 1;
4219 genSkipc(&rFalseIfx);
4222 if(ifx) ifx->generated = 1;
4226 if(lit & (0x80 << (size*8))) {
4227 /* Lit is less than zero */
4228 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4229 //rFalseIfx.condition ^= 1;
4230 //genSkipCond(&rFalseIfx,left,size,7);
4231 //rFalseIfx.condition ^= 1;
4232 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4233 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4235 if(rFalseIfx.condition)
4236 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4238 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4242 /* Lit is greater than or equal to zero */
4243 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4244 //rFalseIfx.condition ^= 1;
4245 //genSkipCond(&rFalseIfx,right,size,7);
4246 //rFalseIfx.condition ^= 1;
4248 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4249 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4251 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4252 if(rFalseIfx.condition)
4253 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4255 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4260 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4261 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4265 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4267 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4269 rFalseIfx.condition ^= 1;
4270 //rFalseIfx.condition = 1;
4271 genSkipc(&rFalseIfx);
4273 emitpLabel(truelbl->key);
4275 if(ifx) ifx->generated = 1;
4280 /* compare word or long to an unsigned literal on the right.*/
4285 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4288 break; /* handled above */
4291 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4293 emitpcode(POC_IORFW, popGet(AOP(right),size));
4294 genSkipz2(&rFalseIfx,0);
4298 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4300 emitpcode(POC_IORFW, popGet(AOP(right),size));
4303 if(rFalseIfx.condition)
4304 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4306 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4309 emitpcode(POC_MOVLW, popGetLit(lit+1));
4310 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4312 rFalseIfx.condition ^= 1;
4313 genSkipc(&rFalseIfx);
4316 emitpLabel(truelbl->key);
4318 if(ifx) ifx->generated = 1;
4324 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4325 i = (lit >> (size*8)) & 0xff;
4327 emitpcode(POC_MOVLW, popGetLit(i));
4328 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4331 i = (lit >> (size*8)) & 0xff;
4334 emitpcode(POC_MOVLW, popGetLit(i));
4336 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4338 /* this byte of the lit is zero,
4339 *if it's not the last then OR in the variable */
4341 emitpcode(POC_IORFW, popGet(AOP(right),size));
4346 emitpLabel(lbl->key);
4348 rFalseIfx.condition ^= 1;
4349 genSkipc(&rFalseIfx);
4353 emitpLabel(truelbl->key);
4354 if(ifx) ifx->generated = 1;
4358 /* Compare two variables */
4360 DEBUGpic14_emitcode(";sign","%d",sign);
4364 /* Sigh. thus sucks... */
4366 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4367 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4368 emitpcode(POC_MOVLW, popGetLit(0x80));
4369 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4370 emitpcode(POC_XORFW, popGet(AOP(right),size));
4371 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4373 /* Signed char comparison */
4374 /* Special thanks to Nikolai Golovchenko for this snippet */
4375 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4376 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4377 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4378 emitpcode(POC_XORFW, popGet(AOP(left),0));
4379 emitpcode(POC_XORFW, popGet(AOP(right),0));
4380 emitpcode(POC_ADDLW, popGetLit(0x80));
4382 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4383 genSkipc(&rFalseIfx);
4385 if(ifx) ifx->generated = 1;
4391 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4392 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4396 /* The rest of the bytes of a multi-byte compare */
4400 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4403 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4404 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4409 emitpLabel(lbl->key);
4411 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4412 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4413 (AOP_TYPE(result) == AOP_REG)) {
4414 emitpcode(POC_CLRF, popGet(AOP(result),0));
4415 emitpcode(POC_RLF, popGet(AOP(result),0));
4417 genSkipc(&rFalseIfx);
4419 //genSkipc(&rFalseIfx);
4420 if(ifx) ifx->generated = 1;
4427 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4429 pic14_outBitC(result);
4431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4432 /* if the result is used in the next
4433 ifx conditional branch then generate
4434 code a little differently */
4436 genIfxJump (ifx,"c");
4438 pic14_outBitC(result);
4439 /* leave the result in acc */
4444 /*-----------------------------------------------------------------*/
4445 /* genCmpGt :- greater than comparison */
4446 /*-----------------------------------------------------------------*/
4447 static void genCmpGt (iCode *ic, iCode *ifx)
4449 operand *left, *right, *result;
4450 sym_link *letype , *retype;
4453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4455 right= IC_RIGHT(ic);
4456 result = IC_RESULT(ic);
4458 letype = getSpec(operandType(left));
4459 retype =getSpec(operandType(right));
4460 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4461 /* assign the amsops */
4462 aopOp (left,ic,FALSE);
4463 aopOp (right,ic,FALSE);
4464 aopOp (result,ic,TRUE);
4466 genCmp(right, left, result, ifx, sign);
4468 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4469 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4470 freeAsmop(result,NULL,ic,TRUE);
4473 /*-----------------------------------------------------------------*/
4474 /* genCmpLt - less than comparisons */
4475 /*-----------------------------------------------------------------*/
4476 static void genCmpLt (iCode *ic, iCode *ifx)
4478 operand *left, *right, *result;
4479 sym_link *letype , *retype;
4482 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4484 right= IC_RIGHT(ic);
4485 result = IC_RESULT(ic);
4487 letype = getSpec(operandType(left));
4488 retype =getSpec(operandType(right));
4489 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4491 /* assign the amsops */
4492 aopOp (left,ic,FALSE);
4493 aopOp (right,ic,FALSE);
4494 aopOp (result,ic,TRUE);
4496 genCmp(left, right, result, ifx, sign);
4498 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4499 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4500 freeAsmop(result,NULL,ic,TRUE);
4503 /*-----------------------------------------------------------------*/
4504 /* genc16bit2lit - compare a 16 bit value to a literal */
4505 /*-----------------------------------------------------------------*/
4506 static void genc16bit2lit(operand *op, int lit, int offset)
4510 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4511 if( (lit&0xff) == 0)
4516 switch( BYTEofLONG(lit,i)) {
4518 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4521 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4524 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4527 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4528 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4533 switch( BYTEofLONG(lit,i)) {
4535 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4539 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4543 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4546 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4548 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4554 /*-----------------------------------------------------------------*/
4555 /* gencjneshort - compare and jump if not equal */
4556 /*-----------------------------------------------------------------*/
4557 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4559 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4561 int res_offset = 0; /* the result may be a different size then left or right */
4562 int res_size = AOP_SIZE(result);
4566 unsigned long lit = 0L;
4567 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4568 DEBUGpic14_AopType(__LINE__,left,right,result);
4570 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4571 resolveIfx(&rIfx,ifx);
4572 lbl = newiTempLabel(NULL);
4575 /* if the left side is a literal or
4576 if the right is in a pointer register and left
4578 if ((AOP_TYPE(left) == AOP_LIT) ||
4579 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4584 if(AOP_TYPE(right) == AOP_LIT)
4585 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4587 /* if the right side is a literal then anything goes */
4588 if (AOP_TYPE(right) == AOP_LIT &&
4589 AOP_TYPE(left) != AOP_DIR ) {
4592 genc16bit2lit(left, lit, 0);
4594 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4599 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4600 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4602 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4606 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4608 if(res_offset < res_size-1)
4616 /* if the right side is in a register or in direct space or
4617 if the left is a pointer register & right is not */
4618 else if (AOP_TYPE(right) == AOP_REG ||
4619 AOP_TYPE(right) == AOP_DIR ||
4620 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4621 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4622 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4623 int lbl_key = lbl->key;
4626 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4627 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4629 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4630 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4631 __FUNCTION__,__LINE__);
4635 /* switch(size) { */
4637 /* genc16bit2lit(left, lit, 0); */
4639 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4644 if((AOP_TYPE(left) == AOP_DIR) &&
4645 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4647 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4648 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4650 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4652 switch (lit & 0xff) {
4654 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4657 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4658 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4659 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4663 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4664 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4665 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4666 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4670 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4671 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4676 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4679 if(AOP_TYPE(result) == AOP_CRY) {
4680 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4685 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4687 /* fix me. probably need to check result size too */
4688 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4693 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4694 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4701 if(res_offset < res_size-1)
4706 } else if(AOP_TYPE(right) == AOP_REG &&
4707 AOP_TYPE(left) != AOP_DIR){
4710 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4711 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4712 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4717 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4719 if(res_offset < res_size-1)
4724 /* right is a pointer reg need both a & b */
4726 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4728 pic14_emitcode("mov","b,%s",l);
4729 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4730 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4735 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4737 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4739 emitpLabel(lbl->key);
4741 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4748 /*-----------------------------------------------------------------*/
4749 /* gencjne - compare and jump if not equal */
4750 /*-----------------------------------------------------------------*/
4751 static void gencjne(operand *left, operand *right, iCode *ifx)
4753 symbol *tlbl = newiTempLabel(NULL);
4755 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4756 gencjneshort(left, right, lbl);
4758 pic14_emitcode("mov","a,%s",one);
4759 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4760 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4761 pic14_emitcode("clr","a");
4762 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4764 emitpLabel(lbl->key);
4765 emitpLabel(tlbl->key);
4770 /*-----------------------------------------------------------------*/
4771 /* genCmpEq - generates code for equal to */
4772 /*-----------------------------------------------------------------*/
4773 static void genCmpEq (iCode *ic, iCode *ifx)
4775 operand *left, *right, *result;
4776 unsigned long lit = 0L;
4779 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4782 DEBUGpic14_emitcode ("; ifx is non-null","");
4784 DEBUGpic14_emitcode ("; ifx is null","");
4786 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4787 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4788 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4790 size = max(AOP_SIZE(left),AOP_SIZE(right));
4792 DEBUGpic14_AopType(__LINE__,left,right,result);
4794 /* if literal, literal on the right or
4795 if the right is in a pointer register and left
4797 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4798 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4799 operand *tmp = right ;
4805 if(ifx && !AOP_SIZE(result)){
4807 /* if they are both bit variables */
4808 if (AOP_TYPE(left) == AOP_CRY &&
4809 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4810 if(AOP_TYPE(right) == AOP_LIT){
4811 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4813 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4814 pic14_emitcode("cpl","c");
4815 } else if(lit == 1L) {
4816 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4818 pic14_emitcode("clr","c");
4820 /* AOP_TYPE(right) == AOP_CRY */
4822 symbol *lbl = newiTempLabel(NULL);
4823 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4824 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4825 pic14_emitcode("cpl","c");
4826 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4828 /* if true label then we jump if condition
4830 tlbl = newiTempLabel(NULL);
4831 if ( IC_TRUE(ifx) ) {
4832 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4833 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4835 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4836 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4838 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4841 /* left and right are both bit variables, result is carry */
4844 resolveIfx(&rIfx,ifx);
4846 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4847 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4848 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4849 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4854 /* They're not both bit variables. Is the right a literal? */
4855 if(AOP_TYPE(right) == AOP_LIT) {
4856 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4861 switch(lit & 0xff) {
4863 if ( IC_TRUE(ifx) ) {
4864 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4866 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4868 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4869 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4873 if ( IC_TRUE(ifx) ) {
4874 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4876 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4878 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4879 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4883 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4885 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4890 /* end of size == 1 */
4894 genc16bit2lit(left,lit,offset);
4897 /* end of size == 2 */
4902 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4903 emitpcode(POC_IORFW,popGet(AOP(left),1));
4904 emitpcode(POC_IORFW,popGet(AOP(left),2));
4905 emitpcode(POC_IORFW,popGet(AOP(left),3));
4909 /* search for patterns that can be optimized */
4911 genc16bit2lit(left,lit,0);
4914 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4916 genc16bit2lit(left,lit,2);
4918 emitpcode(POC_IORFW,popGet(AOP(left),2));
4919 emitpcode(POC_IORFW,popGet(AOP(left),3));
4932 } else if(AOP_TYPE(right) == AOP_CRY ) {
4933 /* we know the left is not a bit, but that the right is */
4934 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4935 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4936 popGet(AOP(right),offset));
4937 emitpcode(POC_XORLW,popGetLit(1));
4939 /* if the two are equal, then W will be 0 and the Z bit is set
4940 * we could test Z now, or go ahead and check the high order bytes if
4941 * the variable we're comparing is larger than a byte. */
4944 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4946 if ( IC_TRUE(ifx) ) {
4948 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4949 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4952 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4953 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4957 /* They're both variables that are larger than bits */
4960 tlbl = newiTempLabel(NULL);
4963 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4964 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4966 if ( IC_TRUE(ifx) ) {
4969 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4970 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4973 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4974 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4978 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4979 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4983 if(s>1 && IC_TRUE(ifx)) {
4984 emitpLabel(tlbl->key);
4985 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4989 /* mark the icode as generated */
4994 /* if they are both bit variables */
4995 if (AOP_TYPE(left) == AOP_CRY &&
4996 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4997 if(AOP_TYPE(right) == AOP_LIT){
4998 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
5000 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5001 pic14_emitcode("cpl","c");
5002 } else if(lit == 1L) {
5003 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5005 pic14_emitcode("clr","c");
5007 /* AOP_TYPE(right) == AOP_CRY */
5009 symbol *lbl = newiTempLabel(NULL);
5010 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5011 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
5012 pic14_emitcode("cpl","c");
5013 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
5016 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
5017 pic14_outBitC(result);
5021 genIfxJump (ifx,"c");
5024 /* if the result is used in an arithmetic operation
5025 then put the result in place */
5026 pic14_outBitC(result);
5029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5030 gencjne(left,right,result,ifx);
5033 gencjne(left,right,newiTempLabel(NULL));
5035 if(IC_TRUE(ifx)->key)
5036 gencjne(left,right,IC_TRUE(ifx)->key);
5038 gencjne(left,right,IC_FALSE(ifx)->key);
5042 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5043 aopPut(AOP(result),"a",0);
5048 genIfxJump (ifx,"a");
5052 /* if the result is used in an arithmetic operation
5053 then put the result in place */
5055 if (AOP_TYPE(result) != AOP_CRY)
5056 pic14_outAcc(result);
5058 /* leave the result in acc */
5062 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5063 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5064 freeAsmop(result,NULL,ic,TRUE);
5067 /*-----------------------------------------------------------------*/
5068 /* ifxForOp - returns the icode containing the ifx for operand */
5069 /*-----------------------------------------------------------------*/
5070 static iCode *ifxForOp ( operand *op, iCode *ic )
5072 /* if true symbol then needs to be assigned */
5073 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5074 if (IS_TRUE_SYMOP(op))
5077 /* if this has register type condition and
5078 the next instruction is ifx with the same operand
5079 and live to of the operand is upto the ifx only then */
5081 ic->next->op == IFX &&
5082 IC_COND(ic->next)->key == op->key &&
5083 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5087 ic->next->op == IFX &&
5088 IC_COND(ic->next)->key == op->key) {
5089 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5093 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5095 ic->next->op == IFX)
5096 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5099 ic->next->op == IFX &&
5100 IC_COND(ic->next)->key == op->key) {
5101 DEBUGpic14_emitcode ("; "," key is okay");
5102 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5103 OP_SYMBOL(op)->liveTo,
5110 /*-----------------------------------------------------------------*/
5111 /* genAndOp - for && operation */
5112 /*-----------------------------------------------------------------*/
5113 static void genAndOp (iCode *ic)
5115 operand *left,*right, *result;
5118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5119 /* note here that && operations that are in an
5120 if statement are taken away by backPatchLabels
5121 only those used in arthmetic operations remain */
5122 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5123 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5124 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5126 DEBUGpic14_AopType(__LINE__,left,right,result);
5128 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5129 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5130 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5132 /* if both are bit variables */
5133 /* if (AOP_TYPE(left) == AOP_CRY && */
5134 /* AOP_TYPE(right) == AOP_CRY ) { */
5135 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5136 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5137 /* pic14_outBitC(result); */
5139 /* tlbl = newiTempLabel(NULL); */
5140 /* pic14_toBoolean(left); */
5141 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5142 /* pic14_toBoolean(right); */
5143 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5144 /* pic14_outBitAcc(result); */
5147 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5148 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5149 freeAsmop(result,NULL,ic,TRUE);
5153 /*-----------------------------------------------------------------*/
5154 /* genOrOp - for || operation */
5155 /*-----------------------------------------------------------------*/
5158 modified this code, but it doesn't appear to ever get called
5161 static void genOrOp (iCode *ic)
5163 operand *left,*right, *result;
5166 /* note here that || operations that are in an
5167 if statement are taken away by backPatchLabels
5168 only those used in arthmetic operations remain */
5169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5170 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5171 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5172 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5174 DEBUGpic14_AopType(__LINE__,left,right,result);
5176 /* if both are bit variables */
5177 if (AOP_TYPE(left) == AOP_CRY &&
5178 AOP_TYPE(right) == AOP_CRY ) {
5179 pic14_emitcode("clrc","");
5180 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5181 AOP(left)->aopu.aop_dir,
5182 AOP(left)->aopu.aop_dir);
5183 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5184 AOP(right)->aopu.aop_dir,
5185 AOP(right)->aopu.aop_dir);
5186 pic14_emitcode("setc","");
5189 tlbl = newiTempLabel(NULL);
5190 pic14_toBoolean(left);
5192 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5193 pic14_toBoolean(right);
5194 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5196 pic14_outBitAcc(result);
5199 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5200 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5201 freeAsmop(result,NULL,ic,TRUE);
5204 /*-----------------------------------------------------------------*/
5205 /* isLiteralBit - test if lit == 2^n */
5206 /*-----------------------------------------------------------------*/
5207 static int isLiteralBit(unsigned long lit)
5209 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5210 0x100L,0x200L,0x400L,0x800L,
5211 0x1000L,0x2000L,0x4000L,0x8000L,
5212 0x10000L,0x20000L,0x40000L,0x80000L,
5213 0x100000L,0x200000L,0x400000L,0x800000L,
5214 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5215 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5218 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5219 for(idx = 0; idx < 32; idx++)
5225 /*-----------------------------------------------------------------*/
5226 /* continueIfTrue - */
5227 /*-----------------------------------------------------------------*/
5228 static void continueIfTrue (iCode *ic)
5230 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5232 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5236 /*-----------------------------------------------------------------*/
5238 /*-----------------------------------------------------------------*/
5239 static void jumpIfTrue (iCode *ic)
5241 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5243 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5247 /*-----------------------------------------------------------------*/
5248 /* jmpTrueOrFalse - */
5249 /*-----------------------------------------------------------------*/
5250 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5252 // ugly but optimized by peephole
5253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5255 symbol *nlbl = newiTempLabel(NULL);
5256 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5257 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5258 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5259 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5262 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5263 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5268 /*-----------------------------------------------------------------*/
5269 /* genAnd - code for and */
5270 /*-----------------------------------------------------------------*/
5271 static void genAnd (iCode *ic, iCode *ifx)
5273 operand *left, *right, *result;
5275 unsigned long lit = 0L;
5280 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5281 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5282 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5283 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5285 resolveIfx(&rIfx,ifx);
5287 /* if left is a literal & right is not then exchange them */
5288 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5289 AOP_NEEDSACC(left)) {
5290 operand *tmp = right ;
5295 /* if result = right then exchange them */
5296 if(pic14_sameRegs(AOP(result),AOP(right))){
5297 operand *tmp = right ;
5302 /* if right is bit then exchange them */
5303 if (AOP_TYPE(right) == AOP_CRY &&
5304 AOP_TYPE(left) != AOP_CRY){
5305 operand *tmp = right ;
5309 if(AOP_TYPE(right) == AOP_LIT)
5310 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5312 size = AOP_SIZE(result);
5314 DEBUGpic14_AopType(__LINE__,left,right,result);
5317 // result = bit & yy;
5318 if (AOP_TYPE(left) == AOP_CRY){
5319 // c = bit & literal;
5320 if(AOP_TYPE(right) == AOP_LIT){
5322 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5325 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5328 if(size && (AOP_TYPE(result) == AOP_CRY)){
5329 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5332 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5336 pic14_emitcode("clr","c");
5339 if (AOP_TYPE(right) == AOP_CRY){
5341 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5342 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5345 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5347 pic14_emitcode("rrc","a");
5348 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5354 pic14_outBitC(result);
5356 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5357 genIfxJump(ifx, "c");
5361 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5362 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5363 if((AOP_TYPE(right) == AOP_LIT) &&
5364 (AOP_TYPE(result) == AOP_CRY) &&
5365 (AOP_TYPE(left) != AOP_CRY)){
5366 int posbit = isLiteralBit(lit);
5370 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5373 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5379 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5380 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5382 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5383 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5386 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5387 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5388 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5395 symbol *tlbl = newiTempLabel(NULL);
5396 int sizel = AOP_SIZE(left);
5398 pic14_emitcode("setb","c");
5400 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5401 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5403 if((posbit = isLiteralBit(bytelit)) != 0)
5404 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5406 if(bytelit != 0x0FFL)
5407 pic14_emitcode("anl","a,%s",
5408 aopGet(AOP(right),offset,FALSE,TRUE));
5409 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5414 // bit = left & literal
5416 pic14_emitcode("clr","c");
5417 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5419 // if(left & literal)
5422 jmpTrueOrFalse(ifx, tlbl);
5426 pic14_outBitC(result);
5430 /* if left is same as result */
5431 if(pic14_sameRegs(AOP(result),AOP(left))){
5433 for(;size--; offset++,lit>>=8) {
5434 if(AOP_TYPE(right) == AOP_LIT){
5435 switch(lit & 0xff) {
5437 /* and'ing with 0 has clears the result */
5438 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5439 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5442 /* and'ing with 0xff is a nop when the result and left are the same */
5447 int p = my_powof2( (~lit) & 0xff );
5449 /* only one bit is set in the literal, so use a bcf instruction */
5450 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5451 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5454 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5455 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5456 if(know_W != (int)(lit&0xff))
5457 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5459 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5464 if (AOP_TYPE(left) == AOP_ACC) {
5465 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5467 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5468 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5475 // left & result in different registers
5476 if(AOP_TYPE(result) == AOP_CRY){
5478 // if(size), result in bit
5479 // if(!size && ifx), conditional oper: if(left & right)
5480 symbol *tlbl = newiTempLabel(NULL);
5481 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5483 pic14_emitcode("setb","c");
5485 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5486 pic14_emitcode("anl","a,%s",
5487 aopGet(AOP(left),offset,FALSE,FALSE));
5488 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5493 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5494 pic14_outBitC(result);
5496 jmpTrueOrFalse(ifx, tlbl);
5498 for(;(size--);offset++) {
5500 // result = left & right
5501 if(AOP_TYPE(right) == AOP_LIT){
5502 int t = (lit >> (offset*8)) & 0x0FFL;
5505 pic14_emitcode("clrf","%s",
5506 aopGet(AOP(result),offset,FALSE,FALSE));
5507 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5510 if(AOP_TYPE(left) != AOP_ACC) {
5511 pic14_emitcode("movf","%s,w",
5512 aopGet(AOP(left),offset,FALSE,FALSE));
5513 pic14_emitcode("movwf","%s",
5514 aopGet(AOP(result),offset,FALSE,FALSE));
5515 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5517 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5520 if(AOP_TYPE(left) == AOP_ACC) {
5521 emitpcode(POC_ANDLW, popGetLit(t));
5523 pic14_emitcode("movlw","0x%x",t);
5524 pic14_emitcode("andwf","%s,w",
5525 aopGet(AOP(left),offset,FALSE,FALSE));
5526 pic14_emitcode("movwf","%s",
5527 aopGet(AOP(result),offset,FALSE,FALSE));
5529 emitpcode(POC_MOVLW, popGetLit(t));
5530 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5532 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5537 if (AOP_TYPE(left) == AOP_ACC) {
5538 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5539 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5541 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5542 pic14_emitcode("andwf","%s,w",
5543 aopGet(AOP(left),offset,FALSE,FALSE));
5544 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5545 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5547 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5548 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5554 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5555 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5556 freeAsmop(result,NULL,ic,TRUE);
5559 /*-----------------------------------------------------------------*/
5560 /* genOr - code for or */
5561 /*-----------------------------------------------------------------*/
5562 static void genOr (iCode *ic, iCode *ifx)
5564 operand *left, *right, *result;
5566 unsigned long lit = 0L;
5568 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5570 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5571 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5572 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5574 DEBUGpic14_AopType(__LINE__,left,right,result);
5576 /* if left is a literal & right is not then exchange them */
5577 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5578 AOP_NEEDSACC(left)) {
5579 operand *tmp = right ;
5584 /* if result = right then exchange them */
5585 if(pic14_sameRegs(AOP(result),AOP(right))){
5586 operand *tmp = right ;
5591 /* if right is bit then exchange them */
5592 if (AOP_TYPE(right) == AOP_CRY &&
5593 AOP_TYPE(left) != AOP_CRY){
5594 operand *tmp = right ;
5599 DEBUGpic14_AopType(__LINE__,left,right,result);
5601 if(AOP_TYPE(right) == AOP_LIT)
5602 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5604 size = AOP_SIZE(result);
5608 if (AOP_TYPE(left) == AOP_CRY){
5609 if(AOP_TYPE(right) == AOP_LIT){
5610 // c = bit & literal;
5612 // lit != 0 => result = 1
5613 if(AOP_TYPE(result) == AOP_CRY){
5615 emitpcode(POC_BSF, popGet(AOP(result),0));
5616 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5617 // AOP(result)->aopu.aop_dir,
5618 // AOP(result)->aopu.aop_dir);
5620 continueIfTrue(ifx);
5624 // lit == 0 => result = left
5625 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5627 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5630 if (AOP_TYPE(right) == AOP_CRY){
5631 if(pic14_sameRegs(AOP(result),AOP(left))){
5633 emitpcode(POC_BCF, popGet(AOP(result),0));
5634 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5635 emitpcode(POC_BSF, popGet(AOP(result),0));
5637 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5638 AOP(result)->aopu.aop_dir,
5639 AOP(result)->aopu.aop_dir);
5640 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5641 AOP(right)->aopu.aop_dir,
5642 AOP(right)->aopu.aop_dir);
5643 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5644 AOP(result)->aopu.aop_dir,
5645 AOP(result)->aopu.aop_dir);
5647 if( AOP_TYPE(result) == AOP_ACC) {
5648 emitpcode(POC_MOVLW, popGetLit(0));
5649 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5650 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5651 emitpcode(POC_MOVLW, popGetLit(1));
5655 emitpcode(POC_BCF, popGet(AOP(result),0));
5656 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5657 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5658 emitpcode(POC_BSF, popGet(AOP(result),0));
5660 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5661 AOP(result)->aopu.aop_dir,
5662 AOP(result)->aopu.aop_dir);
5663 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5664 AOP(right)->aopu.aop_dir,
5665 AOP(right)->aopu.aop_dir);
5666 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5667 AOP(left)->aopu.aop_dir,
5668 AOP(left)->aopu.aop_dir);
5669 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5670 AOP(result)->aopu.aop_dir,
5671 AOP(result)->aopu.aop_dir);
5676 symbol *tlbl = newiTempLabel(NULL);
5677 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5680 emitpcode(POC_BCF, popGet(AOP(result),0));
5681 if( AOP_TYPE(right) == AOP_ACC) {
5682 emitpcode(POC_IORLW, popGetLit(0));
5684 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5685 emitpcode(POC_BSF, popGet(AOP(result),0));
5690 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5691 pic14_emitcode(";XXX setb","c");
5692 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5693 AOP(left)->aopu.aop_dir,tlbl->key+100);
5694 pic14_toBoolean(right);
5695 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5696 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5697 jmpTrueOrFalse(ifx, tlbl);
5701 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5708 pic14_outBitC(result);
5710 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5711 genIfxJump(ifx, "c");
5715 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5716 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5717 if((AOP_TYPE(right) == AOP_LIT) &&
5718 (AOP_TYPE(result) == AOP_CRY) &&
5719 (AOP_TYPE(left) != AOP_CRY)){
5721 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5724 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5726 continueIfTrue(ifx);
5729 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5730 // lit = 0, result = boolean(left)
5732 pic14_emitcode(";XXX setb","c");
5733 pic14_toBoolean(right);
5735 symbol *tlbl = newiTempLabel(NULL);
5736 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5738 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5740 genIfxJump (ifx,"a");
5744 pic14_outBitC(result);
5748 /* if left is same as result */
5749 if(pic14_sameRegs(AOP(result),AOP(left))){
5751 for(;size--; offset++,lit>>=8) {
5752 if(AOP_TYPE(right) == AOP_LIT){
5753 if((lit & 0xff) == 0)
5754 /* or'ing with 0 has no effect */
5757 int p = my_powof2(lit & 0xff);
5759 /* only one bit is set in the literal, so use a bsf instruction */
5761 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5763 if(know_W != (int)(lit & 0xff))
5764 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5765 know_W = lit & 0xff;
5766 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5771 if (AOP_TYPE(left) == AOP_ACC) {
5772 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5773 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5775 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5776 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5778 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5779 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5785 // left & result in different registers
5786 if(AOP_TYPE(result) == AOP_CRY){
5788 // if(size), result in bit
5789 // if(!size && ifx), conditional oper: if(left | right)
5790 symbol *tlbl = newiTempLabel(NULL);
5791 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5792 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5796 pic14_emitcode(";XXX setb","c");
5798 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5799 pic14_emitcode(";XXX orl","a,%s",
5800 aopGet(AOP(left),offset,FALSE,FALSE));
5801 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5806 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5807 pic14_outBitC(result);
5809 jmpTrueOrFalse(ifx, tlbl);
5810 } else for(;(size--);offset++){
5812 // result = left & right
5813 if(AOP_TYPE(right) == AOP_LIT){
5814 int t = (lit >> (offset*8)) & 0x0FFL;
5817 if (AOP_TYPE(left) != AOP_ACC) {
5818 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5820 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5824 if (AOP_TYPE(left) == AOP_ACC) {
5825 emitpcode(POC_IORLW, popGetLit(t));
5827 emitpcode(POC_MOVLW, popGetLit(t));
5828 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5830 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5835 // faster than result <- left, anl result,right
5836 // and better if result is SFR
5837 if (AOP_TYPE(left) == AOP_ACC) {
5838 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5839 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5841 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5842 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5844 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5845 pic14_emitcode("iorwf","%s,w",
5846 aopGet(AOP(left),offset,FALSE,FALSE));
5848 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5849 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5854 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5855 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5856 freeAsmop(result,NULL,ic,TRUE);
5859 /*-----------------------------------------------------------------*/
5860 /* genXor - code for xclusive or */
5861 /*-----------------------------------------------------------------*/
5862 static void genXor (iCode *ic, iCode *ifx)
5864 operand *left, *right, *result;
5866 unsigned long lit = 0L;
5868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5870 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5871 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5872 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5874 /* if left is a literal & right is not ||
5875 if left needs acc & right does not */
5876 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5877 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5878 operand *tmp = right ;
5883 /* if result = right then exchange them */
5884 if(pic14_sameRegs(AOP(result),AOP(right))){
5885 operand *tmp = right ;
5890 /* if right is bit then exchange them */
5891 if (AOP_TYPE(right) == AOP_CRY &&
5892 AOP_TYPE(left) != AOP_CRY){
5893 operand *tmp = right ;
5897 if(AOP_TYPE(right) == AOP_LIT)
5898 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5900 size = AOP_SIZE(result);
5904 if (AOP_TYPE(left) == AOP_CRY){
5905 if(AOP_TYPE(right) == AOP_LIT){
5906 // c = bit & literal;
5908 // lit>>1 != 0 => result = 1
5909 if(AOP_TYPE(result) == AOP_CRY){
5911 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5912 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5914 continueIfTrue(ifx);
5917 pic14_emitcode("setb","c");
5921 // lit == 0, result = left
5922 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5924 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5926 // lit == 1, result = not(left)
5927 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5928 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5929 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5930 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5933 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5934 pic14_emitcode("cpl","c");
5941 symbol *tlbl = newiTempLabel(NULL);
5942 if (AOP_TYPE(right) == AOP_CRY){
5944 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5947 int sizer = AOP_SIZE(right);
5949 // if val>>1 != 0, result = 1
5950 pic14_emitcode("setb","c");
5952 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5954 // test the msb of the lsb
5955 pic14_emitcode("anl","a,#0xfe");
5956 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5960 pic14_emitcode("rrc","a");
5962 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5963 pic14_emitcode("cpl","c");
5964 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5969 pic14_outBitC(result);
5971 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5972 genIfxJump(ifx, "c");
5976 if(pic14_sameRegs(AOP(result),AOP(left))){
5977 /* if left is same as result */
5978 for(;size--; offset++) {
5979 if(AOP_TYPE(right) == AOP_LIT){
5980 int t = (lit >> (offset*8)) & 0x0FFL;
5984 if (IS_AOP_PREG(left)) {
5985 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5986 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5987 aopPut(AOP(result),"a",offset);
5989 emitpcode(POC_MOVLW, popGetLit(t));
5990 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5991 pic14_emitcode("xrl","%s,%s",
5992 aopGet(AOP(left),offset,FALSE,TRUE),
5993 aopGet(AOP(right),offset,FALSE,FALSE));
5996 if (AOP_TYPE(left) == AOP_ACC)
5997 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5999 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6000 emitpcode(POC_XORWF,popGet(AOP(left),offset));
6002 if (IS_AOP_PREG(left)) {
6003 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
6004 aopPut(AOP(result),"a",offset);
6006 pic14_emitcode("xrl","%s,a",
6007 aopGet(AOP(left),offset,FALSE,TRUE));
6013 // left & result in different registers
6014 if(AOP_TYPE(result) == AOP_CRY){
6016 // if(size), result in bit
6017 // if(!size && ifx), conditional oper: if(left ^ right)
6018 symbol *tlbl = newiTempLabel(NULL);
6019 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
6021 pic14_emitcode("setb","c");
6023 if((AOP_TYPE(right) == AOP_LIT) &&
6024 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
6025 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
6027 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
6028 pic14_emitcode("xrl","a,%s",
6029 aopGet(AOP(left),offset,FALSE,FALSE));
6031 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6036 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6037 pic14_outBitC(result);
6039 jmpTrueOrFalse(ifx, tlbl);
6040 } else for(;(size--);offset++){
6042 // result = left & right
6043 if(AOP_TYPE(right) == AOP_LIT){
6044 int t = (lit >> (offset*8)) & 0x0FFL;
6047 if (AOP_TYPE(left) != AOP_ACC) {
6048 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6050 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6051 pic14_emitcode("movf","%s,w",
6052 aopGet(AOP(left),offset,FALSE,FALSE));
6053 pic14_emitcode("movwf","%s",
6054 aopGet(AOP(result),offset,FALSE,FALSE));
6057 if (AOP_TYPE(left) == AOP_ACC) {
6058 emitpcode(POC_XORLW, popGetLit(t));
6060 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6062 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6065 if (AOP_TYPE(left) == AOP_ACC) {
6066 emitpcode(POC_XORLW, popGetLit(t));
6068 emitpcode(POC_MOVLW, popGetLit(t));
6069 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6071 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6072 pic14_emitcode("movlw","0x%x",t);
6073 pic14_emitcode("xorwf","%s,w",
6074 aopGet(AOP(left),offset,FALSE,FALSE));
6075 pic14_emitcode("movwf","%s",
6076 aopGet(AOP(result),offset,FALSE,FALSE));
6082 // faster than result <- left, anl result,right
6083 // and better if result is SFR
6084 if (AOP_TYPE(left) == AOP_ACC) {
6085 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6086 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6088 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6089 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6090 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6091 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6093 if ( AOP_TYPE(result) != AOP_ACC){
6094 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6095 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6101 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6102 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6103 freeAsmop(result,NULL,ic,TRUE);
6106 /*-----------------------------------------------------------------*/
6107 /* genInline - write the inline code out */
6108 /*-----------------------------------------------------------------*/
6109 static void genInline (iCode *ic)
6111 char *buffer, *bp, *bp1;
6113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6115 _G.inLine += (!options.asmpeep);
6117 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6118 strcpy(buffer,IC_INLINE(ic));
6120 /* emit each line as a code */
6126 addpCode2pBlock(pb,AssembleLine(bp1));
6133 pic14_emitcode(bp1,"");
6139 if ((bp1 != bp) && *bp1)
6140 addpCode2pBlock(pb,AssembleLine(bp1));
6144 _G.inLine -= (!options.asmpeep);
6147 /*-----------------------------------------------------------------*/
6148 /* genRRC - rotate right with carry */
6149 /*-----------------------------------------------------------------*/
6150 static void genRRC (iCode *ic)
6152 operand *left , *result ;
6153 int size, offset = 0, same;
6155 /* rotate right with carry */
6157 result=IC_RESULT(ic);
6158 aopOp (left,ic,FALSE);
6159 aopOp (result,ic,FALSE);
6161 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6163 same = pic14_sameRegs(AOP(result),AOP(left));
6165 size = AOP_SIZE(result);
6167 /* get the lsb and put it into the carry */
6168 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6175 emitpcode(POC_RRF, popGet(AOP(left),offset));
6177 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6178 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6184 freeAsmop(left,NULL,ic,TRUE);
6185 freeAsmop(result,NULL,ic,TRUE);
6188 /*-----------------------------------------------------------------*/
6189 /* genRLC - generate code for rotate left with carry */
6190 /*-----------------------------------------------------------------*/
6191 static void genRLC (iCode *ic)
6193 operand *left , *result ;
6194 int size, offset = 0;
6197 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6198 /* rotate right with carry */
6200 result=IC_RESULT(ic);
6201 aopOp (left,ic,FALSE);
6202 aopOp (result,ic,FALSE);
6204 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6206 same = pic14_sameRegs(AOP(result),AOP(left));
6208 /* move it to the result */
6209 size = AOP_SIZE(result);
6211 /* get the msb and put it into the carry */
6212 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6219 emitpcode(POC_RLF, popGet(AOP(left),offset));
6221 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6222 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6229 freeAsmop(left,NULL,ic,TRUE);
6230 freeAsmop(result,NULL,ic,TRUE);
6233 /*-----------------------------------------------------------------*/
6234 /* genGetHbit - generates code get highest order bit */
6235 /*-----------------------------------------------------------------*/
6236 static void genGetHbit (iCode *ic)
6238 operand *left, *result;
6240 result=IC_RESULT(ic);
6241 aopOp (left,ic,FALSE);
6242 aopOp (result,ic,FALSE);
6244 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6245 /* get the highest order byte into a */
6246 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6247 if(AOP_TYPE(result) == AOP_CRY){
6248 pic14_emitcode("rlc","a");
6249 pic14_outBitC(result);
6252 pic14_emitcode("rl","a");
6253 pic14_emitcode("anl","a,#0x01");
6254 pic14_outAcc(result);
6258 freeAsmop(left,NULL,ic,TRUE);
6259 freeAsmop(result,NULL,ic,TRUE);
6262 /*-----------------------------------------------------------------*/
6263 /* AccRol - rotate left accumulator by known count */
6264 /*-----------------------------------------------------------------*/
6265 static void AccRol (int shCount)
6267 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6268 shCount &= 0x0007; // shCount : 0..7
6273 pic14_emitcode("rl","a");
6276 pic14_emitcode("rl","a");
6277 pic14_emitcode("rl","a");
6280 pic14_emitcode("swap","a");
6281 pic14_emitcode("rr","a");
6284 pic14_emitcode("swap","a");
6287 pic14_emitcode("swap","a");
6288 pic14_emitcode("rl","a");
6291 pic14_emitcode("rr","a");
6292 pic14_emitcode("rr","a");
6295 pic14_emitcode("rr","a");
6300 /*-----------------------------------------------------------------*/
6301 /* AccLsh - left shift accumulator by known count */
6302 /*-----------------------------------------------------------------*/
6303 static void AccLsh (int shCount)
6305 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6308 pic14_emitcode("add","a,acc");
6311 pic14_emitcode("add","a,acc");
6312 pic14_emitcode("add","a,acc");
6314 /* rotate left accumulator */
6316 /* and kill the lower order bits */
6317 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6322 /*-----------------------------------------------------------------*/
6323 /* AccRsh - right shift accumulator by known count */
6324 /*-----------------------------------------------------------------*/
6325 static void AccRsh (int shCount)
6327 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6331 pic14_emitcode("rrc","a");
6333 /* rotate right accumulator */
6334 AccRol(8 - shCount);
6335 /* and kill the higher order bits */
6336 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6342 /*-----------------------------------------------------------------*/
6343 /* AccSRsh - signed right shift accumulator by known count */
6344 /*-----------------------------------------------------------------*/
6345 static void AccSRsh (int shCount)
6348 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6351 pic14_emitcode("mov","c,acc.7");
6352 pic14_emitcode("rrc","a");
6353 } else if(shCount == 2){
6354 pic14_emitcode("mov","c,acc.7");
6355 pic14_emitcode("rrc","a");
6356 pic14_emitcode("mov","c,acc.7");
6357 pic14_emitcode("rrc","a");
6359 tlbl = newiTempLabel(NULL);
6360 /* rotate right accumulator */
6361 AccRol(8 - shCount);
6362 /* and kill the higher order bits */
6363 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6364 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6365 pic14_emitcode("orl","a,#0x%02x",
6366 (unsigned char)~SRMask[shCount]);
6367 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6372 /*-----------------------------------------------------------------*/
6373 /* shiftR1Left2Result - shift right one byte from left to result */
6374 /*-----------------------------------------------------------------*/
6375 static void shiftR1Left2ResultSigned (operand *left, int offl,
6376 operand *result, int offr,
6381 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6383 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6387 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6389 emitpcode(POC_RRF, popGet(AOP(result),offr));
6391 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6392 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6398 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6400 emitpcode(POC_RRF, popGet(AOP(result),offr));
6402 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6403 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6405 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6406 emitpcode(POC_RRF, popGet(AOP(result),offr));
6412 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6414 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6415 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6418 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6419 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6420 emitpcode(POC_ANDLW, popGetLit(0x1f));
6422 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6423 emitpcode(POC_IORLW, popGetLit(0xe0));
6425 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6429 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6430 emitpcode(POC_ANDLW, popGetLit(0x0f));
6431 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6432 emitpcode(POC_IORLW, popGetLit(0xf0));
6433 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6437 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6439 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6440 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6442 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6443 emitpcode(POC_ANDLW, popGetLit(0x07));
6444 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6445 emitpcode(POC_IORLW, popGetLit(0xf8));
6446 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6451 emitpcode(POC_MOVLW, popGetLit(0x00));
6452 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6453 emitpcode(POC_MOVLW, popGetLit(0xfe));
6454 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6455 emitpcode(POC_IORLW, popGetLit(0x01));
6456 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6458 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6459 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6460 emitpcode(POC_DECF, popGet(AOP(result),offr));
6461 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6462 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6468 emitpcode(POC_MOVLW, popGetLit(0x00));
6469 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6470 emitpcode(POC_MOVLW, popGetLit(0xff));
6471 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6473 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6474 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6475 emitpcode(POC_DECF, popGet(AOP(result),offr));
6483 /*-----------------------------------------------------------------*/
6484 /* shiftR1Left2Result - shift right one byte from left to result */
6485 /*-----------------------------------------------------------------*/
6486 static void shiftR1Left2Result (operand *left, int offl,
6487 operand *result, int offr,
6488 int shCount, int sign)
6492 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6494 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6496 /* Copy the msb into the carry if signed. */
6498 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6508 emitpcode(POC_RRF, popGet(AOP(result),offr));
6510 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6511 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6517 emitpcode(POC_RRF, popGet(AOP(result),offr));
6519 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6520 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6523 emitpcode(POC_RRF, popGet(AOP(result),offr));
6528 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6530 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6531 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6534 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6535 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6536 emitpcode(POC_ANDLW, popGetLit(0x1f));
6537 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6541 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6542 emitpcode(POC_ANDLW, popGetLit(0x0f));
6543 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6547 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6548 emitpcode(POC_ANDLW, popGetLit(0x0f));
6549 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6551 emitpcode(POC_RRF, popGet(AOP(result),offr));
6556 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6557 emitpcode(POC_ANDLW, popGetLit(0x80));
6558 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6559 emitpcode(POC_RLF, popGet(AOP(result),offr));
6560 emitpcode(POC_RLF, popGet(AOP(result),offr));
6565 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6566 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6567 emitpcode(POC_RLF, popGet(AOP(result),offr));
6576 /*-----------------------------------------------------------------*/
6577 /* shiftL1Left2Result - shift left one byte from left to result */
6578 /*-----------------------------------------------------------------*/
6579 static void shiftL1Left2Result (operand *left, int offl,
6580 operand *result, int offr, int shCount)
6585 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6587 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6588 DEBUGpic14_emitcode ("; ***","same = %d",same);
6589 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6591 /* shift left accumulator */
6592 //AccLsh(shCount); // don't comment out just yet...
6593 // aopPut(AOP(result),"a",offr);
6597 /* Shift left 1 bit position */
6598 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6600 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6602 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6603 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6607 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6608 emitpcode(POC_ANDLW,popGetLit(0x7e));
6609 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6610 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6613 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6614 emitpcode(POC_ANDLW,popGetLit(0x3e));
6615 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6616 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6617 emitpcode(POC_RLF, popGet(AOP(result),offr));
6620 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6621 emitpcode(POC_ANDLW, popGetLit(0xf0));
6622 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6625 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6626 emitpcode(POC_ANDLW, popGetLit(0xf0));
6627 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6628 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6631 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6632 emitpcode(POC_ANDLW, popGetLit(0x30));
6633 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6634 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6635 emitpcode(POC_RLF, popGet(AOP(result),offr));
6638 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6639 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6640 emitpcode(POC_RRF, popGet(AOP(result),offr));
6644 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6649 /*-----------------------------------------------------------------*/
6650 /* movLeft2Result - move byte from left to result */
6651 /*-----------------------------------------------------------------*/
6652 static void movLeft2Result (operand *left, int offl,
6653 operand *result, int offr)
6656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6657 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6658 l = aopGet(AOP(left),offl,FALSE,FALSE);
6660 if (*l == '@' && (IS_AOP_PREG(result))) {
6661 pic14_emitcode("mov","a,%s",l);
6662 aopPut(AOP(result),"a",offr);
6664 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6665 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6670 /*-----------------------------------------------------------------*/
6671 /* shiftL2Left2Result - shift left two bytes from left to result */
6672 /*-----------------------------------------------------------------*/
6673 static void shiftL2Left2Result (operand *left, int offl,
6674 operand *result, int offr, int shCount)
6678 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6680 if(pic14_sameRegs(AOP(result), AOP(left))) {
6688 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6689 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6690 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6694 emitpcode(POC_RLF, popGet(AOP(result),offr));
6695 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6701 emitpcode(POC_MOVLW, popGetLit(0x0f));
6702 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6703 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6704 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6705 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6706 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6707 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6709 emitpcode(POC_RLF, popGet(AOP(result),offr));
6710 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6714 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6715 emitpcode(POC_RRF, popGet(AOP(result),offr));
6716 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6717 emitpcode(POC_RRF, popGet(AOP(result),offr));
6718 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6719 emitpcode(POC_ANDLW,popGetLit(0xc0));
6720 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6721 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6722 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6723 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6726 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6727 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6728 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6729 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6730 emitpcode(POC_RRF, popGet(AOP(result),offr));
6740 /* note, use a mov/add for the shift since the mov has a
6741 chance of getting optimized out */
6742 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6743 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6744 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6745 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6746 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_RLF, popGet(AOP(result),offr));
6751 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6757 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6758 emitpcode(POC_ANDLW, popGetLit(0xF0));
6759 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6760 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6761 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6762 emitpcode(POC_ANDLW, popGetLit(0xF0));
6763 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6764 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6768 emitpcode(POC_RLF, popGet(AOP(result),offr));
6769 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6773 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6774 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6775 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6776 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6778 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6779 emitpcode(POC_RRF, popGet(AOP(result),offr));
6780 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6781 emitpcode(POC_ANDLW,popGetLit(0xc0));
6782 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6783 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6784 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6785 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6788 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6789 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6790 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6791 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6792 emitpcode(POC_RRF, popGet(AOP(result),offr));
6797 /*-----------------------------------------------------------------*/
6798 /* shiftR2Left2Result - shift right two bytes from left to result */
6799 /*-----------------------------------------------------------------*/
6800 static void shiftR2Left2Result (operand *left, int offl,
6801 operand *result, int offr,
6802 int shCount, int sign)
6806 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6807 same = pic14_sameRegs(AOP(result), AOP(left));
6809 if(same && ((offl + MSB16) == offr)){
6811 /* don't crash result[offr] */
6812 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6813 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6816 movLeft2Result(left,offl, result, offr);
6817 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6820 /* a:x >> shCount (x = lsb(result))*/
6823 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6825 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6834 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6839 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6840 emitpcode(POC_RRF,popGet(AOP(result),offr));
6842 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6843 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6844 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6845 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6850 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6853 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6854 emitpcode(POC_RRF,popGet(AOP(result),offr));
6861 emitpcode(POC_MOVLW, popGetLit(0xf0));
6862 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6863 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6865 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6866 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6867 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6868 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6870 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6871 emitpcode(POC_ANDLW, popGetLit(0x0f));
6872 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6874 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6875 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6876 emitpcode(POC_ANDLW, popGetLit(0xf0));
6877 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6878 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6882 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6883 emitpcode(POC_RRF, popGet(AOP(result),offr));
6887 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6888 emitpcode(POC_BTFSC,
6889 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6890 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6898 emitpcode(POC_RLF, popGet(AOP(result),offr));
6899 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6901 emitpcode(POC_RLF, popGet(AOP(result),offr));
6902 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6903 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6904 emitpcode(POC_ANDLW,popGetLit(0x03));
6906 emitpcode(POC_BTFSC,
6907 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6908 emitpcode(POC_IORLW,popGetLit(0xfc));
6910 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6911 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6912 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6913 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6915 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6916 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6917 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6918 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6919 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6920 emitpcode(POC_RLF, popGet(AOP(result),offr));
6921 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6922 emitpcode(POC_ANDLW,popGetLit(0x03));
6924 emitpcode(POC_BTFSC,
6925 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6926 emitpcode(POC_IORLW,popGetLit(0xfc));
6928 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6929 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6936 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6937 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6938 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6939 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6942 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6944 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6949 /*-----------------------------------------------------------------*/
6950 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6951 /*-----------------------------------------------------------------*/
6952 static void shiftLLeftOrResult (operand *left, int offl,
6953 operand *result, int offr, int shCount)
6955 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6956 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6957 /* shift left accumulator */
6959 /* or with result */
6960 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6961 /* back to result */
6962 aopPut(AOP(result),"a",offr);
6965 /*-----------------------------------------------------------------*/
6966 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6967 /*-----------------------------------------------------------------*/
6968 static void shiftRLeftOrResult (operand *left, int offl,
6969 operand *result, int offr, int shCount)
6971 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6972 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6973 /* shift right accumulator */
6975 /* or with result */
6976 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6977 /* back to result */
6978 aopPut(AOP(result),"a",offr);
6981 /*-----------------------------------------------------------------*/
6982 /* genlshOne - left shift a one byte quantity by known count */
6983 /*-----------------------------------------------------------------*/
6984 static void genlshOne (operand *result, operand *left, int shCount)
6986 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6987 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6990 /*-----------------------------------------------------------------*/
6991 /* genlshTwo - left shift two bytes by known amount != 0 */
6992 /*-----------------------------------------------------------------*/
6993 static void genlshTwo (operand *result,operand *left, int shCount)
6997 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6998 size = pic14_getDataSize(result);
7000 /* if shCount >= 8 */
7006 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7008 movLeft2Result(left, LSB, result, MSB16);
7010 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
7013 /* 1 <= shCount <= 7 */
7016 shiftL1Left2Result(left, LSB, result, LSB, shCount);
7018 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7022 /*-----------------------------------------------------------------*/
7023 /* shiftLLong - shift left one long from left to result */
7024 /* offl = LSB or MSB16 */
7025 /*-----------------------------------------------------------------*/
7026 static void shiftLLong (operand *left, operand *result, int offr )
7029 int size = AOP_SIZE(result);
7031 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7032 if(size >= LSB+offr){
7033 l = aopGet(AOP(left),LSB,FALSE,FALSE);
7035 pic14_emitcode("add","a,acc");
7036 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7037 size >= MSB16+offr && offr != LSB )
7038 pic14_emitcode("xch","a,%s",
7039 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7041 aopPut(AOP(result),"a",LSB+offr);
7044 if(size >= MSB16+offr){
7045 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7046 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7049 pic14_emitcode("rlc","a");
7050 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7051 size >= MSB24+offr && offr != LSB)
7052 pic14_emitcode("xch","a,%s",
7053 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7055 aopPut(AOP(result),"a",MSB16+offr);
7058 if(size >= MSB24+offr){
7059 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7060 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7063 pic14_emitcode("rlc","a");
7064 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7065 size >= MSB32+offr && offr != LSB )
7066 pic14_emitcode("xch","a,%s",
7067 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7069 aopPut(AOP(result),"a",MSB24+offr);
7072 if(size > MSB32+offr){
7073 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7074 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7077 pic14_emitcode("rlc","a");
7078 aopPut(AOP(result),"a",MSB32+offr);
7081 aopPut(AOP(result),zero,LSB);
7084 /*-----------------------------------------------------------------*/
7085 /* genlshFour - shift four byte by a known amount != 0 */
7086 /*-----------------------------------------------------------------*/
7087 static void genlshFour (operand *result, operand *left, int shCount)
7091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7092 size = AOP_SIZE(result);
7094 /* if shifting more that 3 bytes */
7095 if (shCount >= 24 ) {
7098 /* lowest order of left goes to the highest
7099 order of the destination */
7100 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7102 movLeft2Result(left, LSB, result, MSB32);
7103 aopPut(AOP(result),zero,LSB);
7104 aopPut(AOP(result),zero,MSB16);
7105 aopPut(AOP(result),zero,MSB32);
7109 /* more than two bytes */
7110 else if ( shCount >= 16 ) {
7111 /* lower order two bytes goes to higher order two bytes */
7113 /* if some more remaining */
7115 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7117 movLeft2Result(left, MSB16, result, MSB32);
7118 movLeft2Result(left, LSB, result, MSB24);
7120 aopPut(AOP(result),zero,MSB16);
7121 aopPut(AOP(result),zero,LSB);
7125 /* if more than 1 byte */
7126 else if ( shCount >= 8 ) {
7127 /* lower order three bytes goes to higher order three bytes */
7131 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7133 movLeft2Result(left, LSB, result, MSB16);
7135 else{ /* size = 4 */
7137 movLeft2Result(left, MSB24, result, MSB32);
7138 movLeft2Result(left, MSB16, result, MSB24);
7139 movLeft2Result(left, LSB, result, MSB16);
7140 aopPut(AOP(result),zero,LSB);
7142 else if(shCount == 1)
7143 shiftLLong(left, result, MSB16);
7145 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7146 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7147 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7148 aopPut(AOP(result),zero,LSB);
7153 /* 1 <= shCount <= 7 */
7154 else if(shCount <= 2){
7155 shiftLLong(left, result, LSB);
7157 shiftLLong(result, result, LSB);
7159 /* 3 <= shCount <= 7, optimize */
7161 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7162 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7163 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7167 /*-----------------------------------------------------------------*/
7168 /* genLeftShiftLiteral - left shifting by known count */
7169 /*-----------------------------------------------------------------*/
7170 static void genLeftShiftLiteral (operand *left,
7175 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7178 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7179 freeAsmop(right,NULL,ic,TRUE);
7181 aopOp(left,ic,FALSE);
7182 aopOp(result,ic,FALSE);
7184 size = getSize(operandType(result));
7187 pic14_emitcode("; shift left ","result %d, left %d",size,
7191 /* I suppose that the left size >= result size */
7194 movLeft2Result(left, size, result, size);
7198 else if(shCount >= (size * 8))
7200 aopPut(AOP(result),zero,size);
7204 genlshOne (result,left,shCount);
7209 genlshTwo (result,left,shCount);
7213 genlshFour (result,left,shCount);
7217 freeAsmop(left,NULL,ic,TRUE);
7218 freeAsmop(result,NULL,ic,TRUE);
7221 /*-----------------------------------------------------------------*
7222 * genMultiAsm - repeat assembly instruction for size of register.
7223 * if endian == 1, then the high byte (i.e base address + size of
7224 * register) is used first else the low byte is used first;
7225 *-----------------------------------------------------------------*/
7226 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7244 emitpcode(poc, popGet(AOP(reg),offset));
7249 /*-----------------------------------------------------------------*/
7250 /* genLeftShift - generates code for left shifting */
7251 /*-----------------------------------------------------------------*/
7252 static void genLeftShift (iCode *ic)
7254 operand *left,*right, *result;
7257 symbol *tlbl , *tlbl1;
7260 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7262 right = IC_RIGHT(ic);
7264 result = IC_RESULT(ic);
7266 aopOp(right,ic,FALSE);
7268 /* if the shift count is known then do it
7269 as efficiently as possible */
7270 if (AOP_TYPE(right) == AOP_LIT) {
7271 genLeftShiftLiteral (left,right,result,ic);
7275 /* shift count is unknown then we have to form
7276 a loop get the loop count in B : Note: we take
7277 only the lower order byte since shifting
7278 more that 32 bits make no sense anyway, ( the
7279 largest size of an object can be only 32 bits ) */
7282 aopOp(left,ic,FALSE);
7283 aopOp(result,ic,FALSE);
7285 /* now move the left to the result if they are not the
7287 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7288 AOP_SIZE(result) > 1) {
7290 size = AOP_SIZE(result);
7293 l = aopGet(AOP(left),offset,FALSE,TRUE);
7294 if (*l == '@' && (IS_AOP_PREG(result))) {
7296 pic14_emitcode("mov","a,%s",l);
7297 aopPut(AOP(result),"a",offset);
7299 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7300 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7301 //aopPut(AOP(result),l,offset);
7307 size = AOP_SIZE(result);
7309 /* if it is only one byte then */
7311 if(optimized_for_speed) {
7312 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7313 emitpcode(POC_ANDLW, popGetLit(0xf0));
7314 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7315 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7316 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7317 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7318 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7319 emitpcode(POC_RLFW, popGet(AOP(result),0));
7320 emitpcode(POC_ANDLW, popGetLit(0xfe));
7321 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7322 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7323 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7326 tlbl = newiTempLabel(NULL);
7327 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7328 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7329 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7332 emitpcode(POC_COMFW, popGet(AOP(right),0));
7333 emitpcode(POC_RRF, popGet(AOP(result),0));
7334 emitpLabel(tlbl->key);
7335 emitpcode(POC_RLF, popGet(AOP(result),0));
7336 emitpcode(POC_ADDLW, popGetLit(1));
7338 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7343 if (pic14_sameRegs(AOP(left),AOP(result))) {
7345 tlbl = newiTempLabel(NULL);
7346 emitpcode(POC_COMFW, popGet(AOP(right),0));
7347 genMultiAsm(POC_RRF, result, size,1);
7348 emitpLabel(tlbl->key);
7349 genMultiAsm(POC_RLF, result, size,0);
7350 emitpcode(POC_ADDLW, popGetLit(1));
7352 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7356 //tlbl = newiTempLabel(NULL);
7358 //tlbl1 = newiTempLabel(NULL);
7360 //reAdjustPreg(AOP(result));
7362 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7363 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7364 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7366 //pic14_emitcode("add","a,acc");
7367 //aopPut(AOP(result),"a",offset++);
7369 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7371 // pic14_emitcode("rlc","a");
7372 // aopPut(AOP(result),"a",offset++);
7374 //reAdjustPreg(AOP(result));
7376 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7377 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7380 tlbl = newiTempLabel(NULL);
7381 tlbl1= newiTempLabel(NULL);
7383 size = AOP_SIZE(result);
7386 pctemp = popGetTempReg(); /* grab a temporary working register. */
7388 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7390 /* offset should be 0, 1 or 3 */
7391 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7393 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7395 emitpcode(POC_MOVWF, pctemp);
7398 emitpLabel(tlbl->key);
7401 emitpcode(POC_RLF, popGet(AOP(result),0));
7403 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7405 emitpcode(POC_DECFSZ, pctemp);
7406 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7407 emitpLabel(tlbl1->key);
7409 popReleaseTempReg(pctemp);
7413 freeAsmop (right,NULL,ic,TRUE);
7414 freeAsmop(left,NULL,ic,TRUE);
7415 freeAsmop(result,NULL,ic,TRUE);
7418 /*-----------------------------------------------------------------*/
7419 /* genrshOne - right shift a one byte quantity by known count */
7420 /*-----------------------------------------------------------------*/
7421 static void genrshOne (operand *result, operand *left,
7422 int shCount, int sign)
7424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7425 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7428 /*-----------------------------------------------------------------*/
7429 /* genrshTwo - right shift two bytes by known amount != 0 */
7430 /*-----------------------------------------------------------------*/
7431 static void genrshTwo (operand *result,operand *left,
7432 int shCount, int sign)
7434 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7435 /* if shCount >= 8 */
7439 shiftR1Left2Result(left, MSB16, result, LSB,
7442 movLeft2Result(left, MSB16, result, LSB);
7444 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7447 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7448 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7452 /* 1 <= shCount <= 7 */
7454 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7457 /*-----------------------------------------------------------------*/
7458 /* shiftRLong - shift right one long from left to result */
7459 /* offl = LSB or MSB16 */
7460 /*-----------------------------------------------------------------*/
7461 static void shiftRLong (operand *left, int offl,
7462 operand *result, int sign)
7464 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7466 pic14_emitcode("clr","c");
7467 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7469 pic14_emitcode("mov","c,acc.7");
7470 pic14_emitcode("rrc","a");
7471 aopPut(AOP(result),"a",MSB32-offl);
7473 /* add sign of "a" */
7474 addSign(result, MSB32, sign);
7476 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7477 pic14_emitcode("rrc","a");
7478 aopPut(AOP(result),"a",MSB24-offl);
7480 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7481 pic14_emitcode("rrc","a");
7482 aopPut(AOP(result),"a",MSB16-offl);
7485 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7486 pic14_emitcode("rrc","a");
7487 aopPut(AOP(result),"a",LSB);
7491 /*-----------------------------------------------------------------*/
7492 /* genrshFour - shift four byte by a known amount != 0 */
7493 /*-----------------------------------------------------------------*/
7494 static void genrshFour (operand *result, operand *left,
7495 int shCount, int sign)
7497 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7498 /* if shifting more that 3 bytes */
7499 if(shCount >= 24 ) {
7502 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7504 movLeft2Result(left, MSB32, result, LSB);
7506 addSign(result, MSB16, sign);
7508 else if(shCount >= 16){
7511 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7513 movLeft2Result(left, MSB24, result, LSB);
7514 movLeft2Result(left, MSB32, result, MSB16);
7516 addSign(result, MSB24, sign);
7518 else if(shCount >= 8){
7521 shiftRLong(left, MSB16, result, sign);
7522 else if(shCount == 0){
7523 movLeft2Result(left, MSB16, result, LSB);
7524 movLeft2Result(left, MSB24, result, MSB16);
7525 movLeft2Result(left, MSB32, result, MSB24);
7526 addSign(result, MSB32, sign);
7529 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7530 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7531 /* the last shift is signed */
7532 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7533 addSign(result, MSB32, sign);
7536 else{ /* 1 <= shCount <= 7 */
7538 shiftRLong(left, LSB, result, sign);
7540 shiftRLong(result, LSB, result, sign);
7543 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7544 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7545 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7550 /*-----------------------------------------------------------------*/
7551 /* genRightShiftLiteral - right shifting by known count */
7552 /*-----------------------------------------------------------------*/
7553 static void genRightShiftLiteral (operand *left,
7559 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7562 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7563 freeAsmop(right,NULL,ic,TRUE);
7565 aopOp(left,ic,FALSE);
7566 aopOp(result,ic,FALSE);
7569 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7573 lsize = pic14_getDataSize(left);
7574 res_size = pic14_getDataSize(result);
7575 /* test the LEFT size !!! */
7577 /* I suppose that the left size >= result size */
7580 movLeft2Result(left, lsize, result, res_size);
7583 else if(shCount >= (lsize * 8)){
7586 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7588 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7589 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7594 emitpcode(POC_MOVLW, popGetLit(0));
7595 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7596 emitpcode(POC_MOVLW, popGetLit(0xff));
7598 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7603 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7610 genrshOne (result,left,shCount,sign);
7614 genrshTwo (result,left,shCount,sign);
7618 genrshFour (result,left,shCount,sign);
7626 freeAsmop(left,NULL,ic,TRUE);
7627 freeAsmop(result,NULL,ic,TRUE);
7630 /*-----------------------------------------------------------------*/
7631 /* genSignedRightShift - right shift of signed number */
7632 /*-----------------------------------------------------------------*/
7633 static void genSignedRightShift (iCode *ic)
7635 operand *right, *left, *result;
7638 symbol *tlbl, *tlbl1 ;
7641 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7643 /* we do it the hard way put the shift count in b
7644 and loop thru preserving the sign */
7645 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7647 right = IC_RIGHT(ic);
7649 result = IC_RESULT(ic);
7651 aopOp(right,ic,FALSE);
7652 aopOp(left,ic,FALSE);
7653 aopOp(result,ic,FALSE);
7656 if ( AOP_TYPE(right) == AOP_LIT) {
7657 genRightShiftLiteral (left,right,result,ic,1);
7660 /* shift count is unknown then we have to form
7661 a loop get the loop count in B : Note: we take
7662 only the lower order byte since shifting
7663 more that 32 bits make no sense anyway, ( the
7664 largest size of an object can be only 32 bits ) */
7666 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7667 //pic14_emitcode("inc","b");
7668 //freeAsmop (right,NULL,ic,TRUE);
7669 //aopOp(left,ic,FALSE);
7670 //aopOp(result,ic,FALSE);
7672 /* now move the left to the result if they are not the
7674 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7675 AOP_SIZE(result) > 1) {
7677 size = AOP_SIZE(result);
7681 l = aopGet(AOP(left),offset,FALSE,TRUE);
7682 if (*l == '@' && IS_AOP_PREG(result)) {
7684 pic14_emitcode("mov","a,%s",l);
7685 aopPut(AOP(result),"a",offset);
7687 aopPut(AOP(result),l,offset);
7689 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7690 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7696 /* mov the highest order bit to OVR */
7697 tlbl = newiTempLabel(NULL);
7698 tlbl1= newiTempLabel(NULL);
7700 size = AOP_SIZE(result);
7703 pctemp = popGetTempReg(); /* grab a temporary working register. */
7705 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7707 /* offset should be 0, 1 or 3 */
7708 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7710 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7712 emitpcode(POC_MOVWF, pctemp);
7715 emitpLabel(tlbl->key);
7717 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7718 emitpcode(POC_RRF, popGet(AOP(result),offset));
7721 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7724 emitpcode(POC_DECFSZ, pctemp);
7725 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7726 emitpLabel(tlbl1->key);
7728 popReleaseTempReg(pctemp);
7730 size = AOP_SIZE(result);
7732 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7733 pic14_emitcode("rlc","a");
7734 pic14_emitcode("mov","ov,c");
7735 /* if it is only one byte then */
7737 l = aopGet(AOP(left),0,FALSE,FALSE);
7739 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7740 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7741 pic14_emitcode("mov","c,ov");
7742 pic14_emitcode("rrc","a");
7743 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7744 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7745 aopPut(AOP(result),"a",0);
7749 reAdjustPreg(AOP(result));
7750 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7751 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7752 pic14_emitcode("mov","c,ov");
7754 l = aopGet(AOP(result),offset,FALSE,FALSE);
7756 pic14_emitcode("rrc","a");
7757 aopPut(AOP(result),"a",offset--);
7759 reAdjustPreg(AOP(result));
7760 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7761 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7766 freeAsmop(left,NULL,ic,TRUE);
7767 freeAsmop(result,NULL,ic,TRUE);
7768 freeAsmop(right,NULL,ic,TRUE);
7771 /*-----------------------------------------------------------------*/
7772 /* genRightShift - generate code for right shifting */
7773 /*-----------------------------------------------------------------*/
7774 static void genRightShift (iCode *ic)
7776 operand *right, *left, *result;
7780 symbol *tlbl, *tlbl1 ;
7782 /* if signed then we do it the hard way preserve the
7783 sign bit moving it inwards */
7784 retype = getSpec(operandType(IC_RESULT(ic)));
7785 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7787 if (!SPEC_USIGN(retype)) {
7788 genSignedRightShift (ic);
7792 /* signed & unsigned types are treated the same : i.e. the
7793 signed is NOT propagated inwards : quoting from the
7794 ANSI - standard : "for E1 >> E2, is equivalent to division
7795 by 2**E2 if unsigned or if it has a non-negative value,
7796 otherwise the result is implementation defined ", MY definition
7797 is that the sign does not get propagated */
7799 right = IC_RIGHT(ic);
7801 result = IC_RESULT(ic);
7803 aopOp(right,ic,FALSE);
7805 /* if the shift count is known then do it
7806 as efficiently as possible */
7807 if (AOP_TYPE(right) == AOP_LIT) {
7808 genRightShiftLiteral (left,right,result,ic, 0);
7812 /* shift count is unknown then we have to form
7813 a loop get the loop count in B : Note: we take
7814 only the lower order byte since shifting
7815 more that 32 bits make no sense anyway, ( the
7816 largest size of an object can be only 32 bits ) */
7818 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7819 pic14_emitcode("inc","b");
7820 aopOp(left,ic,FALSE);
7821 aopOp(result,ic,FALSE);
7823 /* now move the left to the result if they are not the
7825 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7826 AOP_SIZE(result) > 1) {
7828 size = AOP_SIZE(result);
7831 l = aopGet(AOP(left),offset,FALSE,TRUE);
7832 if (*l == '@' && IS_AOP_PREG(result)) {
7834 pic14_emitcode("mov","a,%s",l);
7835 aopPut(AOP(result),"a",offset);
7837 aopPut(AOP(result),l,offset);
7842 tlbl = newiTempLabel(NULL);
7843 tlbl1= newiTempLabel(NULL);
7844 size = AOP_SIZE(result);
7847 /* if it is only one byte then */
7850 tlbl = newiTempLabel(NULL);
7851 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7852 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7853 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7856 emitpcode(POC_COMFW, popGet(AOP(right),0));
7857 emitpcode(POC_RLF, popGet(AOP(result),0));
7858 emitpLabel(tlbl->key);
7859 emitpcode(POC_RRF, popGet(AOP(result),0));
7860 emitpcode(POC_ADDLW, popGetLit(1));
7862 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7867 reAdjustPreg(AOP(result));
7868 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7869 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7872 l = aopGet(AOP(result),offset,FALSE,FALSE);
7874 pic14_emitcode("rrc","a");
7875 aopPut(AOP(result),"a",offset--);
7877 reAdjustPreg(AOP(result));
7879 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7880 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7883 freeAsmop(left,NULL,ic,TRUE);
7884 freeAsmop (right,NULL,ic,TRUE);
7885 freeAsmop(result,NULL,ic,TRUE);
7888 /*-----------------------------------------------------------------*/
7889 /* genUnpackBits - generates code for unpacking bits */
7890 /*-----------------------------------------------------------------*/
7891 static void genUnpackBits (operand *result, char *rname, int ptype)
7898 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7899 etype = getSpec(operandType(result));
7901 /* read the first byte */
7906 pic14_emitcode("mov","a,@%s",rname);
7910 pic14_emitcode("movx","a,@%s",rname);
7914 pic14_emitcode("movx","a,@dptr");
7918 pic14_emitcode("clr","a");
7919 pic14_emitcode("movc","a","@a+dptr");
7923 pic14_emitcode("lcall","__gptrget");
7927 /* if we have bitdisplacement then it fits */
7928 /* into this byte completely or if length is */
7929 /* less than a byte */
7930 if ((shCnt = SPEC_BSTR(etype)) ||
7931 (SPEC_BLEN(etype) <= 8)) {
7933 /* shift right acc */
7936 pic14_emitcode("anl","a,#0x%02x",
7937 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7938 aopPut(AOP(result),"a",offset);
7942 /* bit field did not fit in a byte */
7943 rlen = SPEC_BLEN(etype) - 8;
7944 aopPut(AOP(result),"a",offset++);
7951 pic14_emitcode("inc","%s",rname);
7952 pic14_emitcode("mov","a,@%s",rname);
7956 pic14_emitcode("inc","%s",rname);
7957 pic14_emitcode("movx","a,@%s",rname);
7961 pic14_emitcode("inc","dptr");
7962 pic14_emitcode("movx","a,@dptr");
7966 pic14_emitcode("clr","a");
7967 pic14_emitcode("inc","dptr");
7968 pic14_emitcode("movc","a","@a+dptr");
7972 pic14_emitcode("inc","dptr");
7973 pic14_emitcode("lcall","__gptrget");
7978 /* if we are done */
7982 aopPut(AOP(result),"a",offset++);
7987 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7988 aopPut(AOP(result),"a",offset);
7995 /*-----------------------------------------------------------------*/
7996 /* genDataPointerGet - generates code when ptr offset is known */
7997 /*-----------------------------------------------------------------*/
7998 static void genDataPointerGet (operand *left,
8002 int size , offset = 0;
8005 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8008 /* optimization - most of the time, left and result are the same
8009 * address, but different types. for the pic code, we could omit
8013 aopOp(result,ic,TRUE);
8015 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8017 emitpcode(POC_MOVFW, popGet(AOP(left),0));
8019 size = AOP_SIZE(result);
8022 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
8026 freeAsmop(left,NULL,ic,TRUE);
8027 freeAsmop(result,NULL,ic,TRUE);
8030 /*-----------------------------------------------------------------*/
8031 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
8032 /*-----------------------------------------------------------------*/
8033 static void genNearPointerGet (operand *left,
8038 //regs *preg = NULL ;
8040 sym_link *rtype, *retype;
8041 sym_link *ltype = operandType(left);
8044 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8046 rtype = operandType(result);
8047 retype= getSpec(rtype);
8049 aopOp(left,ic,FALSE);
8051 /* if left is rematerialisable and
8052 result is not bit variable type and
8053 the left is pointer to data space i.e
8054 lower 128 bytes of space */
8055 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8056 !IS_BITVAR(retype) &&
8057 DCL_TYPE(ltype) == POINTER) {
8058 //genDataPointerGet (left,result,ic);
8062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8064 /* if the value is already in a pointer register
8065 then don't need anything more */
8066 if (!AOP_INPREG(AOP(left))) {
8067 /* otherwise get a free pointer register */
8068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8071 preg = getFreePtr(ic,&aop,FALSE);
8072 pic14_emitcode("mov","%s,%s",
8074 aopGet(AOP(left),0,FALSE,TRUE));
8075 rname = preg->name ;
8079 rname = aopGet(AOP(left),0,FALSE,FALSE);
8081 aopOp (result,ic,FALSE);
8083 /* if bitfield then unpack the bits */
8084 if (IS_BITVAR(retype))
8085 genUnpackBits (result,rname,POINTER);
8087 /* we have can just get the values */
8088 int size = AOP_SIZE(result);
8091 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8093 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8094 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8096 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8097 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8099 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8103 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8105 pic14_emitcode("mov","a,@%s",rname);
8106 aopPut(AOP(result),"a",offset);
8108 sprintf(buffer,"@%s",rname);
8109 aopPut(AOP(result),buffer,offset);
8113 pic14_emitcode("inc","%s",rname);
8118 /* now some housekeeping stuff */
8120 /* we had to allocate for this iCode */
8121 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8122 freeAsmop(NULL,aop,ic,TRUE);
8124 /* we did not allocate which means left
8125 already in a pointer register, then
8126 if size > 0 && this could be used again
8127 we have to point it back to where it
8129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8130 if (AOP_SIZE(result) > 1 &&
8131 !OP_SYMBOL(left)->remat &&
8132 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8134 int size = AOP_SIZE(result) - 1;
8136 pic14_emitcode("dec","%s",rname);
8141 freeAsmop(left,NULL,ic,TRUE);
8142 freeAsmop(result,NULL,ic,TRUE);
8146 /*-----------------------------------------------------------------*/
8147 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8148 /*-----------------------------------------------------------------*/
8149 static void genPagedPointerGet (operand *left,
8156 sym_link *rtype, *retype;
8158 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8160 rtype = operandType(result);
8161 retype= getSpec(rtype);
8163 aopOp(left,ic,FALSE);
8165 /* if the value is already in a pointer register
8166 then don't need anything more */
8167 if (!AOP_INPREG(AOP(left))) {
8168 /* otherwise get a free pointer register */
8170 preg = getFreePtr(ic,&aop,FALSE);
8171 pic14_emitcode("mov","%s,%s",
8173 aopGet(AOP(left),0,FALSE,TRUE));
8174 rname = preg->name ;
8176 rname = aopGet(AOP(left),0,FALSE,FALSE);
8178 freeAsmop(left,NULL,ic,TRUE);
8179 aopOp (result,ic,FALSE);
8181 /* if bitfield then unpack the bits */
8182 if (IS_BITVAR(retype))
8183 genUnpackBits (result,rname,PPOINTER);
8185 /* we have can just get the values */
8186 int size = AOP_SIZE(result);
8191 pic14_emitcode("movx","a,@%s",rname);
8192 aopPut(AOP(result),"a",offset);
8197 pic14_emitcode("inc","%s",rname);
8201 /* now some housekeeping stuff */
8203 /* we had to allocate for this iCode */
8204 freeAsmop(NULL,aop,ic,TRUE);
8206 /* we did not allocate which means left
8207 already in a pointer register, then
8208 if size > 0 && this could be used again
8209 we have to point it back to where it
8211 if (AOP_SIZE(result) > 1 &&
8212 !OP_SYMBOL(left)->remat &&
8213 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8215 int size = AOP_SIZE(result) - 1;
8217 pic14_emitcode("dec","%s",rname);
8222 freeAsmop(result,NULL,ic,TRUE);
8227 /*-----------------------------------------------------------------*/
8228 /* genFarPointerGet - gget value from far space */
8229 /*-----------------------------------------------------------------*/
8230 static void genFarPointerGet (operand *left,
8231 operand *result, iCode *ic)
8234 sym_link *retype = getSpec(operandType(result));
8236 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8238 aopOp(left,ic,FALSE);
8240 /* if the operand is already in dptr
8241 then we do nothing else we move the value to dptr */
8242 if (AOP_TYPE(left) != AOP_STR) {
8243 /* if this is remateriazable */
8244 if (AOP_TYPE(left) == AOP_IMMD)
8245 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8246 else { /* we need to get it byte by byte */
8247 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8248 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8249 if (options.model == MODEL_FLAT24)
8251 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8255 /* so dptr know contains the address */
8256 freeAsmop(left,NULL,ic,TRUE);
8257 aopOp(result,ic,FALSE);
8259 /* if bit then unpack */
8260 if (IS_BITVAR(retype))
8261 genUnpackBits(result,"dptr",FPOINTER);
8263 size = AOP_SIZE(result);
8267 pic14_emitcode("movx","a,@dptr");
8268 aopPut(AOP(result),"a",offset++);
8270 pic14_emitcode("inc","dptr");
8274 freeAsmop(result,NULL,ic,TRUE);
8277 /*-----------------------------------------------------------------*/
8278 /* genCodePointerGet - get value from code space */
8279 /*-----------------------------------------------------------------*/
8280 static void genCodePointerGet (operand *left,
8281 operand *result, iCode *ic)
8284 sym_link *retype = getSpec(operandType(result));
8286 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8288 aopOp(left,ic,FALSE);
8290 /* if the operand is already in dptr
8291 then we do nothing else we move the value to dptr */
8292 if (AOP_TYPE(left) != AOP_STR) {
8293 /* if this is remateriazable */
8294 if (AOP_TYPE(left) == AOP_IMMD)
8295 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8296 else { /* we need to get it byte by byte */
8297 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8298 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8299 if (options.model == MODEL_FLAT24)
8301 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8305 /* so dptr know contains the address */
8306 freeAsmop(left,NULL,ic,TRUE);
8307 aopOp(result,ic,FALSE);
8309 /* if bit then unpack */
8310 if (IS_BITVAR(retype))
8311 genUnpackBits(result,"dptr",CPOINTER);
8313 size = AOP_SIZE(result);
8317 pic14_emitcode("clr","a");
8318 pic14_emitcode("movc","a,@a+dptr");
8319 aopPut(AOP(result),"a",offset++);
8321 pic14_emitcode("inc","dptr");
8325 freeAsmop(result,NULL,ic,TRUE);
8328 /*-----------------------------------------------------------------*/
8329 /* genGenPointerGet - gget value from generic pointer space */
8330 /*-----------------------------------------------------------------*/
8331 static void genGenPointerGet (operand *left,
8332 operand *result, iCode *ic)
8335 sym_link *retype = getSpec(operandType(result));
8337 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8338 aopOp(left,ic,FALSE);
8339 aopOp(result,ic,FALSE);
8342 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8344 /* if the operand is already in dptr
8345 then we do nothing else we move the value to dptr */
8346 // if (AOP_TYPE(left) != AOP_STR) {
8347 /* if this is remateriazable */
8348 if (AOP_TYPE(left) == AOP_IMMD) {
8349 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8350 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8352 else { /* we need to get it byte by byte */
8354 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8355 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8357 size = AOP_SIZE(result);
8361 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8362 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8364 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8369 /* so dptr know contains the address */
8371 /* if bit then unpack */
8372 //if (IS_BITVAR(retype))
8373 // genUnpackBits(result,"dptr",GPOINTER);
8376 freeAsmop(left,NULL,ic,TRUE);
8377 freeAsmop(result,NULL,ic,TRUE);
8381 /*-----------------------------------------------------------------*/
8382 /* genConstPointerGet - get value from const generic pointer space */
8383 /*-----------------------------------------------------------------*/
8384 static void genConstPointerGet (operand *left,
8385 operand *result, iCode *ic)
8387 //sym_link *retype = getSpec(operandType(result));
8388 symbol *albl = newiTempLabel(NULL);
8389 symbol *blbl = newiTempLabel(NULL);
8392 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8393 aopOp(left,ic,FALSE);
8394 aopOp(result,ic,FALSE);
8397 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8399 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8401 emitpcode(POC_CALL,popGetLabel(albl->key));
8402 emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
8403 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8404 emitpLabel(albl->key);
8406 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8408 emitpcode(poc,popGet(AOP(left),1));
8409 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8410 emitpcode(poc,popGet(AOP(left),0));
8411 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8413 emitpLabel(blbl->key);
8415 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8418 freeAsmop(left,NULL,ic,TRUE);
8419 freeAsmop(result,NULL,ic,TRUE);
8422 /*-----------------------------------------------------------------*/
8423 /* genPointerGet - generate code for pointer get */
8424 /*-----------------------------------------------------------------*/
8425 static void genPointerGet (iCode *ic)
8427 operand *left, *result ;
8428 sym_link *type, *etype;
8431 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8434 result = IC_RESULT(ic) ;
8436 /* depending on the type of pointer we need to
8437 move it to the correct pointer register */
8438 type = operandType(left);
8439 etype = getSpec(type);
8441 if (IS_PTR_CONST(type))
8442 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8444 /* if left is of type of pointer then it is simple */
8445 if (IS_PTR(type) && !IS_FUNC(type->next))
8446 p_type = DCL_TYPE(type);
8448 /* we have to go by the storage class */
8449 p_type = PTR_TYPE(SPEC_OCLS(etype));
8451 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8453 if (SPEC_OCLS(etype)->codesp ) {
8454 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8455 //p_type = CPOINTER ;
8458 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8459 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8460 /*p_type = FPOINTER ;*/
8462 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8463 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8464 /* p_type = PPOINTER; */
8466 if (SPEC_OCLS(etype) == idata )
8467 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8468 /* p_type = IPOINTER; */
8470 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8471 /* p_type = POINTER ; */
8474 /* now that we have the pointer type we assign
8475 the pointer values */
8480 genNearPointerGet (left,result,ic);
8484 genPagedPointerGet(left,result,ic);
8488 genFarPointerGet (left,result,ic);
8492 genConstPointerGet (left,result,ic);
8493 //pic14_emitcodePointerGet (left,result,ic);
8497 if (IS_PTR_CONST(type))
8498 genConstPointerGet (left,result,ic);
8500 genGenPointerGet (left,result,ic);
8506 /*-----------------------------------------------------------------*/
8507 /* genPackBits - generates code for packed bit storage */
8508 /*-----------------------------------------------------------------*/
8509 static void genPackBits (sym_link *etype ,
8511 char *rname, int p_type)
8519 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8520 blen = SPEC_BLEN(etype);
8521 bstr = SPEC_BSTR(etype);
8523 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8526 /* if the bit lenth is less than or */
8527 /* it exactly fits a byte then */
8528 if (SPEC_BLEN(etype) <= 8 ) {
8529 shCount = SPEC_BSTR(etype) ;
8531 /* shift left acc */
8534 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8539 pic14_emitcode ("mov","b,a");
8540 pic14_emitcode("mov","a,@%s",rname);
8544 pic14_emitcode ("mov","b,a");
8545 pic14_emitcode("movx","a,@dptr");
8549 pic14_emitcode ("push","b");
8550 pic14_emitcode ("push","acc");
8551 pic14_emitcode ("lcall","__gptrget");
8552 pic14_emitcode ("pop","b");
8556 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8557 ((unsigned char)(0xFF << (blen+bstr)) |
8558 (unsigned char)(0xFF >> (8-bstr)) ) );
8559 pic14_emitcode ("orl","a,b");
8560 if (p_type == GPOINTER)
8561 pic14_emitcode("pop","b");
8567 pic14_emitcode("mov","@%s,a",rname);
8571 pic14_emitcode("movx","@dptr,a");
8575 DEBUGpic14_emitcode(";lcall","__gptrput");
8580 if ( SPEC_BLEN(etype) <= 8 )
8583 pic14_emitcode("inc","%s",rname);
8584 rLen = SPEC_BLEN(etype) ;
8586 /* now generate for lengths greater than one byte */
8589 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8599 pic14_emitcode("mov","@%s,a",rname);
8601 pic14_emitcode("mov","@%s,%s",rname,l);
8606 pic14_emitcode("movx","@dptr,a");
8611 DEBUGpic14_emitcode(";lcall","__gptrput");
8614 pic14_emitcode ("inc","%s",rname);
8619 /* last last was not complete */
8621 /* save the byte & read byte */
8624 pic14_emitcode ("mov","b,a");
8625 pic14_emitcode("mov","a,@%s",rname);
8629 pic14_emitcode ("mov","b,a");
8630 pic14_emitcode("movx","a,@dptr");
8634 pic14_emitcode ("push","b");
8635 pic14_emitcode ("push","acc");
8636 pic14_emitcode ("lcall","__gptrget");
8637 pic14_emitcode ("pop","b");
8641 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8642 pic14_emitcode ("orl","a,b");
8645 if (p_type == GPOINTER)
8646 pic14_emitcode("pop","b");
8651 pic14_emitcode("mov","@%s,a",rname);
8655 pic14_emitcode("movx","@dptr,a");
8659 DEBUGpic14_emitcode(";lcall","__gptrput");
8663 /*-----------------------------------------------------------------*/
8664 /* genDataPointerSet - remat pointer to data space */
8665 /*-----------------------------------------------------------------*/
8666 static void genDataPointerSet(operand *right,
8670 int size, offset = 0 ;
8671 char *l, buffer[256];
8673 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8674 aopOp(right,ic,FALSE);
8676 l = aopGet(AOP(result),0,FALSE,TRUE);
8677 size = AOP_SIZE(right);
8679 if ( AOP_TYPE(result) == AOP_PCODE) {
8680 fprintf(stderr,"genDataPointerSet %s, %d\n",
8681 AOP(result)->aopu.pcop->name,
8682 PCOI(AOP(result)->aopu.pcop)->offset);
8686 // tsd, was l+1 - the underline `_' prefix was being stripped
8689 sprintf(buffer,"(%s + %d)",l,offset);
8690 fprintf(stderr,"oops %s\n",buffer);
8692 sprintf(buffer,"%s",l);
8694 if (AOP_TYPE(right) == AOP_LIT) {
8695 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8696 lit = lit >> (8*offset);
8698 pic14_emitcode("movlw","%d",lit);
8699 pic14_emitcode("movwf","%s",buffer);
8701 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8702 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8703 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8706 pic14_emitcode("clrf","%s",buffer);
8707 //emitpcode(POC_CLRF, popRegFromString(buffer));
8708 emitpcode(POC_CLRF, popGet(AOP(result),0));
8711 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8712 pic14_emitcode("movwf","%s",buffer);
8714 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8715 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8716 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8723 freeAsmop(right,NULL,ic,TRUE);
8724 freeAsmop(result,NULL,ic,TRUE);
8727 /*-----------------------------------------------------------------*/
8728 /* genNearPointerSet - pic14_emitcode for near pointer put */
8729 /*-----------------------------------------------------------------*/
8730 static void genNearPointerSet (operand *right,
8737 sym_link *ptype = operandType(result);
8740 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8741 retype= getSpec(operandType(right));
8743 aopOp(result,ic,FALSE);
8746 /* if the result is rematerializable &
8747 in data space & not a bit variable */
8748 //if (AOP_TYPE(result) == AOP_IMMD &&
8749 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8750 DCL_TYPE(ptype) == POINTER &&
8751 !IS_BITVAR(retype)) {
8752 genDataPointerSet (right,result,ic);
8753 freeAsmop(result,NULL,ic,TRUE);
8757 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8758 aopOp(right,ic,FALSE);
8759 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8761 /* if the value is already in a pointer register
8762 then don't need anything more */
8763 if (!AOP_INPREG(AOP(result))) {
8764 /* otherwise get a free pointer register */
8765 //aop = newAsmop(0);
8766 //preg = getFreePtr(ic,&aop,FALSE);
8767 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8768 //pic14_emitcode("mov","%s,%s",
8770 // aopGet(AOP(result),0,FALSE,TRUE));
8771 //rname = preg->name ;
8772 //pic14_emitcode("movwf","fsr");
8773 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8774 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8775 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8776 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8780 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8783 /* if bitfield then unpack the bits */
8784 if (IS_BITVAR(retype)) {
8785 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8786 "The programmer is obviously confused");
8787 //genPackBits (retype,right,rname,POINTER);
8791 /* we have can just get the values */
8792 int size = AOP_SIZE(right);
8795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8797 l = aopGet(AOP(right),offset,FALSE,TRUE);
8800 //pic14_emitcode("mov","@%s,a",rname);
8801 pic14_emitcode("movf","indf,w ;1");
8804 if (AOP_TYPE(right) == AOP_LIT) {
8805 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8807 pic14_emitcode("movlw","%s",l);
8808 pic14_emitcode("movwf","indf ;2");
8810 pic14_emitcode("clrf","indf");
8812 pic14_emitcode("movf","%s,w",l);
8813 pic14_emitcode("movwf","indf ;2");
8815 //pic14_emitcode("mov","@%s,%s",rname,l);
8818 pic14_emitcode("incf","fsr,f ;3");
8819 //pic14_emitcode("inc","%s",rname);
8824 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8825 /* now some housekeeping stuff */
8827 /* we had to allocate for this iCode */
8828 freeAsmop(NULL,aop,ic,TRUE);
8830 /* we did not allocate which means left
8831 already in a pointer register, then
8832 if size > 0 && this could be used again
8833 we have to point it back to where it
8835 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8836 if (AOP_SIZE(right) > 1 &&
8837 !OP_SYMBOL(result)->remat &&
8838 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8840 int size = AOP_SIZE(right) - 1;
8842 pic14_emitcode("decf","fsr,f");
8843 //pic14_emitcode("dec","%s",rname);
8847 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8850 freeAsmop(right,NULL,ic,TRUE);
8851 freeAsmop(result,NULL,ic,TRUE);
8854 /*-----------------------------------------------------------------*/
8855 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8856 /*-----------------------------------------------------------------*/
8857 static void genPagedPointerSet (operand *right,
8866 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8868 retype= getSpec(operandType(right));
8870 aopOp(result,ic,FALSE);
8872 /* if the value is already in a pointer register
8873 then don't need anything more */
8874 if (!AOP_INPREG(AOP(result))) {
8875 /* otherwise get a free pointer register */
8877 preg = getFreePtr(ic,&aop,FALSE);
8878 pic14_emitcode("mov","%s,%s",
8880 aopGet(AOP(result),0,FALSE,TRUE));
8881 rname = preg->name ;
8883 rname = aopGet(AOP(result),0,FALSE,FALSE);
8885 freeAsmop(result,NULL,ic,TRUE);
8886 aopOp (right,ic,FALSE);
8888 /* if bitfield then unpack the bits */
8889 if (IS_BITVAR(retype))
8890 genPackBits (retype,right,rname,PPOINTER);
8892 /* we have can just get the values */
8893 int size = AOP_SIZE(right);
8897 l = aopGet(AOP(right),offset,FALSE,TRUE);
8900 pic14_emitcode("movx","@%s,a",rname);
8903 pic14_emitcode("inc","%s",rname);
8909 /* now some housekeeping stuff */
8911 /* we had to allocate for this iCode */
8912 freeAsmop(NULL,aop,ic,TRUE);
8914 /* we did not allocate which means left
8915 already in a pointer register, then
8916 if size > 0 && this could be used again
8917 we have to point it back to where it
8919 if (AOP_SIZE(right) > 1 &&
8920 !OP_SYMBOL(result)->remat &&
8921 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8923 int size = AOP_SIZE(right) - 1;
8925 pic14_emitcode("dec","%s",rname);
8930 freeAsmop(right,NULL,ic,TRUE);
8935 /*-----------------------------------------------------------------*/
8936 /* genFarPointerSet - set value from far space */
8937 /*-----------------------------------------------------------------*/
8938 static void genFarPointerSet (operand *right,
8939 operand *result, iCode *ic)
8942 sym_link *retype = getSpec(operandType(right));
8944 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8945 aopOp(result,ic,FALSE);
8947 /* if the operand is already in dptr
8948 then we do nothing else we move the value to dptr */
8949 if (AOP_TYPE(result) != AOP_STR) {
8950 /* if this is remateriazable */
8951 if (AOP_TYPE(result) == AOP_IMMD)
8952 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8953 else { /* we need to get it byte by byte */
8954 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8955 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8956 if (options.model == MODEL_FLAT24)
8958 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8962 /* so dptr know contains the address */
8963 freeAsmop(result,NULL,ic,TRUE);
8964 aopOp(right,ic,FALSE);
8966 /* if bit then unpack */
8967 if (IS_BITVAR(retype))
8968 genPackBits(retype,right,"dptr",FPOINTER);
8970 size = AOP_SIZE(right);
8974 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8976 pic14_emitcode("movx","@dptr,a");
8978 pic14_emitcode("inc","dptr");
8982 freeAsmop(right,NULL,ic,TRUE);
8985 /*-----------------------------------------------------------------*/
8986 /* genGenPointerSet - set value from generic pointer space */
8987 /*-----------------------------------------------------------------*/
8988 static void genGenPointerSet (operand *right,
8989 operand *result, iCode *ic)
8992 sym_link *retype = getSpec(operandType(right));
8994 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8996 aopOp(result,ic,FALSE);
8997 aopOp(right,ic,FALSE);
8998 size = AOP_SIZE(right);
9000 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9002 /* if the operand is already in dptr
9003 then we do nothing else we move the value to dptr */
9004 if (AOP_TYPE(result) != AOP_STR) {
9005 /* if this is remateriazable */
9006 if (AOP_TYPE(result) == AOP_IMMD) {
9007 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9008 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
9010 else { /* we need to get it byte by byte */
9011 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
9012 size = AOP_SIZE(right);
9015 /* hack hack! see if this the FSR. If so don't load W */
9016 if(AOP_TYPE(right) != AOP_ACC) {
9019 emitpcode(POC_MOVFW,popGet(AOP(result),0));
9020 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9022 if(AOP_SIZE(result) > 1) {
9023 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
9024 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
9025 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
9030 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
9032 // emitpcode(POC_MOVLW,popGetLit(0xfd));
9033 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
9037 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9038 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9041 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9048 if(aopIdx(AOP(result),0) != 4) {
9050 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9054 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9059 /* so dptr know contains the address */
9062 /* if bit then unpack */
9063 if (IS_BITVAR(retype))
9064 genPackBits(retype,right,"dptr",GPOINTER);
9066 size = AOP_SIZE(right);
9069 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9073 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9074 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9076 if (AOP_TYPE(right) == AOP_LIT)
9077 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9079 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9081 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9088 freeAsmop(right,NULL,ic,TRUE);
9089 freeAsmop(result,NULL,ic,TRUE);
9092 /*-----------------------------------------------------------------*/
9093 /* genPointerSet - stores the value into a pointer location */
9094 /*-----------------------------------------------------------------*/
9095 static void genPointerSet (iCode *ic)
9097 operand *right, *result ;
9098 sym_link *type, *etype;
9101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9103 right = IC_RIGHT(ic);
9104 result = IC_RESULT(ic) ;
9106 /* depending on the type of pointer we need to
9107 move it to the correct pointer register */
9108 type = operandType(result);
9109 etype = getSpec(type);
9110 /* if left is of type of pointer then it is simple */
9111 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9112 p_type = DCL_TYPE(type);
9115 /* we have to go by the storage class */
9116 p_type = PTR_TYPE(SPEC_OCLS(etype));
9118 /* if (SPEC_OCLS(etype)->codesp ) { */
9119 /* p_type = CPOINTER ; */
9122 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9123 /* p_type = FPOINTER ; */
9125 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9126 /* p_type = PPOINTER ; */
9128 /* if (SPEC_OCLS(etype) == idata ) */
9129 /* p_type = IPOINTER ; */
9131 /* p_type = POINTER ; */
9134 /* now that we have the pointer type we assign
9135 the pointer values */
9140 genNearPointerSet (right,result,ic);
9144 genPagedPointerSet (right,result,ic);
9148 genFarPointerSet (right,result,ic);
9152 genGenPointerSet (right,result,ic);
9156 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9157 "genPointerSet: illegal pointer type");
9161 /*-----------------------------------------------------------------*/
9162 /* genIfx - generate code for Ifx statement */
9163 /*-----------------------------------------------------------------*/
9164 static void genIfx (iCode *ic, iCode *popIc)
9166 operand *cond = IC_COND(ic);
9169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9171 aopOp(cond,ic,FALSE);
9173 /* get the value into acc */
9174 if (AOP_TYPE(cond) != AOP_CRY)
9175 pic14_toBoolean(cond);
9178 /* the result is now in the accumulator */
9179 freeAsmop(cond,NULL,ic,TRUE);
9181 /* if there was something to be popped then do it */
9185 /* if the condition is a bit variable */
9186 if (isbit && IS_ITEMP(cond) &&
9188 genIfxJump(ic,SPIL_LOC(cond)->rname);
9189 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9192 if (isbit && !IS_ITEMP(cond))
9193 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9201 /*-----------------------------------------------------------------*/
9202 /* genAddrOf - generates code for address of */
9203 /*-----------------------------------------------------------------*/
9204 static void genAddrOf (iCode *ic)
9206 operand *right, *result, *left;
9209 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9212 //aopOp(IC_RESULT(ic),ic,FALSE);
9214 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9215 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9216 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9218 DEBUGpic14_AopType(__LINE__,left,right,result);
9220 size = AOP_SIZE(IC_RESULT(ic));
9224 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9225 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9229 freeAsmop(left,NULL,ic,FALSE);
9230 freeAsmop(result,NULL,ic,TRUE);
9235 /*-----------------------------------------------------------------*/
9236 /* genFarFarAssign - assignment when both are in far space */
9237 /*-----------------------------------------------------------------*/
9238 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9240 int size = AOP_SIZE(right);
9243 /* first push the right side on to the stack */
9245 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9247 pic14_emitcode ("push","acc");
9250 freeAsmop(right,NULL,ic,FALSE);
9251 /* now assign DPTR to result */
9252 aopOp(result,ic,FALSE);
9253 size = AOP_SIZE(result);
9255 pic14_emitcode ("pop","acc");
9256 aopPut(AOP(result),"a",--offset);
9258 freeAsmop(result,NULL,ic,FALSE);
9263 /*-----------------------------------------------------------------*/
9264 /* genAssign - generate code for assignment */
9265 /*-----------------------------------------------------------------*/
9266 static void genAssign (iCode *ic)
9268 operand *result, *right;
9269 int size, offset,know_W;
9270 unsigned long lit = 0L;
9272 result = IC_RESULT(ic);
9273 right = IC_RIGHT(ic) ;
9275 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9277 /* if they are the same */
9278 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9281 aopOp(right,ic,FALSE);
9282 aopOp(result,ic,TRUE);
9284 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9286 /* if they are the same registers */
9287 if (pic14_sameRegs(AOP(right),AOP(result)))
9290 /* if the result is a bit */
9291 if (AOP_TYPE(result) == AOP_CRY) {
9293 /* if the right size is a literal then
9294 we know what the value is */
9295 if (AOP_TYPE(right) == AOP_LIT) {
9297 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9298 popGet(AOP(result),0));
9300 if (((int) operandLitValue(right)))
9301 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9302 AOP(result)->aopu.aop_dir,
9303 AOP(result)->aopu.aop_dir);
9305 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9306 AOP(result)->aopu.aop_dir,
9307 AOP(result)->aopu.aop_dir);
9311 /* the right is also a bit variable */
9312 if (AOP_TYPE(right) == AOP_CRY) {
9313 emitpcode(POC_BCF, popGet(AOP(result),0));
9314 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9315 emitpcode(POC_BSF, popGet(AOP(result),0));
9317 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9318 AOP(result)->aopu.aop_dir,
9319 AOP(result)->aopu.aop_dir);
9320 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9321 AOP(right)->aopu.aop_dir,
9322 AOP(right)->aopu.aop_dir);
9323 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9324 AOP(result)->aopu.aop_dir,
9325 AOP(result)->aopu.aop_dir);
9330 emitpcode(POC_BCF, popGet(AOP(result),0));
9331 pic14_toBoolean(right);
9333 emitpcode(POC_BSF, popGet(AOP(result),0));
9334 //aopPut(AOP(result),"a",0);
9338 /* bit variables done */
9340 size = AOP_SIZE(result);
9342 if(AOP_TYPE(right) == AOP_LIT)
9343 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9345 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9347 if(aopIdx(AOP(result),0) == 4) {
9348 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9349 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9350 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9353 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9358 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9359 if(AOP_TYPE(right) == AOP_LIT) {
9361 if(know_W != (int)(lit&0xff))
9362 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9364 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9366 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9370 } else if (AOP_TYPE(right) == AOP_CRY) {
9371 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9373 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9374 emitpcode(POC_INCF, popGet(AOP(result),0));
9377 mov2w (AOP(right), offset);
9378 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9386 freeAsmop (right,NULL,ic,FALSE);
9387 freeAsmop (result,NULL,ic,TRUE);
9390 /*-----------------------------------------------------------------*/
9391 /* genJumpTab - genrates code for jump table */
9392 /*-----------------------------------------------------------------*/
9393 static void genJumpTab (iCode *ic)
9398 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9400 aopOp(IC_JTCOND(ic),ic,FALSE);
9401 /* get the condition into accumulator */
9402 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9404 /* multiply by three */
9405 pic14_emitcode("add","a,acc");
9406 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9408 jtab = newiTempLabel(NULL);
9409 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9410 pic14_emitcode("jmp","@a+dptr");
9411 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9413 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9414 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9415 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9416 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9418 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9419 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9420 emitpLabel(jtab->key);
9422 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9424 /* now generate the jump labels */
9425 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9426 jtab = setNextItem(IC_JTLABELS(ic))) {
9427 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9428 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9434 /*-----------------------------------------------------------------*/
9435 /* genMixedOperation - gen code for operators between mixed types */
9436 /*-----------------------------------------------------------------*/
9438 TSD - Written for the PIC port - but this unfortunately is buggy.
9439 This routine is good in that it is able to efficiently promote
9440 types to different (larger) sizes. Unfortunately, the temporary
9441 variables that are optimized out by this routine are sometimes
9442 used in other places. So until I know how to really parse the
9443 iCode tree, I'm going to not be using this routine :(.
9445 static int genMixedOperation (iCode *ic)
9448 operand *result = IC_RESULT(ic);
9449 sym_link *ctype = operandType(IC_LEFT(ic));
9450 operand *right = IC_RIGHT(ic);
9456 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9458 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9464 nextright = IC_RIGHT(nextic);
9465 nextleft = IC_LEFT(nextic);
9466 nextresult = IC_RESULT(nextic);
9468 aopOp(right,ic,FALSE);
9469 aopOp(result,ic,FALSE);
9470 aopOp(nextright, nextic, FALSE);
9471 aopOp(nextleft, nextic, FALSE);
9472 aopOp(nextresult, nextic, FALSE);
9474 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9480 pic14_emitcode(";remove right +","");
9482 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9488 pic14_emitcode(";remove left +","");
9492 big = AOP_SIZE(nextleft);
9493 small = AOP_SIZE(nextright);
9495 switch(nextic->op) {
9498 pic14_emitcode(";optimize a +","");
9499 /* if unsigned or not an integral type */
9500 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9501 pic14_emitcode(";add a bit to something","");
9504 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9506 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9507 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9508 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9510 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9518 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9519 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9520 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9523 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9525 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9526 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9527 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9528 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9529 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9532 pic14_emitcode("rlf","known_zero,w");
9539 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9540 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9541 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9543 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9553 freeAsmop(right,NULL,ic,TRUE);
9554 freeAsmop(result,NULL,ic,TRUE);
9555 freeAsmop(nextright,NULL,ic,TRUE);
9556 freeAsmop(nextleft,NULL,ic,TRUE);
9558 nextic->generated = 1;
9565 /*-----------------------------------------------------------------*/
9566 /* genCast - gen code for casting */
9567 /*-----------------------------------------------------------------*/
9568 static void genCast (iCode *ic)
9570 operand *result = IC_RESULT(ic);
9571 sym_link *ctype = operandType(IC_LEFT(ic));
9572 sym_link *rtype = operandType(IC_RIGHT(ic));
9573 operand *right = IC_RIGHT(ic);
9576 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9577 /* if they are equivalent then do nothing */
9578 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9581 aopOp(right,ic,FALSE) ;
9582 aopOp(result,ic,FALSE);
9584 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9586 /* if the result is a bit */
9587 if (AOP_TYPE(result) == AOP_CRY) {
9588 /* if the right size is a literal then
9589 we know what the value is */
9590 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9591 if (AOP_TYPE(right) == AOP_LIT) {
9593 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9594 popGet(AOP(result),0));
9596 if (((int) operandLitValue(right)))
9597 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9598 AOP(result)->aopu.aop_dir,
9599 AOP(result)->aopu.aop_dir);
9601 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9602 AOP(result)->aopu.aop_dir,
9603 AOP(result)->aopu.aop_dir);
9608 /* the right is also a bit variable */
9609 if (AOP_TYPE(right) == AOP_CRY) {
9612 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9614 pic14_emitcode("clrc","");
9615 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9616 AOP(right)->aopu.aop_dir,
9617 AOP(right)->aopu.aop_dir);
9618 aopPut(AOP(result),"c",0);
9623 if (AOP_TYPE(right) == AOP_REG) {
9624 emitpcode(POC_BCF, popGet(AOP(result),0));
9625 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9626 emitpcode(POC_BSF, popGet(AOP(result),0));
9628 pic14_toBoolean(right);
9629 aopPut(AOP(result),"a",0);
9633 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9635 size = AOP_SIZE(result);
9637 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9639 emitpcode(POC_CLRF, popGet(AOP(result),0));
9640 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9641 emitpcode(POC_INCF, popGet(AOP(result),0));
9644 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9649 /* if they are the same size : or less */
9650 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9652 /* if they are in the same place */
9653 if (pic14_sameRegs(AOP(right),AOP(result)))
9656 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9657 if (IS_PTR_CONST(rtype))
9658 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9659 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9660 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9662 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9663 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9664 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9665 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9666 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9667 if(AOP_SIZE(result) <2)
9668 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9672 /* if they in different places then copy */
9673 size = AOP_SIZE(result);
9676 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9677 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9679 //aopPut(AOP(result),
9680 // aopGet(AOP(right),offset,FALSE,FALSE),
9690 /* if the result is of type pointer */
9691 if (IS_PTR(ctype)) {
9694 sym_link *type = operandType(right);
9695 sym_link *etype = getSpec(type);
9696 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9698 /* pointer to generic pointer */
9699 if (IS_GENPTR(ctype)) {
9703 p_type = DCL_TYPE(type);
9705 /* we have to go by the storage class */
9706 p_type = PTR_TYPE(SPEC_OCLS(etype));
9708 /* if (SPEC_OCLS(etype)->codesp ) */
9709 /* p_type = CPOINTER ; */
9711 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9712 /* p_type = FPOINTER ; */
9714 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9715 /* p_type = PPOINTER; */
9717 /* if (SPEC_OCLS(etype) == idata ) */
9718 /* p_type = IPOINTER ; */
9720 /* p_type = POINTER ; */
9723 /* the first two bytes are known */
9724 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9725 size = GPTRSIZE - 1;
9728 if(offset < AOP_SIZE(right)) {
9729 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9730 if ((AOP_TYPE(right) == AOP_PCODE) &&
9731 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9732 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9733 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9736 aopGet(AOP(right),offset,FALSE,FALSE),
9740 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9743 /* the last byte depending on type */
9747 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9750 pic14_emitcode(";BUG!? ","%d",__LINE__);
9754 pic14_emitcode(";BUG!? ","%d",__LINE__);
9758 pic14_emitcode(";BUG!? ","%d",__LINE__);
9763 /* this should never happen */
9764 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9765 "got unknown pointer type");
9768 //aopPut(AOP(result),l, GPTRSIZE - 1);
9772 /* just copy the pointers */
9773 size = AOP_SIZE(result);
9777 aopGet(AOP(right),offset,FALSE,FALSE),
9786 /* so we now know that the size of destination is greater
9787 than the size of the source.
9788 Now, if the next iCode is an operator then we might be
9789 able to optimize the operation without performing a cast.
9791 if(genMixedOperation(ic))
9794 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9796 /* we move to result for the size of source */
9797 size = AOP_SIZE(right);
9800 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9801 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9805 /* now depending on the sign of the destination */
9806 size = AOP_SIZE(result) - AOP_SIZE(right);
9807 /* if unsigned or not an integral type */
9808 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9810 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9812 /* we need to extend the sign :{ */
9815 /* Save one instruction of casting char to int */
9816 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9817 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9818 emitpcode(POC_DECF, popGet(AOP(result),offset));
9820 emitpcodeNULLop(POC_CLRW);
9823 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9825 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9827 emitpcode(POC_MOVLW, popGetLit(0xff));
9830 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9835 freeAsmop(right,NULL,ic,TRUE);
9836 freeAsmop(result,NULL,ic,TRUE);
9840 /*-----------------------------------------------------------------*/
9841 /* genDjnz - generate decrement & jump if not zero instrucion */
9842 /*-----------------------------------------------------------------*/
9843 static int genDjnz (iCode *ic, iCode *ifx)
9846 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9851 /* if the if condition has a false label
9852 then we cannot save */
9856 /* if the minus is not of the form
9858 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9859 !IS_OP_LITERAL(IC_RIGHT(ic)))
9862 if (operandLitValue(IC_RIGHT(ic)) != 1)
9865 /* if the size of this greater than one then no
9867 if (getSize(operandType(IC_RESULT(ic))) > 1)
9870 /* otherwise we can save BIG */
9871 lbl = newiTempLabel(NULL);
9872 lbl1= newiTempLabel(NULL);
9874 aopOp(IC_RESULT(ic),ic,FALSE);
9876 if (IS_AOP_PREG(IC_RESULT(ic))) {
9877 pic14_emitcode("dec","%s",
9878 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9879 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9880 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9884 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9885 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9887 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9888 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9891 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9892 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9893 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9894 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9897 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9902 /*-----------------------------------------------------------------*/
9903 /* genReceive - generate code for a receive iCode */
9904 /*-----------------------------------------------------------------*/
9905 static void genReceive (iCode *ic)
9907 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9909 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9910 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9911 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9913 int size = getSize(operandType(IC_RESULT(ic)));
9914 int offset = fReturnSizePic - size;
9916 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9917 fReturn[fReturnSizePic - offset - 1] : "acc"));
9920 aopOp(IC_RESULT(ic),ic,FALSE);
9921 size = AOP_SIZE(IC_RESULT(ic));
9924 pic14_emitcode ("pop","acc");
9925 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9930 aopOp(IC_RESULT(ic),ic,FALSE);
9932 assignResultValue(IC_RESULT(ic));
9935 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9938 /*-----------------------------------------------------------------*/
9939 /* genDummyRead - generate code for dummy read of volatiles */
9940 /*-----------------------------------------------------------------*/
9942 genDummyRead (iCode * ic)
9944 pic14_emitcode ("; genDummyRead","");
9945 pic14_emitcode ("; not implemented","");
9950 /*-----------------------------------------------------------------*/
9951 /* genpic14Code - generate code for pic14 based controllers */
9952 /*-----------------------------------------------------------------*/
9954 * At this point, ralloc.c has gone through the iCode and attempted
9955 * to optimize in a way suitable for a PIC. Now we've got to generate
9956 * PIC instructions that correspond to the iCode.
9958 * Once the instructions are generated, we'll pass through both the
9959 * peep hole optimizer and the pCode optimizer.
9960 *-----------------------------------------------------------------*/
9962 void genpic14Code (iCode *lic)
9967 lineHead = lineCurr = NULL;
9969 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9972 /* if debug information required */
9973 if (options.debug && currFunc) {
9975 debugFile->writeFunction(currFunc);
9977 if (IS_STATIC(currFunc->etype)) {
9978 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9979 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9981 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9982 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9989 for (ic = lic ; ic ; ic = ic->next ) {
9991 DEBUGpic14_emitcode(";ic","");
9992 if ( cln != ic->lineno ) {
9993 if ( options.debug ) {
9995 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9996 FileBaseName(ic->filename),ic->lineno,
9997 ic->level,ic->block);
10001 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
10002 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
10003 printCLine(ic->filename, ic->lineno));
10005 if (!options.noCcodeInAsm) {
10006 addpCode2pBlock(pb,
10007 newpCodeCSource(ic->lineno,
10009 printCLine(ic->filename, ic->lineno)));
10015 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
10017 /* if the result is marked as
10018 spilt and rematerializable or code for
10019 this has already been generated then
10021 if (resultRemat(ic) || ic->generated )
10024 /* depending on the operation */
10043 /* IPOP happens only when trying to restore a
10044 spilt live range, if there is an ifx statement
10045 following this pop then the if statement might
10046 be using some of the registers being popped which
10047 would destory the contents of the register so
10048 we need to check for this condition and handle it */
10050 ic->next->op == IFX &&
10051 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10052 genIfx (ic->next,ic);
10070 genEndFunction (ic);
10090 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10107 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10111 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10118 /* note these two are xlated by algebraic equivalence
10119 during parsing SDCC.y */
10120 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10121 "got '>=' or '<=' shouldn't have come here");
10125 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10137 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10141 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10145 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10169 genRightShift (ic);
10172 case GET_VALUE_AT_ADDRESS:
10177 if (POINTER_SET(ic))
10204 addSet(&_G.sendSet,ic);
10207 case DUMMY_READ_VOLATILE:
10217 /* now we are ready to call the
10218 peep hole optimizer */
10219 if (!options.nopeep) {
10220 peepHole (&lineHead);
10222 /* now do the actual printing */
10223 printLine (lineHead,codeOutFile);
10226 DFPRINTF((stderr,"printing pBlock\n\n"));
10227 printpBlock(stdout,pb);