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 extern void printpBlock(FILE *of, pBlock *pb);
51 static int labelOffset=0;
52 extern int debug_verbose;
53 static int optimized_for_speed = 0;
55 /* max_key keeps track of the largest label number used in
56 a function. This is then used to adjust the label offset
57 for the next function.
60 static int GpsuedoStkPtr=0;
62 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
63 unsigned int pic14aopLiteral (value *val, int offset);
64 const char *AopType(short type);
66 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
68 /* this is the down and dirty file with all kinds of
69 kludgy & hacky stuff. This is what it is all about
70 CODE GENERATION for a specific MCU . some of the
71 routines may be reusable, will have to see */
73 static char *zero = "#0x00";
74 static char *one = "#0x01";
75 static char *spname = "sp";
77 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
78 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
79 static char **fReturn = fReturnpic14;
81 static char *accUse[] = {"a","b"};
83 //static short rbank = -1;
95 /* Resolved ifx structure. This structure stores information
96 about an iCode ifx that makes it easier to generate code.
98 typedef struct resolvedIfx {
99 symbol *lbl; /* pointer to a label */
100 int condition; /* true or false ifx */
101 int generated; /* set true when the code associated with the ifx
105 extern int pic14_ptrRegReq ;
106 extern int pic14_nRegs;
107 extern FILE *codeOutFile;
108 static void saverbank (int, iCode *,bool);
110 static lineNode *lineHead = NULL;
111 static lineNode *lineCurr = NULL;
113 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
114 0xE0, 0xC0, 0x80, 0x00};
115 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
116 0x07, 0x03, 0x01, 0x00};
120 /*-----------------------------------------------------------------*/
121 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
122 /* exponent of 2 is returned, otherwise -1 is */
124 /* note that this is similar to the function `powof2' in SDCCsymt */
128 /*-----------------------------------------------------------------*/
129 static int my_powof2 (unsigned long num)
132 if( (num & (num-1)) == 0) {
145 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
148 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
150 ((result) ? AopType(AOP_TYPE(result)) : "-"),
151 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
152 ((left) ? AopType(AOP_TYPE(left)) : "-"),
153 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
154 ((right) ? AopType(AOP_TYPE(right)) : "-"),
155 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
156 ((result) ? AOP_SIZE(result) : 0));
160 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
163 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
165 ((result) ? AopType(AOP_TYPE(result)) : "-"),
166 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
167 ((left) ? AopType(AOP_TYPE(left)) : "-"),
168 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
169 ((right) ? AopType(AOP_TYPE(right)) : "-"),
170 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
174 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
177 char lb[INITIAL_INLINEASM];
187 sprintf(lb,"%s\t",inst);
189 sprintf(lb,"%s",inst);
190 vsprintf(lb+(strlen(lb)),fmt,ap);
194 while (isspace(*lbp)) lbp++;
197 lineCurr = (lineCurr ?
198 connectLine(lineCurr,newLineNode(lb)) :
199 (lineHead = newLineNode(lb)));
200 lineCurr->isInline = _G.inLine;
201 lineCurr->isDebug = _G.debugLine;
203 addpCode2pBlock(pb,newpCodeCharP(lb));
209 void emitpLabel(int key)
211 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
214 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
217 addpCode2pBlock(pb,newpCode(poc,pcop));
219 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
222 void emitpcodeNULLop(PIC_OPCODE poc)
225 addpCode2pBlock(pb,newpCode(poc,NULL));
230 /*-----------------------------------------------------------------*/
231 /* pic14_emitcode - writes the code into a file : for now it is simple */
232 /*-----------------------------------------------------------------*/
233 void pic14_emitcode (char *inst,char *fmt, ...)
236 char lb[INITIAL_INLINEASM];
243 sprintf(lb,"%s\t",inst);
245 sprintf(lb,"%s",inst);
246 vsprintf(lb+(strlen(lb)),fmt,ap);
250 while (isspace(*lbp)) lbp++;
253 lineCurr = (lineCurr ?
254 connectLine(lineCurr,newLineNode(lb)) :
255 (lineHead = newLineNode(lb)));
256 lineCurr->isInline = _G.inLine;
257 lineCurr->isDebug = _G.debugLine;
260 addpCode2pBlock(pb,newpCodeCharP(lb));
265 /*-----------------------------------------------------------------*/
266 /* pic14_emitDebuggerSymbol - associate the current code location */
267 /* with a debugger symbol */
268 /*-----------------------------------------------------------------*/
270 pic14_emitDebuggerSymbol (char * debugSym)
273 pic14_emitcode ("", ";%s ==.", debugSym);
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 (sym1->rname[0] && sym2->rname[0]
698 && strcmp (sym1->rname, sym2->rname) == 0)
702 /* if left is a tmp & right is not */
706 (sym1->usl.spillLoc == sym2))
713 (sym2->usl.spillLoc == sym1))
719 /*-----------------------------------------------------------------*/
720 /* pic14_sameRegs - two asmops have the same registers */
721 /*-----------------------------------------------------------------*/
722 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
729 if (aop1->type != AOP_REG ||
730 aop2->type != AOP_REG )
733 if (aop1->size != aop2->size )
736 for (i = 0 ; i < aop1->size ; i++ )
737 if (aop1->aopu.aop_reg[i] !=
738 aop2->aopu.aop_reg[i] )
744 /*-----------------------------------------------------------------*/
745 /* aopOp - allocates an asmop for an operand : */
746 /*-----------------------------------------------------------------*/
747 void aopOp (operand *op, iCode *ic, bool result)
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 = aopForRemat (op);
816 aop->size = getSize(sym->type);
817 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
823 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
824 aop->size = getSize(sym->type);
825 for ( i = 0 ; i < 2 ; i++ )
826 aop->aopu.aop_str[i] = accUse[i];
827 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
832 if(sym->isptr) { // && sym->uptr
833 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
834 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
836 //PCOI(aop->aopu.pcop)->_const = 0;
837 //PCOI(aop->aopu.pcop)->index = 0;
839 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
840 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
842 //allocDirReg (IC_LEFT(ic));
844 aop->size = getSize(sym->type);
845 DEBUGpic14_emitcode(";","%d",__LINE__);
852 aop = op->aop = sym->aop = newAsmop(AOP_STR);
853 aop->size = getSize(sym->type);
854 for ( i = 0 ; i < fReturnSizePic ; i++ )
855 aop->aopu.aop_str[i] = fReturn[i];
857 DEBUGpic14_emitcode(";","%d",__LINE__);
862 /* else spill location */
863 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
864 /* force a new aop if sizes differ */
865 sym->usl.spillLoc->aop = NULL;
867 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
868 __FUNCTION__,__LINE__,
869 sym->usl.spillLoc->rname,
870 sym->rname, sym->usl.spillLoc->offset);
872 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
873 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
874 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
876 sym->usl.spillLoc->offset);
877 aop->size = getSize(sym->type);
883 sym_link *type = operandType(op);
884 if(IS_PTR_CONST(type))
885 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
888 /* must be in a register */
889 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
890 sym->aop = op->aop = aop = newAsmop(AOP_REG);
891 aop->size = sym->nRegs;
892 for ( i = 0 ; i < sym->nRegs ;i++)
893 aop->aopu.aop_reg[i] = sym->regs[i];
896 /*-----------------------------------------------------------------*/
897 /* freeAsmop - free up the asmop given to an operand */
898 /*----------------------------------------------------------------*/
899 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
916 /* depending on the asmop type only three cases need work AOP_RO
917 , AOP_R1 && AOP_STK */
923 pic14_emitcode ("pop","ar0");
927 bitVectUnSetBit(ic->rUsed,R0_IDX);
933 pic14_emitcode ("pop","ar1");
937 bitVectUnSetBit(ic->rUsed,R1_IDX);
943 int stk = aop->aopu.aop_stk + aop->size;
944 bitVectUnSetBit(ic->rUsed,R0_IDX);
945 bitVectUnSetBit(ic->rUsed,R1_IDX);
947 getFreePtr(ic,&aop,FALSE);
949 if (options.stack10bit)
951 /* I'm not sure what to do here yet... */
954 "*** Warning: probably generating bad code for "
955 "10 bit stack mode.\n");
959 pic14_emitcode ("mov","a,_bp");
960 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
961 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
963 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
967 pic14_emitcode("pop","acc");
968 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
970 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
973 freeAsmop(op,NULL,ic,TRUE);
975 pic14_emitcode("pop","ar0");
980 pic14_emitcode("pop","ar1");
988 /* all other cases just dealloc */
992 OP_SYMBOL(op)->aop = NULL;
993 /* if the symbol has a spill */
995 SPIL_LOC(op)->aop = NULL;
1000 /*-----------------------------------------------------------------*/
1001 /* aopGet - for fetching value of the aop */
1002 /*-----------------------------------------------------------------*/
1003 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1008 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1009 /* offset is greater than
1011 if (offset > (aop->size - 1) &&
1012 aop->type != AOP_LIT)
1015 /* depending on type */
1016 switch (aop->type) {
1020 DEBUGpic14_emitcode(";","%d",__LINE__);
1021 /* if we need to increment it */
1022 while (offset > aop->coff) {
1023 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1027 while (offset < aop->coff) {
1028 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1032 aop->coff = offset ;
1034 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1035 return (dname ? "acc" : "a");
1037 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1038 rs = Safe_calloc(1,strlen(s)+1);
1044 DEBUGpic14_emitcode(";","%d",__LINE__);
1045 if (aop->type == AOP_DPTR2)
1050 while (offset > aop->coff) {
1051 pic14_emitcode ("inc","dptr");
1055 while (offset < aop->coff) {
1056 pic14_emitcode("lcall","__decdptr");
1062 pic14_emitcode("clr","a");
1063 pic14_emitcode("movc","a,@a+dptr");
1066 pic14_emitcode("movx","a,@dptr");
1069 if (aop->type == AOP_DPTR2)
1074 return (dname ? "acc" : "a");
1079 sprintf (s,"%s",aop->aopu.aop_immd);
1082 sprintf(s,"(%s >> %d)",
1087 aop->aopu.aop_immd);
1088 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1089 rs = Safe_calloc(1,strlen(s)+1);
1095 sprintf(s,"(%s + %d)",
1098 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1100 sprintf(s,"%s",aop->aopu.aop_dir);
1101 rs = Safe_calloc(1,strlen(s)+1);
1107 // return aop->aopu.aop_reg[offset]->dname;
1109 return aop->aopu.aop_reg[offset]->name;
1112 //pic14_emitcode(";","%d",__LINE__);
1113 return aop->aopu.aop_dir;
1116 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1117 return "AOP_accumulator_bug";
1120 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1121 rs = Safe_calloc(1,strlen(s)+1);
1126 aop->coff = offset ;
1127 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1130 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1132 return aop->aopu.aop_str[offset];
1136 pCodeOp *pcop = aop->aopu.pcop;
1137 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1140 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset);
1141 sprintf(s,"(%s+%d)", pcop->name,offset);
1143 DEBUGpic14_emitcode(";","%s",pcop->name);
1144 sprintf(s,"%s", pcop->name);
1147 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1150 rs = Safe_calloc(1,strlen(s)+1);
1156 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1157 "aopget got unsupported aop->type");
1162 /*-----------------------------------------------------------------*/
1163 /* popGetTempReg - create a new temporary pCodeOp */
1164 /*-----------------------------------------------------------------*/
1165 pCodeOp *popGetTempReg(void)
1170 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1171 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1172 PCOR(pcop)->r->wasUsed=1;
1173 PCOR(pcop)->r->isFree=0;
1179 /*-----------------------------------------------------------------*/
1180 /* popReleaseTempReg - create a new temporary pCodeOp */
1181 /*-----------------------------------------------------------------*/
1182 void popReleaseTempReg(pCodeOp *pcop)
1185 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1186 PCOR(pcop)->r->isFree = 1;
1189 /*-----------------------------------------------------------------*/
1190 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1191 /*-----------------------------------------------------------------*/
1192 pCodeOp *popGetLabel(unsigned int key)
1195 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1197 if(key>(unsigned int)max_key)
1200 return newpCodeOpLabel(NULL,key+100+labelOffset);
1203 /*-------------------------------------------------------------------*/
1204 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1205 /*-------------------------------------------------------------------*/
1206 pCodeOp *popGetHighLabel(unsigned int key)
1209 pcop = popGetLabel(key);
1210 PCOLAB(pcop)->offset = 1;
1214 /*-----------------------------------------------------------------*/
1215 /* popGetLit - asm operator to pcode operator conversion */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetLit(unsigned int lit)
1220 return newpCodeOpLit(lit);
1223 /*-----------------------------------------------------------------*/
1224 /* popGetImmd - asm operator to pcode immediate conversion */
1225 /*-----------------------------------------------------------------*/
1226 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1229 return newpCodeOpImmd(name, offset,index, 0, is_func);
1233 /*-----------------------------------------------------------------*/
1234 /* popGetWithString - asm operator to pcode operator conversion */
1235 /*-----------------------------------------------------------------*/
1236 pCodeOp *popGetWithString(char *str, int isExtern)
1242 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1246 pcop = newpCodeOp(str,PO_STR);
1247 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1252 /*-----------------------------------------------------------------*/
1253 /* popRegFromString - */
1254 /*-----------------------------------------------------------------*/
1255 pCodeOp *popRegFromString(char *str, int size, int offset)
1258 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1259 pcop->type = PO_DIR;
1261 DEBUGpic14_emitcode(";","%d",__LINE__);
1266 pcop->name = Safe_calloc(1,strlen(str)+1);
1267 strcpy(pcop->name,str);
1269 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1271 PCOR(pcop)->r = dirregWithName(pcop->name);
1272 if(PCOR(pcop)->r == NULL) {
1273 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1274 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1275 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1277 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1279 PCOR(pcop)->instance = offset;
1284 /*-----------------------------------------------------------------*/
1285 /*-----------------------------------------------------------------*/
1286 pCodeOp *popRegFromIdx(int rIdx)
1290 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1291 __FUNCTION__,__LINE__,rIdx);
1293 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1295 PCOR(pcop)->rIdx = rIdx;
1296 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1297 PCOR(pcop)->r->isFree = 0;
1298 PCOR(pcop)->r->wasUsed = 1;
1300 pcop->type = PCOR(pcop)->r->pc_type;
1306 /*-----------------------------------------------------------------*/
1307 /* popGet - asm operator to pcode operator conversion */
1308 /*-----------------------------------------------------------------*/
1309 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1311 //char *s = buffer ;
1316 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1317 /* offset is greater than
1320 if (offset > (aop->size - 1) &&
1321 aop->type != AOP_LIT)
1322 return NULL; //zero;
1324 /* depending on type */
1325 switch (aop->type) {
1332 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1336 DEBUGpic14_emitcode(";","%d",__LINE__);
1337 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1340 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1342 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1343 pcop->type = PO_DIR;
1345 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1346 strcpy(pcop->name,aop->aopu.aop_dir);
1347 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1348 if(PCOR(pcop)->r == NULL) {
1349 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1350 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1351 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1353 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1355 PCOR(pcop)->instance = offset;
1362 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1364 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1365 PCOR(pcop)->rIdx = rIdx;
1366 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1367 PCOR(pcop)->r->wasUsed=1;
1368 PCOR(pcop)->r->isFree=0;
1370 PCOR(pcop)->instance = offset;
1371 pcop->type = PCOR(pcop)->r->pc_type;
1372 //rs = aop->aopu.aop_reg[offset]->name;
1373 DEBUGpic14_emitcode(";","%d rIdx = r0x%X ",__LINE__,rIdx);
1378 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
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\n",__LINE__,aop->aopu.aop_dir);
1385 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1388 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1389 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1391 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1392 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1393 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1394 pcop->type = PCOR(pcop)->r->pc_type;
1395 pcop->name = PCOR(pcop)->r->name;
1401 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1403 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1404 pcop = pCodeOpCopy(aop->aopu.pcop);
1405 PCOI(pcop)->offset = offset;
1409 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1410 "popGet got unsupported aop->type");
1413 /*-----------------------------------------------------------------*/
1414 /* aopPut - puts a string for a aop */
1415 /*-----------------------------------------------------------------*/
1416 void aopPut (asmop *aop, char *s, int offset)
1421 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1423 if (aop->size && offset > ( aop->size - 1)) {
1424 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1425 "aopPut got offset > aop->size");
1429 /* will assign value to value */
1430 /* depending on where it is ofcourse */
1431 switch (aop->type) {
1434 sprintf(d,"(%s + %d)",
1435 aop->aopu.aop_dir,offset);
1436 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1439 sprintf(d,"%s",aop->aopu.aop_dir);
1442 DEBUGpic14_emitcode(";","%d",__LINE__);
1444 pic14_emitcode("movf","%s,w",s);
1445 pic14_emitcode("movwf","%s",d);
1448 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1449 if(offset >= aop->size) {
1450 emitpcode(POC_CLRF,popGet(aop,offset));
1453 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1456 emitpcode(POC_MOVWF,popGet(aop,offset));
1463 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) {
1464 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1467 strcmp(s,"r0") == 0 ||
1468 strcmp(s,"r1") == 0 ||
1469 strcmp(s,"r2") == 0 ||
1470 strcmp(s,"r3") == 0 ||
1471 strcmp(s,"r4") == 0 ||
1472 strcmp(s,"r5") == 0 ||
1473 strcmp(s,"r6") == 0 ||
1474 strcmp(s,"r7") == 0 )
1475 pic14_emitcode("mov","%s,%s ; %d",
1476 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1480 if(strcmp(s,"W")==0 )
1481 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1483 pic14_emitcode("movwf","%s",
1484 aop->aopu.aop_reg[offset]->name);
1486 if(strcmp(s,zero)==0) {
1487 emitpcode(POC_CLRF,popGet(aop,offset));
1489 } else if(strcmp(s,"W")==0) {
1490 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1491 pcop->type = PO_GPR_REGISTER;
1493 PCOR(pcop)->rIdx = -1;
1494 PCOR(pcop)->r = NULL;
1496 DEBUGpic14_emitcode(";","%d",__LINE__);
1497 pcop->name = Safe_strdup(s);
1498 emitpcode(POC_MOVFW,pcop);
1499 emitpcode(POC_MOVWF,popGet(aop,offset));
1500 } else if(strcmp(s,one)==0) {
1501 emitpcode(POC_CLRF,popGet(aop,offset));
1502 emitpcode(POC_INCF,popGet(aop,offset));
1504 emitpcode(POC_MOVWF,popGet(aop,offset));
1512 if (aop->type == AOP_DPTR2)
1518 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1519 "aopPut writting to code space");
1523 while (offset > aop->coff) {
1525 pic14_emitcode ("inc","dptr");
1528 while (offset < aop->coff) {
1530 pic14_emitcode("lcall","__decdptr");
1535 /* if not in accumulater */
1538 pic14_emitcode ("movx","@dptr,a");
1540 if (aop->type == AOP_DPTR2)
1548 while (offset > aop->coff) {
1550 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1552 while (offset < aop->coff) {
1554 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1560 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1565 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1567 if (strcmp(s,"r0") == 0 ||
1568 strcmp(s,"r1") == 0 ||
1569 strcmp(s,"r2") == 0 ||
1570 strcmp(s,"r3") == 0 ||
1571 strcmp(s,"r4") == 0 ||
1572 strcmp(s,"r5") == 0 ||
1573 strcmp(s,"r6") == 0 ||
1574 strcmp(s,"r7") == 0 ) {
1576 sprintf(buffer,"a%s",s);
1577 pic14_emitcode("mov","@%s,%s",
1578 aop->aopu.aop_ptr->name,buffer);
1580 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1585 if (strcmp(s,"a") == 0)
1586 pic14_emitcode("push","acc");
1588 pic14_emitcode("push","%s",s);
1593 /* if bit variable */
1594 if (!aop->aopu.aop_dir) {
1595 pic14_emitcode("clr","a");
1596 pic14_emitcode("rlc","a");
1599 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1602 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1605 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1607 lbl = newiTempLabel(NULL);
1609 if (strcmp(s,"a")) {
1612 pic14_emitcode("clr","c");
1613 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1614 pic14_emitcode("cpl","c");
1615 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1616 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1623 if (strcmp(aop->aopu.aop_str[offset],s))
1624 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1629 if (!offset && (strcmp(s,"acc") == 0))
1632 if (strcmp(aop->aopu.aop_str[offset],s))
1633 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1637 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1638 "aopPut got unsupported aop->type");
1644 /*-----------------------------------------------------------------*/
1645 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1646 /*-----------------------------------------------------------------*/
1647 void mov2w (asmop *aop, int offset)
1653 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1655 if ( aop->type == AOP_PCODE ||
1656 aop->type == AOP_LIT ||
1657 aop->type == AOP_IMMD )
1658 emitpcode(POC_MOVLW,popGet(aop,offset));
1660 emitpcode(POC_MOVFW,popGet(aop,offset));
1664 /*-----------------------------------------------------------------*/
1665 /* reAdjustPreg - points a register back to where it should */
1666 /*-----------------------------------------------------------------*/
1667 static void reAdjustPreg (asmop *aop)
1671 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1673 if ((size = aop->size) <= 1)
1676 switch (aop->type) {
1680 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1684 if (aop->type == AOP_DPTR2)
1690 pic14_emitcode("lcall","__decdptr");
1693 if (aop->type == AOP_DPTR2)
1705 /*-----------------------------------------------------------------*/
1706 /* opIsGptr: returns non-zero if the passed operand is */
1707 /* a generic pointer type. */
1708 /*-----------------------------------------------------------------*/
1709 static int opIsGptr(operand *op)
1711 sym_link *type = operandType(op);
1713 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1714 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1722 /*-----------------------------------------------------------------*/
1723 /* pic14_getDataSize - get the operand data size */
1724 /*-----------------------------------------------------------------*/
1725 int pic14_getDataSize(operand *op)
1727 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1730 return AOP_SIZE(op);
1732 // tsd- in the pic port, the genptr size is 1, so this code here
1733 // fails. ( in the 8051 port, the size was 4).
1736 size = AOP_SIZE(op);
1737 if (size == GPTRSIZE)
1739 sym_link *type = operandType(op);
1740 if (IS_GENPTR(type))
1742 /* generic pointer; arithmetic operations
1743 * should ignore the high byte (pointer type).
1746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1753 /*-----------------------------------------------------------------*/
1754 /* pic14_outAcc - output Acc */
1755 /*-----------------------------------------------------------------*/
1756 void pic14_outAcc(operand *result)
1759 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1760 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1763 size = pic14_getDataSize(result);
1765 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1768 /* unsigned or positive */
1770 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1775 /*-----------------------------------------------------------------*/
1776 /* pic14_outBitC - output a bit C */
1777 /*-----------------------------------------------------------------*/
1778 void pic14_outBitC(operand *result)
1781 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1782 /* if the result is bit */
1783 if (AOP_TYPE(result) == AOP_CRY)
1784 aopPut(AOP(result),"c",0);
1786 pic14_emitcode("clr","a ; %d", __LINE__);
1787 pic14_emitcode("rlc","a");
1788 pic14_outAcc(result);
1792 /*-----------------------------------------------------------------*/
1793 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1794 /*-----------------------------------------------------------------*/
1795 void pic14_toBoolean(operand *oper)
1797 int size = AOP_SIZE(oper) - 1;
1800 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1802 if ( AOP_TYPE(oper) != AOP_ACC) {
1803 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1806 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1811 /*-----------------------------------------------------------------*/
1812 /* genNot - generate code for ! operation */
1813 /*-----------------------------------------------------------------*/
1814 static void genNot (iCode *ic)
1819 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1820 /* assign asmOps to operand & result */
1821 aopOp (IC_LEFT(ic),ic,FALSE);
1822 aopOp (IC_RESULT(ic),ic,TRUE);
1824 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1825 /* if in bit space then a special case */
1826 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1827 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1828 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1829 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1831 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1832 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1833 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1838 size = AOP_SIZE(IC_LEFT(ic));
1840 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1841 emitpcode(POC_ANDLW,popGetLit(1));
1842 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1845 pic14_toBoolean(IC_LEFT(ic));
1847 tlbl = newiTempLabel(NULL);
1848 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1849 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1850 pic14_outBitC(IC_RESULT(ic));
1853 /* release the aops */
1854 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1855 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1859 /*-----------------------------------------------------------------*/
1860 /* genCpl - generate code for complement */
1861 /*-----------------------------------------------------------------*/
1862 static void genCpl (iCode *ic)
1864 operand *left, *result;
1868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1869 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1870 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1872 /* if both are in bit space then
1874 if (AOP_TYPE(result) == AOP_CRY &&
1875 AOP_TYPE(left) == AOP_CRY ) {
1877 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1878 pic14_emitcode("cpl","c");
1879 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1883 size = AOP_SIZE(result);
1886 if(AOP_TYPE(left) == AOP_ACC)
1887 emitpcode(POC_XORLW, popGetLit(0xff));
1889 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1891 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1897 /* release the aops */
1898 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1899 freeAsmop(result,NULL,ic,TRUE);
1902 /*-----------------------------------------------------------------*/
1903 /* genUminusFloat - unary minus for floating points */
1904 /*-----------------------------------------------------------------*/
1905 static void genUminusFloat(operand *op,operand *result)
1907 int size ,offset =0 ;
1910 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1911 /* for this we just need to flip the
1912 first it then copy the rest in place */
1913 size = AOP_SIZE(op) - 1;
1914 l = aopGet(AOP(op),3,FALSE,FALSE);
1918 pic14_emitcode("cpl","acc.7");
1919 aopPut(AOP(result),"a",3);
1923 aopGet(AOP(op),offset,FALSE,FALSE),
1929 /*-----------------------------------------------------------------*/
1930 /* genUminus - unary minus code generation */
1931 /*-----------------------------------------------------------------*/
1932 static void genUminus (iCode *ic)
1935 sym_link *optype, *rtype;
1938 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1940 aopOp(IC_LEFT(ic),ic,FALSE);
1941 aopOp(IC_RESULT(ic),ic,TRUE);
1943 /* if both in bit space then special
1945 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1946 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1948 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1949 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1950 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1955 optype = operandType(IC_LEFT(ic));
1956 rtype = operandType(IC_RESULT(ic));
1958 /* if float then do float stuff */
1959 if (IS_FLOAT(optype)) {
1960 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1964 /* otherwise subtract from zero by taking the 2's complement */
1965 size = AOP_SIZE(IC_LEFT(ic));
1967 for(i=0; i<size; i++) {
1968 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1969 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1971 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1972 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1976 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1977 for(i=1; i<size; i++) {
1979 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1983 /* release the aops */
1984 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1985 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1988 /*-----------------------------------------------------------------*/
1989 /* saveRegisters - will look for a call and save the registers */
1990 /*-----------------------------------------------------------------*/
1991 static void saveRegisters(iCode *lic)
1998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2000 for (ic = lic ; ic ; ic = ic->next)
2001 if (ic->op == CALL || ic->op == PCALL)
2005 fprintf(stderr,"found parameter push with no function call\n");
2009 /* if the registers have been saved already then
2011 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2014 /* find the registers in use at this time
2015 and push them away to safety */
2016 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2020 if (options.useXstack) {
2021 if (bitVectBitValue(rsave,R0_IDX))
2022 pic14_emitcode("mov","b,r0");
2023 pic14_emitcode("mov","r0,%s",spname);
2024 for (i = 0 ; i < pic14_nRegs ; i++) {
2025 if (bitVectBitValue(rsave,i)) {
2027 pic14_emitcode("mov","a,b");
2029 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2030 pic14_emitcode("movx","@r0,a");
2031 pic14_emitcode("inc","r0");
2034 pic14_emitcode("mov","%s,r0",spname);
2035 if (bitVectBitValue(rsave,R0_IDX))
2036 pic14_emitcode("mov","r0,b");
2038 //for (i = 0 ; i < pic14_nRegs ; i++) {
2039 // if (bitVectBitValue(rsave,i))
2040 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2043 dtype = operandType(IC_LEFT(ic));
2044 if (currFunc && dtype &&
2045 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2046 IFFUNC_ISISR(currFunc->type) &&
2049 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2052 /*-----------------------------------------------------------------*/
2053 /* unsaveRegisters - pop the pushed registers */
2054 /*-----------------------------------------------------------------*/
2055 static void unsaveRegisters (iCode *ic)
2060 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2061 /* find the registers in use at this time
2062 and push them away to safety */
2063 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2066 if (options.useXstack) {
2067 pic14_emitcode("mov","r0,%s",spname);
2068 for (i = pic14_nRegs ; i >= 0 ; i--) {
2069 if (bitVectBitValue(rsave,i)) {
2070 pic14_emitcode("dec","r0");
2071 pic14_emitcode("movx","a,@r0");
2073 pic14_emitcode("mov","b,a");
2075 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2079 pic14_emitcode("mov","%s,r0",spname);
2080 if (bitVectBitValue(rsave,R0_IDX))
2081 pic14_emitcode("mov","r0,b");
2083 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2084 // if (bitVectBitValue(rsave,i))
2085 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2091 /*-----------------------------------------------------------------*/
2093 /*-----------------------------------------------------------------*/
2094 static void pushSide(operand * oper, int size)
2098 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2100 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2101 if (AOP_TYPE(oper) != AOP_REG &&
2102 AOP_TYPE(oper) != AOP_DIR &&
2104 pic14_emitcode("mov","a,%s",l);
2105 pic14_emitcode("push","acc");
2107 pic14_emitcode("push","%s",l);
2112 /*-----------------------------------------------------------------*/
2113 /* assignResultValue - */
2114 /*-----------------------------------------------------------------*/
2115 static void assignResultValue(operand * oper)
2117 int size = AOP_SIZE(oper);
2119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2121 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2124 if (GpsuedoStkPtr++)
2125 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2126 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2131 /*-----------------------------------------------------------------*/
2132 /* genIpush - genrate code for pushing this gets a little complex */
2133 /*-----------------------------------------------------------------*/
2134 static void genIpush (iCode *ic)
2137 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2139 int size, offset = 0 ;
2143 /* if this is not a parm push : ie. it is spill push
2144 and spill push is always done on the local stack */
2145 if (!ic->parmPush) {
2147 /* and the item is spilt then do nothing */
2148 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2151 aopOp(IC_LEFT(ic),ic,FALSE);
2152 size = AOP_SIZE(IC_LEFT(ic));
2153 /* push it on the stack */
2155 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2160 pic14_emitcode("push","%s",l);
2165 /* this is a paramter push: in this case we call
2166 the routine to find the call and save those
2167 registers that need to be saved */
2170 /* then do the push */
2171 aopOp(IC_LEFT(ic),ic,FALSE);
2174 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2175 size = AOP_SIZE(IC_LEFT(ic));
2178 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2179 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2180 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2182 pic14_emitcode("mov","a,%s",l);
2183 pic14_emitcode("push","acc");
2185 pic14_emitcode("push","%s",l);
2188 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2192 /*-----------------------------------------------------------------*/
2193 /* genIpop - recover the registers: can happen only for spilling */
2194 /*-----------------------------------------------------------------*/
2195 static void genIpop (iCode *ic)
2197 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2202 /* if the temp was not pushed then */
2203 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2206 aopOp(IC_LEFT(ic),ic,FALSE);
2207 size = AOP_SIZE(IC_LEFT(ic));
2210 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2213 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2217 /*-----------------------------------------------------------------*/
2218 /* unsaverbank - restores the resgister bank from stack */
2219 /*-----------------------------------------------------------------*/
2220 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2222 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2228 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2230 if (options.useXstack) {
2232 r = getFreePtr(ic,&aop,FALSE);
2235 pic14_emitcode("mov","%s,_spx",r->name);
2236 pic14_emitcode("movx","a,@%s",r->name);
2237 pic14_emitcode("mov","psw,a");
2238 pic14_emitcode("dec","%s",r->name);
2241 pic14_emitcode ("pop","psw");
2244 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2245 if (options.useXstack) {
2246 pic14_emitcode("movx","a,@%s",r->name);
2247 //pic14_emitcode("mov","(%s+%d),a",
2248 // regspic14[i].base,8*bank+regspic14[i].offset);
2249 pic14_emitcode("dec","%s",r->name);
2252 pic14_emitcode("pop",""); //"(%s+%d)",
2253 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2256 if (options.useXstack) {
2258 pic14_emitcode("mov","_spx,%s",r->name);
2259 freeAsmop(NULL,aop,ic,TRUE);
2265 /*-----------------------------------------------------------------*/
2266 /* saverbank - saves an entire register bank on the stack */
2267 /*-----------------------------------------------------------------*/
2268 static void saverbank (int bank, iCode *ic, bool pushPsw)
2270 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2277 if (options.useXstack) {
2280 r = getFreePtr(ic,&aop,FALSE);
2281 pic14_emitcode("mov","%s,_spx",r->name);
2285 for (i = 0 ; i < pic14_nRegs ;i++) {
2286 if (options.useXstack) {
2287 pic14_emitcode("inc","%s",r->name);
2288 //pic14_emitcode("mov","a,(%s+%d)",
2289 // regspic14[i].base,8*bank+regspic14[i].offset);
2290 pic14_emitcode("movx","@%s,a",r->name);
2292 pic14_emitcode("push","");// "(%s+%d)",
2293 //regspic14[i].base,8*bank+regspic14[i].offset);
2297 if (options.useXstack) {
2298 pic14_emitcode("mov","a,psw");
2299 pic14_emitcode("movx","@%s,a",r->name);
2300 pic14_emitcode("inc","%s",r->name);
2301 pic14_emitcode("mov","_spx,%s",r->name);
2302 freeAsmop (NULL,aop,ic,TRUE);
2305 pic14_emitcode("push","psw");
2307 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2313 /*-----------------------------------------------------------------*/
2314 /* genCall - generates a call statement */
2315 /*-----------------------------------------------------------------*/
2316 static void genCall (iCode *ic)
2320 unsigned char *name;
2323 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2325 /* if caller saves & we have not saved then */
2329 /* if we are calling a function that is not using
2330 the same register bank then we need to save the
2331 destination registers on the stack */
2332 dtype = operandType(IC_LEFT(ic));
2333 if (currFunc && dtype &&
2334 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2335 IFFUNC_ISISR(currFunc->type) &&
2338 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2340 /* if send set is not empty the assign */
2343 /* For the Pic port, there is no data stack.
2344 * So parameters passed to functions are stored
2345 * in registers. (The pCode optimizer will get
2346 * rid of most of these :).
2348 int psuedoStkPtr=-1;
2349 int firstTimeThruLoop = 1;
2351 _G.sendSet = reverseSet(_G.sendSet);
2353 /* First figure how many parameters are getting passed */
2354 for (sic = setFirstItem(_G.sendSet) ; sic ;
2355 sic = setNextItem(_G.sendSet)) {
2357 aopOp(IC_LEFT(sic),sic,FALSE);
2358 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2359 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2362 for (sic = setFirstItem(_G.sendSet) ; sic ;
2363 sic = setNextItem(_G.sendSet)) {
2364 int size, offset = 0;
2366 aopOp(IC_LEFT(sic),sic,FALSE);
2367 size = AOP_SIZE(IC_LEFT(sic));
2370 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2371 AopType(AOP_TYPE(IC_LEFT(sic))));
2373 if(!firstTimeThruLoop) {
2374 /* If this is not the first time we've been through the loop
2375 * then we need to save the parameter in a temporary
2376 * register. The last byte of the last parameter is
2378 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2381 firstTimeThruLoop=0;
2383 mov2w (AOP(IC_LEFT(sic)), offset);
2386 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2391 sym = OP_SYMBOL(IC_LEFT(ic));
2392 name = sym->rname[0] ? sym->rname : sym->name;
2393 isExtern = IS_EXTERN(sym->etype);
2395 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2397 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2399 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
2402 /* if we need assign a result value */
2403 if ((IS_ITEMP(IC_RESULT(ic)) &&
2404 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2405 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2406 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2409 aopOp(IC_RESULT(ic),ic,FALSE);
2412 assignResultValue(IC_RESULT(ic));
2414 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2415 AopType(AOP_TYPE(IC_RESULT(ic))));
2417 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2420 /* adjust the stack for parameters if
2422 if (ic->parmBytes) {
2424 if (ic->parmBytes > 3) {
2425 pic14_emitcode("mov","a,%s",spname);
2426 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2427 pic14_emitcode("mov","%s,a",spname);
2429 for ( i = 0 ; i < ic->parmBytes ;i++)
2430 pic14_emitcode("dec","%s",spname);
2434 /* if register bank was saved then pop them */
2436 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2438 /* if we hade saved some registers then unsave them */
2439 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2440 unsaveRegisters (ic);
2445 /*-----------------------------------------------------------------*/
2446 /* genPcall - generates a call by pointer statement */
2447 /*-----------------------------------------------------------------*/
2448 static void genPcall (iCode *ic)
2451 symbol *albl = newiTempLabel(NULL);
2452 symbol *blbl = newiTempLabel(NULL);
2457 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2458 /* if caller saves & we have not saved then */
2462 /* if we are calling a function that is not using
2463 the same register bank then we need to save the
2464 destination registers on the stack */
2465 dtype = operandType(IC_LEFT(ic));
2466 if (currFunc && dtype &&
2467 IFFUNC_ISISR(currFunc->type) &&
2468 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2469 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2472 aopOp(left,ic,FALSE);
2473 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2475 pushSide(IC_LEFT(ic), FPTRSIZE);
2477 /* if send set is not empty, assign parameters */
2480 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2481 /* no way to pass args - W always gets used to make the call */
2483 /* first idea - factor out a common helper function and call it.
2484 But don't know how to get it generated only once in its own block
2486 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2489 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2490 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2491 buffer = Safe_calloc(1,strlen(rname)+16);
2492 sprintf(buffer, "%s_goto_helper", rname);
2493 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2497 emitpcode(POC_CALL,popGetLabel(albl->key));
2498 pcop = popGetLabel(blbl->key);
2499 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2500 emitpcode(POC_GOTO,pcop);
2501 emitpLabel(albl->key);
2503 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2505 emitpcode(poc,popGet(AOP(left),1));
2506 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2507 emitpcode(poc,popGet(AOP(left),0));
2508 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2510 emitpLabel(blbl->key);
2512 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2514 /* if we need to assign a result value */
2515 if ((IS_ITEMP(IC_RESULT(ic)) &&
2516 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2517 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2518 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2521 aopOp(IC_RESULT(ic),ic,FALSE);
2524 assignResultValue(IC_RESULT(ic));
2526 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2529 /* if register bank was saved then unsave them */
2530 if (currFunc && dtype &&
2531 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2532 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2534 /* if we hade saved some registers then
2537 unsaveRegisters (ic);
2541 /*-----------------------------------------------------------------*/
2542 /* resultRemat - result is rematerializable */
2543 /*-----------------------------------------------------------------*/
2544 static int resultRemat (iCode *ic)
2546 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2547 if (SKIP_IC(ic) || ic->op == IFX)
2550 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2551 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2552 if (sym->remat && !POINTER_SET(ic))
2559 #if defined(__BORLANDC__) || defined(_MSC_VER)
2560 #define STRCASECMP stricmp
2562 #define STRCASECMP strcasecmp
2566 /*-----------------------------------------------------------------*/
2567 /* inExcludeList - return 1 if the string is in exclude Reg list */
2568 /*-----------------------------------------------------------------*/
2569 static bool inExcludeList(char *s)
2571 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2574 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2575 if (options.excludeRegs[i] &&
2576 STRCASECMP(options.excludeRegs[i],"none") == 0)
2579 for ( i = 0 ; options.excludeRegs[i]; i++) {
2580 if (options.excludeRegs[i] &&
2581 STRCASECMP(s,options.excludeRegs[i]) == 0)
2588 /*-----------------------------------------------------------------*/
2589 /* genFunction - generated code for function entry */
2590 /*-----------------------------------------------------------------*/
2591 static void genFunction (iCode *ic)
2596 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2598 labelOffset += (max_key+4);
2602 /* create the function header */
2603 pic14_emitcode(";","-----------------------------------------");
2604 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2605 pic14_emitcode(";","-----------------------------------------");
2607 pic14_emitcode("","%s:",sym->rname);
2608 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2610 ftype = operandType(IC_LEFT(ic));
2612 /* if critical function then turn interrupts off */
2613 if (IFFUNC_ISCRITICAL(ftype))
2614 pic14_emitcode("clr","ea");
2616 /* here we need to generate the equates for the
2617 register bank if required */
2619 if (FUNC_REGBANK(ftype) != rbank) {
2622 rbank = FUNC_REGBANK(ftype);
2623 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2624 if (strcmp(regspic14[i].base,"0") == 0)
2625 pic14_emitcode("","%s = 0x%02x",
2627 8*rbank+regspic14[i].offset);
2629 pic14_emitcode ("","%s = %s + 0x%02x",
2632 8*rbank+regspic14[i].offset);
2637 /* if this is an interrupt service routine */
2638 if (IFFUNC_ISISR(sym->type)) {
2639 /* already done in pic14createInterruptVect() - delete me
2640 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2641 emitpcodeNULLop(POC_NOP);
2642 emitpcodeNULLop(POC_NOP);
2643 emitpcodeNULLop(POC_NOP);
2645 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2646 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2647 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2648 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2649 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2650 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2651 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2653 pBlockConvert2ISR(pb);
2655 if (!inExcludeList("acc"))
2656 pic14_emitcode ("push","acc");
2657 if (!inExcludeList("b"))
2658 pic14_emitcode ("push","b");
2659 if (!inExcludeList("dpl"))
2660 pic14_emitcode ("push","dpl");
2661 if (!inExcludeList("dph"))
2662 pic14_emitcode ("push","dph");
2663 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2665 pic14_emitcode ("push", "dpx");
2666 /* Make sure we're using standard DPTR */
2667 pic14_emitcode ("push", "dps");
2668 pic14_emitcode ("mov", "dps, #0x00");
2669 if (options.stack10bit)
2671 /* This ISR could conceivably use DPTR2. Better save it. */
2672 pic14_emitcode ("push", "dpl1");
2673 pic14_emitcode ("push", "dph1");
2674 pic14_emitcode ("push", "dpx1");
2677 /* if this isr has no bank i.e. is going to
2678 run with bank 0 , then we need to save more
2680 if (!FUNC_REGBANK(sym->type)) {
2682 /* if this function does not call any other
2683 function then we can be economical and
2684 save only those registers that are used */
2685 if (! IFFUNC_HASFCALL(sym->type)) {
2688 /* if any registers used */
2689 if (sym->regsUsed) {
2690 /* save the registers used */
2691 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2692 if (bitVectBitValue(sym->regsUsed,i) ||
2693 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2694 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2699 /* this function has a function call cannot
2700 determines register usage so we will have the
2702 saverbank(0,ic,FALSE);
2707 /* if callee-save to be used for this function
2708 then save the registers being used in this function */
2709 if (IFFUNC_CALLEESAVES(sym->type)) {
2712 /* if any registers used */
2713 if (sym->regsUsed) {
2714 /* save the registers used */
2715 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2716 if (bitVectBitValue(sym->regsUsed,i) ||
2717 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2718 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2726 /* set the register bank to the desired value */
2727 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2728 pic14_emitcode("push","psw");
2729 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2732 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2734 if (options.useXstack) {
2735 pic14_emitcode("mov","r0,%s",spname);
2736 pic14_emitcode("mov","a,_bp");
2737 pic14_emitcode("movx","@r0,a");
2738 pic14_emitcode("inc","%s",spname);
2742 /* set up the stack */
2743 pic14_emitcode ("push","_bp"); /* save the callers stack */
2745 pic14_emitcode ("mov","_bp,%s",spname);
2748 /* adjust the stack for the function */
2753 werror(W_STACK_OVERFLOW,sym->name);
2755 if (i > 3 && sym->recvSize < 4) {
2757 pic14_emitcode ("mov","a,sp");
2758 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2759 pic14_emitcode ("mov","sp,a");
2764 pic14_emitcode("inc","sp");
2769 pic14_emitcode ("mov","a,_spx");
2770 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2771 pic14_emitcode ("mov","_spx,a");
2776 /*-----------------------------------------------------------------*/
2777 /* genEndFunction - generates epilogue for functions */
2778 /*-----------------------------------------------------------------*/
2779 static void genEndFunction (iCode *ic)
2781 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2785 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2787 pic14_emitcode ("mov","%s,_bp",spname);
2790 /* if use external stack but some variables were
2791 added to the local stack then decrement the
2793 if (options.useXstack && sym->stack) {
2794 pic14_emitcode("mov","a,sp");
2795 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2796 pic14_emitcode("mov","sp,a");
2800 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2801 if (options.useXstack) {
2802 pic14_emitcode("mov","r0,%s",spname);
2803 pic14_emitcode("movx","a,@r0");
2804 pic14_emitcode("mov","_bp,a");
2805 pic14_emitcode("dec","%s",spname);
2809 pic14_emitcode ("pop","_bp");
2813 /* restore the register bank */
2814 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2815 pic14_emitcode ("pop","psw");
2817 if (IFFUNC_ISISR(sym->type)) {
2819 /* now we need to restore the registers */
2820 /* if this isr has no bank i.e. is going to
2821 run with bank 0 , then we need to save more
2823 if (!FUNC_REGBANK(sym->type)) {
2825 /* if this function does not call any other
2826 function then we can be economical and
2827 save only those registers that are used */
2828 if (! IFFUNC_HASFCALL(sym->type)) {
2831 /* if any registers used */
2832 if (sym->regsUsed) {
2833 /* save the registers used */
2834 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2835 if (bitVectBitValue(sym->regsUsed,i) ||
2836 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2837 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2842 /* this function has a function call cannot
2843 determines register usage so we will have the
2845 unsaverbank(0,ic,FALSE);
2849 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2851 if (options.stack10bit)
2853 pic14_emitcode ("pop", "dpx1");
2854 pic14_emitcode ("pop", "dph1");
2855 pic14_emitcode ("pop", "dpl1");
2857 pic14_emitcode ("pop", "dps");
2858 pic14_emitcode ("pop", "dpx");
2860 if (!inExcludeList("dph"))
2861 pic14_emitcode ("pop","dph");
2862 if (!inExcludeList("dpl"))
2863 pic14_emitcode ("pop","dpl");
2864 if (!inExcludeList("b"))
2865 pic14_emitcode ("pop","b");
2866 if (!inExcludeList("acc"))
2867 pic14_emitcode ("pop","acc");
2869 if (IFFUNC_ISCRITICAL(sym->type))
2870 pic14_emitcode("setb","ea");
2873 /* if debug then send end of function */
2874 /* if (options.debug && currFunc) { */
2876 debugFile->writeEndFunction (currFunc, ic, 1);
2879 pic14_emitcode ("reti","");
2880 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2881 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2882 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2883 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2884 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2885 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2886 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2887 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2888 emitpcodeNULLop(POC_RETFIE);
2891 if (IFFUNC_ISCRITICAL(sym->type))
2892 pic14_emitcode("setb","ea");
2894 if (IFFUNC_CALLEESAVES(sym->type)) {
2897 /* if any registers used */
2898 if (sym->regsUsed) {
2899 /* save the registers used */
2900 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2901 if (bitVectBitValue(sym->regsUsed,i) ||
2902 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2903 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2909 /* if debug then send end of function */
2911 debugFile->writeEndFunction (currFunc, ic, 1);
2914 pic14_emitcode ("return","");
2915 emitpcodeNULLop(POC_RETURN);
2917 /* Mark the end of a function */
2918 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2923 /*-----------------------------------------------------------------*/
2924 /* genRet - generate code for return statement */
2925 /*-----------------------------------------------------------------*/
2926 static void genRet (iCode *ic)
2928 int size,offset = 0 , pushed = 0;
2930 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2931 /* if we have no return value then
2932 just generate the "ret" */
2936 /* we have something to return then
2937 move the return value into place */
2938 aopOp(IC_LEFT(ic),ic,FALSE);
2939 size = AOP_SIZE(IC_LEFT(ic));
2943 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2945 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2947 pic14_emitcode("push","%s",l);
2950 l = aopGet(AOP(IC_LEFT(ic)),offset,
2952 if (strcmp(fReturn[offset],l)) {
2953 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2954 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2955 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2956 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2957 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2959 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2962 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2972 if (strcmp(fReturn[pushed],"a"))
2973 pic14_emitcode("pop",fReturn[pushed]);
2975 pic14_emitcode("pop","acc");
2978 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2981 /* generate a jump to the return label
2982 if the next is not the return statement */
2983 if (!(ic->next && ic->next->op == LABEL &&
2984 IC_LABEL(ic->next) == returnLabel)) {
2986 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
2987 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
2992 /*-----------------------------------------------------------------*/
2993 /* genLabel - generates a label */
2994 /*-----------------------------------------------------------------*/
2995 static void genLabel (iCode *ic)
2997 /* special case never generate */
2998 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2999 if (IC_LABEL(ic) == entryLabel)
3002 emitpLabel(IC_LABEL(ic)->key);
3003 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3006 /*-----------------------------------------------------------------*/
3007 /* genGoto - generates a goto */
3008 /*-----------------------------------------------------------------*/
3010 static void genGoto (iCode *ic)
3012 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3013 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3017 /*-----------------------------------------------------------------*/
3018 /* genMultbits :- multiplication of bits */
3019 /*-----------------------------------------------------------------*/
3020 static void genMultbits (operand *left,
3024 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3026 if(!pic14_sameRegs(AOP(result),AOP(right)))
3027 emitpcode(POC_BSF, popGet(AOP(result),0));
3029 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3030 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3031 emitpcode(POC_BCF, popGet(AOP(result),0));
3036 /*-----------------------------------------------------------------*/
3037 /* genMultOneByte : 8 bit multiplication & division */
3038 /*-----------------------------------------------------------------*/
3039 static void genMultOneByte (operand *left,
3043 sym_link *opetype = operandType(result);
3048 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3049 DEBUGpic14_AopType(__LINE__,left,right,result);
3050 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3052 /* (if two literals, the value is computed before) */
3053 /* if one literal, literal on the right */
3054 if (AOP_TYPE(left) == AOP_LIT){
3060 size = AOP_SIZE(result);
3063 if (AOP_TYPE(right) == AOP_LIT){
3064 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3065 aopGet(AOP(right),0,FALSE,FALSE),
3066 aopGet(AOP(left),0,FALSE,FALSE),
3067 aopGet(AOP(result),0,FALSE,FALSE));
3068 pic14_emitcode("call","genMultLit");
3070 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3071 aopGet(AOP(right),0,FALSE,FALSE),
3072 aopGet(AOP(left),0,FALSE,FALSE),
3073 aopGet(AOP(result),0,FALSE,FALSE));
3074 pic14_emitcode("call","genMult8X8_8");
3077 genMult8X8_8 (left, right,result);
3080 /* signed or unsigned */
3081 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3082 //l = aopGet(AOP(left),0,FALSE,FALSE);
3084 //pic14_emitcode("mul","ab");
3085 /* if result size = 1, mul signed = mul unsigned */
3086 //aopPut(AOP(result),"a",0);
3088 } else { // (size > 1)
3090 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3091 aopGet(AOP(right),0,FALSE,FALSE),
3092 aopGet(AOP(left),0,FALSE,FALSE),
3093 aopGet(AOP(result),0,FALSE,FALSE));
3095 if (SPEC_USIGN(opetype)){
3096 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3097 genUMult8X8_16 (left, right, result, NULL);
3100 /* for filling the MSBs */
3101 emitpcode(POC_CLRF, popGet(AOP(result),2));
3102 emitpcode(POC_CLRF, popGet(AOP(result),3));
3106 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3108 pic14_emitcode("mov","a,b");
3110 /* adjust the MSB if left or right neg */
3112 /* if one literal */
3113 if (AOP_TYPE(right) == AOP_LIT){
3114 pic14_emitcode("multiply ","right is a lit");
3115 /* AND literal negative */
3116 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3117 /* adjust MSB (c==0 after mul) */
3118 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3122 genSMult8X8_16 (left, right, result, NULL);
3126 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3128 pic14_emitcode("rlc","a");
3129 pic14_emitcode("subb","a,acc");
3137 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3138 //aopPut(AOP(result),"a",offset++);
3142 /*-----------------------------------------------------------------*/
3143 /* genMult - generates code for multiplication */
3144 /*-----------------------------------------------------------------*/
3145 static void genMult (iCode *ic)
3147 operand *left = IC_LEFT(ic);
3148 operand *right = IC_RIGHT(ic);
3149 operand *result= IC_RESULT(ic);
3151 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3152 /* assign the amsops */
3153 aopOp (left,ic,FALSE);
3154 aopOp (right,ic,FALSE);
3155 aopOp (result,ic,TRUE);
3157 DEBUGpic14_AopType(__LINE__,left,right,result);
3159 /* special cases first */
3161 if (AOP_TYPE(left) == AOP_CRY &&
3162 AOP_TYPE(right)== AOP_CRY) {
3163 genMultbits(left,right,result);
3167 /* if both are of size == 1 */
3168 if (AOP_SIZE(left) == 1 &&
3169 AOP_SIZE(right) == 1 ) {
3170 genMultOneByte(left,right,result);
3174 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3176 /* should have been converted to function call */
3180 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3181 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3182 freeAsmop(result,NULL,ic,TRUE);
3185 /*-----------------------------------------------------------------*/
3186 /* genDivbits :- division of bits */
3187 /*-----------------------------------------------------------------*/
3188 static void genDivbits (operand *left,
3195 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3196 /* the result must be bit */
3197 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3198 l = aopGet(AOP(left),0,FALSE,FALSE);
3202 pic14_emitcode("div","ab");
3203 pic14_emitcode("rrc","a");
3204 aopPut(AOP(result),"c",0);
3207 /*-----------------------------------------------------------------*/
3208 /* genDivOneByte : 8 bit division */
3209 /*-----------------------------------------------------------------*/
3210 static void genDivOneByte (operand *left,
3214 sym_link *opetype = operandType(result);
3219 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3220 size = AOP_SIZE(result) - 1;
3222 /* signed or unsigned */
3223 if (SPEC_USIGN(opetype)) {
3224 /* unsigned is easy */
3225 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3226 l = aopGet(AOP(left),0,FALSE,FALSE);
3228 pic14_emitcode("div","ab");
3229 aopPut(AOP(result),"a",0);
3231 aopPut(AOP(result),zero,offset++);
3235 /* signed is a little bit more difficult */
3237 /* save the signs of the operands */
3238 l = aopGet(AOP(left),0,FALSE,FALSE);
3240 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3241 pic14_emitcode("push","acc"); /* save it on the stack */
3243 /* now sign adjust for both left & right */
3244 l = aopGet(AOP(right),0,FALSE,FALSE);
3246 lbl = newiTempLabel(NULL);
3247 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3248 pic14_emitcode("cpl","a");
3249 pic14_emitcode("inc","a");
3250 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3251 pic14_emitcode("mov","b,a");
3253 /* sign adjust left side */
3254 l = aopGet(AOP(left),0,FALSE,FALSE);
3257 lbl = newiTempLabel(NULL);
3258 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3259 pic14_emitcode("cpl","a");
3260 pic14_emitcode("inc","a");
3261 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3263 /* now the division */
3264 pic14_emitcode("div","ab");
3265 /* we are interested in the lower order
3267 pic14_emitcode("mov","b,a");
3268 lbl = newiTempLabel(NULL);
3269 pic14_emitcode("pop","acc");
3270 /* if there was an over flow we don't
3271 adjust the sign of the result */
3272 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3273 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3275 pic14_emitcode("clr","a");
3276 pic14_emitcode("subb","a,b");
3277 pic14_emitcode("mov","b,a");
3278 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3280 /* now we are done */
3281 aopPut(AOP(result),"b",0);
3283 pic14_emitcode("mov","c,b.7");
3284 pic14_emitcode("subb","a,acc");
3287 aopPut(AOP(result),"a",offset++);
3291 /*-----------------------------------------------------------------*/
3292 /* genDiv - generates code for division */
3293 /*-----------------------------------------------------------------*/
3294 static void genDiv (iCode *ic)
3296 operand *left = IC_LEFT(ic);
3297 operand *right = IC_RIGHT(ic);
3298 operand *result= IC_RESULT(ic);
3300 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3301 /* assign the amsops */
3302 aopOp (left,ic,FALSE);
3303 aopOp (right,ic,FALSE);
3304 aopOp (result,ic,TRUE);
3306 /* special cases first */
3308 if (AOP_TYPE(left) == AOP_CRY &&
3309 AOP_TYPE(right)== AOP_CRY) {
3310 genDivbits(left,right,result);
3314 /* if both are of size == 1 */
3315 if (AOP_SIZE(left) == 1 &&
3316 AOP_SIZE(right) == 1 ) {
3317 genDivOneByte(left,right,result);
3321 /* should have been converted to function call */
3324 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3325 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3326 freeAsmop(result,NULL,ic,TRUE);
3329 /*-----------------------------------------------------------------*/
3330 /* genModbits :- modulus of bits */
3331 /*-----------------------------------------------------------------*/
3332 static void genModbits (operand *left,
3339 /* the result must be bit */
3340 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3341 l = aopGet(AOP(left),0,FALSE,FALSE);
3345 pic14_emitcode("div","ab");
3346 pic14_emitcode("mov","a,b");
3347 pic14_emitcode("rrc","a");
3348 aopPut(AOP(result),"c",0);
3351 /*-----------------------------------------------------------------*/
3352 /* genModOneByte : 8 bit modulus */
3353 /*-----------------------------------------------------------------*/
3354 static void genModOneByte (operand *left,
3358 sym_link *opetype = operandType(result);
3362 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3363 /* signed or unsigned */
3364 if (SPEC_USIGN(opetype)) {
3365 /* unsigned is easy */
3366 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3367 l = aopGet(AOP(left),0,FALSE,FALSE);
3369 pic14_emitcode("div","ab");
3370 aopPut(AOP(result),"b",0);
3374 /* signed is a little bit more difficult */
3376 /* save the signs of the operands */
3377 l = aopGet(AOP(left),0,FALSE,FALSE);
3380 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3381 pic14_emitcode("push","acc"); /* save it on the stack */
3383 /* now sign adjust for both left & right */
3384 l = aopGet(AOP(right),0,FALSE,FALSE);
3387 lbl = newiTempLabel(NULL);
3388 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3389 pic14_emitcode("cpl","a");
3390 pic14_emitcode("inc","a");
3391 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3392 pic14_emitcode("mov","b,a");
3394 /* sign adjust left side */
3395 l = aopGet(AOP(left),0,FALSE,FALSE);
3398 lbl = newiTempLabel(NULL);
3399 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3400 pic14_emitcode("cpl","a");
3401 pic14_emitcode("inc","a");
3402 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3404 /* now the multiplication */
3405 pic14_emitcode("div","ab");
3406 /* we are interested in the lower order
3408 lbl = newiTempLabel(NULL);
3409 pic14_emitcode("pop","acc");
3410 /* if there was an over flow we don't
3411 adjust the sign of the result */
3412 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3413 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3415 pic14_emitcode("clr","a");
3416 pic14_emitcode("subb","a,b");
3417 pic14_emitcode("mov","b,a");
3418 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3420 /* now we are done */
3421 aopPut(AOP(result),"b",0);
3425 /*-----------------------------------------------------------------*/
3426 /* genMod - generates code for division */
3427 /*-----------------------------------------------------------------*/
3428 static void genMod (iCode *ic)
3430 operand *left = IC_LEFT(ic);
3431 operand *right = IC_RIGHT(ic);
3432 operand *result= IC_RESULT(ic);
3434 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3435 /* assign the amsops */
3436 aopOp (left,ic,FALSE);
3437 aopOp (right,ic,FALSE);
3438 aopOp (result,ic,TRUE);
3440 /* special cases first */
3442 if (AOP_TYPE(left) == AOP_CRY &&
3443 AOP_TYPE(right)== AOP_CRY) {
3444 genModbits(left,right,result);
3448 /* if both are of size == 1 */
3449 if (AOP_SIZE(left) == 1 &&
3450 AOP_SIZE(right) == 1 ) {
3451 genModOneByte(left,right,result);
3455 /* should have been converted to function call */
3459 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3460 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3461 freeAsmop(result,NULL,ic,TRUE);
3464 /*-----------------------------------------------------------------*/
3465 /* genIfxJump :- will create a jump depending on the ifx */
3466 /*-----------------------------------------------------------------*/
3468 note: May need to add parameter to indicate when a variable is in bit space.
3470 static void genIfxJump (iCode *ic, char *jval)
3473 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3474 /* if true label then we jump if condition
3476 if ( IC_TRUE(ic) ) {
3478 if(strcmp(jval,"a") == 0)
3480 else if (strcmp(jval,"c") == 0)
3483 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3484 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3487 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3488 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3492 /* false label is present */
3493 if(strcmp(jval,"a") == 0)
3495 else if (strcmp(jval,"c") == 0)
3498 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3499 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3502 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3503 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3508 /* mark the icode as generated */
3512 /*-----------------------------------------------------------------*/
3514 /*-----------------------------------------------------------------*/
3515 static void genSkip(iCode *ifx,int status_bit)
3520 if ( IC_TRUE(ifx) ) {
3521 switch(status_bit) {
3536 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3537 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3541 switch(status_bit) {
3555 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3556 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3562 /*-----------------------------------------------------------------*/
3564 /*-----------------------------------------------------------------*/
3565 static void genSkipc(resolvedIfx *rifx)
3575 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3576 rifx->generated = 1;
3579 /*-----------------------------------------------------------------*/
3581 /*-----------------------------------------------------------------*/
3582 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3587 if( (rifx->condition ^ invert_condition) & 1)
3592 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3593 rifx->generated = 1;
3596 /*-----------------------------------------------------------------*/
3598 /*-----------------------------------------------------------------*/
3599 static void genSkipz(iCode *ifx, int condition)
3610 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3612 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3615 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3617 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3620 /*-----------------------------------------------------------------*/
3622 /*-----------------------------------------------------------------*/
3623 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3629 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3631 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3634 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3635 rifx->generated = 1;
3639 /*-----------------------------------------------------------------*/
3640 /* genChkZeroes :- greater or less than comparison */
3641 /* For each byte in a literal that is zero, inclusive or the */
3642 /* the corresponding byte in the operand with W */
3643 /* returns true if any of the bytes are zero */
3644 /*-----------------------------------------------------------------*/
3645 static int genChkZeroes(operand *op, int lit, int size)
3652 i = (lit >> (size*8)) & 0xff;
3656 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3658 emitpcode(POC_IORFW, popGet(AOP(op),size));
3667 /*-----------------------------------------------------------------*/
3668 /* genCmp :- greater or less than comparison */
3669 /*-----------------------------------------------------------------*/
3670 static void genCmp (operand *left,operand *right,
3671 operand *result, iCode *ifx, int sign)
3673 int size; //, offset = 0 ;
3674 unsigned long lit = 0L,i = 0;
3675 resolvedIfx rFalseIfx;
3676 // resolvedIfx rTrueIfx;
3678 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3681 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3682 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3686 resolveIfx(&rFalseIfx,ifx);
3687 truelbl = newiTempLabel(NULL);
3688 size = max(AOP_SIZE(left),AOP_SIZE(right));
3690 DEBUGpic14_AopType(__LINE__,left,right,result);
3694 /* if literal is on the right then swap with left */
3695 if ((AOP_TYPE(right) == AOP_LIT)) {
3696 operand *tmp = right ;
3697 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3698 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3701 lit = (lit - 1) & mask;
3704 rFalseIfx.condition ^= 1;
3707 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3708 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3712 //if(IC_TRUE(ifx) == NULL)
3713 /* if left & right are bit variables */
3714 if (AOP_TYPE(left) == AOP_CRY &&
3715 AOP_TYPE(right) == AOP_CRY ) {
3716 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3717 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3719 /* subtract right from left if at the
3720 end the carry flag is set then we know that
3721 left is greater than right */
3723 symbol *lbl = newiTempLabel(NULL);
3726 if(AOP_TYPE(right) == AOP_LIT) {
3728 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3730 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3737 genSkipCond(&rFalseIfx,left,size-1,7);
3739 /* no need to compare to 0...*/
3740 /* NOTE: this is a de-generate compare that most certainly
3741 * creates some dead code. */
3742 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3744 if(ifx) ifx->generated = 1;
3751 //i = (lit >> (size*8)) & 0xff;
3752 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3754 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3756 i = ((0-lit) & 0xff);
3759 /* lit is 0x7f, all signed chars are less than
3760 * this except for 0x7f itself */
3761 emitpcode(POC_XORLW, popGetLit(0x7f));
3762 genSkipz2(&rFalseIfx,0);
3764 emitpcode(POC_ADDLW, popGetLit(0x80));
3765 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3766 genSkipc(&rFalseIfx);
3771 genSkipz2(&rFalseIfx,1);
3773 emitpcode(POC_ADDLW, popGetLit(i));
3774 genSkipc(&rFalseIfx);
3778 if(ifx) ifx->generated = 1;
3782 /* chars are out of the way. now do ints and longs */
3785 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3792 genSkipCond(&rFalseIfx,left,size,7);
3793 if(ifx) ifx->generated = 1;
3798 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3800 //rFalseIfx.condition ^= 1;
3801 //genSkipCond(&rFalseIfx,left,size,7);
3802 //rFalseIfx.condition ^= 1;
3804 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3805 if(rFalseIfx.condition)
3806 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3808 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3810 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3811 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3812 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3815 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3817 if(rFalseIfx.condition) {
3819 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3825 genSkipc(&rFalseIfx);
3826 emitpLabel(truelbl->key);
3827 if(ifx) ifx->generated = 1;
3834 if( (lit & 0xff) == 0) {
3835 /* lower byte is zero */
3836 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3837 i = ((lit >> 8) & 0xff) ^0x80;
3838 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3839 emitpcode(POC_ADDLW, popGetLit( 0x80));
3840 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3841 genSkipc(&rFalseIfx);
3844 if(ifx) ifx->generated = 1;
3849 /* Special cases for signed longs */
3850 if( (lit & 0xffffff) == 0) {
3851 /* lower byte is zero */
3852 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3853 i = ((lit >> 8*3) & 0xff) ^0x80;
3854 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3855 emitpcode(POC_ADDLW, popGetLit( 0x80));
3856 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3857 genSkipc(&rFalseIfx);
3860 if(ifx) ifx->generated = 1;
3868 if(lit & (0x80 << (size*8))) {
3869 /* lit is negative */
3870 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3872 //genSkipCond(&rFalseIfx,left,size,7);
3874 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3876 if(rFalseIfx.condition)
3877 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3879 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3883 /* lit is positive */
3884 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3885 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3886 if(rFalseIfx.condition)
3887 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3889 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3893 /* There are no more special cases, so perform a general compare */
3895 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3896 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3900 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3902 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3904 //rFalseIfx.condition ^= 1;
3905 genSkipc(&rFalseIfx);
3907 emitpLabel(truelbl->key);
3909 if(ifx) ifx->generated = 1;
3916 /* sign is out of the way. So now do an unsigned compare */
3917 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3920 /* General case - compare to an unsigned literal on the right.*/
3922 i = (lit >> (size*8)) & 0xff;
3923 emitpcode(POC_MOVLW, popGetLit(i));
3924 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3926 i = (lit >> (size*8)) & 0xff;
3929 emitpcode(POC_MOVLW, popGetLit(i));
3931 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3933 /* this byte of the lit is zero,
3934 *if it's not the last then OR in the variable */
3936 emitpcode(POC_IORFW, popGet(AOP(left),size));
3941 emitpLabel(lbl->key);
3942 //if(emitFinalCheck)
3943 genSkipc(&rFalseIfx);
3945 emitpLabel(truelbl->key);
3947 if(ifx) ifx->generated = 1;
3954 if(AOP_TYPE(left) == AOP_LIT) {
3955 //symbol *lbl = newiTempLabel(NULL);
3957 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3960 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3963 if((lit == 0) && (sign == 0)){
3966 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3968 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3970 genSkipz2(&rFalseIfx,0);
3971 if(ifx) ifx->generated = 1;
3978 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3979 /* degenerate compare can never be true */
3980 if(rFalseIfx.condition == 0)
3981 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3983 if(ifx) ifx->generated = 1;
3988 /* signed comparisons to a literal byte */
3990 int lp1 = (lit+1) & 0xff;
3992 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
3995 rFalseIfx.condition ^= 1;
3996 genSkipCond(&rFalseIfx,right,0,7);
3999 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4000 emitpcode(POC_XORLW, popGetLit(0x7f));
4001 genSkipz2(&rFalseIfx,1);
4004 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4005 emitpcode(POC_ADDLW, popGetLit(0x80));
4006 emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
4007 rFalseIfx.condition ^= 1;
4008 genSkipc(&rFalseIfx);
4011 if(ifx) ifx->generated = 1;
4013 /* unsigned comparisons to a literal byte */
4015 switch(lit & 0xff ) {
4017 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4018 genSkipz2(&rFalseIfx,0);
4019 if(ifx) ifx->generated = 1;
4022 genSkipCond(&rFalseIfx,right,0,7);
4023 if(ifx) ifx->generated = 1;
4027 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4028 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4030 rFalseIfx.condition ^= 1;
4031 if (AOP_TYPE(result) == AOP_CRY) {
4032 genSkipc(&rFalseIfx);
4033 if(ifx) ifx->generated = 1;
4035 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4036 emitpcode(POC_CLRF, popGet(AOP(result),0));
4037 emitpcode(POC_RLF, popGet(AOP(result),0));
4038 emitpcode(POC_MOVLW, popGetLit(0x01));
4039 emitpcode(POC_XORWF, popGet(AOP(result),0));
4050 /* Size is greater than 1 */
4058 /* this means lit = 0xffffffff, or -1 */
4061 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4062 rFalseIfx.condition ^= 1;
4063 genSkipCond(&rFalseIfx,right,size,7);
4064 if(ifx) ifx->generated = 1;
4071 if(rFalseIfx.condition) {
4072 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4073 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4076 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4078 emitpcode(POC_IORFW, popGet(AOP(right),size));
4082 if(rFalseIfx.condition) {
4083 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4084 emitpLabel(truelbl->key);
4086 rFalseIfx.condition ^= 1;
4087 genSkipCond(&rFalseIfx,right,s,7);
4090 if(ifx) ifx->generated = 1;
4094 if((size == 1) && (0 == (lp1&0xff))) {
4095 /* lower byte of signed word is zero */
4096 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4097 i = ((lp1 >> 8) & 0xff) ^0x80;
4098 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4099 emitpcode(POC_ADDLW, popGetLit( 0x80));
4100 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4101 rFalseIfx.condition ^= 1;
4102 genSkipc(&rFalseIfx);
4105 if(ifx) ifx->generated = 1;
4109 if(lit & (0x80 << (size*8))) {
4110 /* Lit is less than zero */
4111 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4112 //rFalseIfx.condition ^= 1;
4113 //genSkipCond(&rFalseIfx,left,size,7);
4114 //rFalseIfx.condition ^= 1;
4115 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4116 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4118 if(rFalseIfx.condition)
4119 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4121 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4125 /* Lit is greater than or equal to zero */
4126 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4127 //rFalseIfx.condition ^= 1;
4128 //genSkipCond(&rFalseIfx,right,size,7);
4129 //rFalseIfx.condition ^= 1;
4131 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4132 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4134 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4135 if(rFalseIfx.condition)
4136 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4138 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4143 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4144 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4148 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4150 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4152 rFalseIfx.condition ^= 1;
4153 //rFalseIfx.condition = 1;
4154 genSkipc(&rFalseIfx);
4156 emitpLabel(truelbl->key);
4158 if(ifx) ifx->generated = 1;
4163 /* compare word or long to an unsigned literal on the right.*/
4168 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4171 break; /* handled above */
4174 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4176 emitpcode(POC_IORFW, popGet(AOP(right),size));
4177 genSkipz2(&rFalseIfx,0);
4181 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4183 emitpcode(POC_IORFW, popGet(AOP(right),size));
4186 if(rFalseIfx.condition)
4187 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4189 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4192 emitpcode(POC_MOVLW, popGetLit(lit+1));
4193 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4195 rFalseIfx.condition ^= 1;
4196 genSkipc(&rFalseIfx);
4199 emitpLabel(truelbl->key);
4201 if(ifx) ifx->generated = 1;
4207 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4208 i = (lit >> (size*8)) & 0xff;
4210 emitpcode(POC_MOVLW, popGetLit(i));
4211 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4214 i = (lit >> (size*8)) & 0xff;
4217 emitpcode(POC_MOVLW, popGetLit(i));
4219 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4221 /* this byte of the lit is zero,
4222 *if it's not the last then OR in the variable */
4224 emitpcode(POC_IORFW, popGet(AOP(right),size));
4229 emitpLabel(lbl->key);
4231 rFalseIfx.condition ^= 1;
4232 genSkipc(&rFalseIfx);
4236 emitpLabel(truelbl->key);
4237 if(ifx) ifx->generated = 1;
4241 /* Compare two variables */
4243 DEBUGpic14_emitcode(";sign","%d",sign);
4247 /* Sigh. thus sucks... */
4249 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4250 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4251 emitpcode(POC_MOVLW, popGetLit(0x80));
4252 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4253 emitpcode(POC_XORFW, popGet(AOP(right),size));
4254 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4256 /* Signed char comparison */
4257 /* Special thanks to Nikolai Golovchenko for this snippet */
4258 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4259 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4260 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4261 emitpcode(POC_XORFW, popGet(AOP(left),0));
4262 emitpcode(POC_XORFW, popGet(AOP(right),0));
4263 emitpcode(POC_ADDLW, popGetLit(0x80));
4265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4266 genSkipc(&rFalseIfx);
4268 if(ifx) ifx->generated = 1;
4274 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4275 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4279 /* The rest of the bytes of a multi-byte compare */
4283 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4286 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4287 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4292 emitpLabel(lbl->key);
4294 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4295 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4296 (AOP_TYPE(result) == AOP_REG)) {
4297 emitpcode(POC_CLRF, popGet(AOP(result),0));
4298 emitpcode(POC_RLF, popGet(AOP(result),0));
4300 genSkipc(&rFalseIfx);
4302 //genSkipc(&rFalseIfx);
4303 if(ifx) ifx->generated = 1;
4310 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4311 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4312 pic14_outBitC(result);
4314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4315 /* if the result is used in the next
4316 ifx conditional branch then generate
4317 code a little differently */
4319 genIfxJump (ifx,"c");
4321 pic14_outBitC(result);
4322 /* leave the result in acc */
4327 /*-----------------------------------------------------------------*/
4328 /* genCmpGt :- greater than comparison */
4329 /*-----------------------------------------------------------------*/
4330 static void genCmpGt (iCode *ic, iCode *ifx)
4332 operand *left, *right, *result;
4333 sym_link *letype , *retype;
4336 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4338 right= IC_RIGHT(ic);
4339 result = IC_RESULT(ic);
4341 letype = getSpec(operandType(left));
4342 retype =getSpec(operandType(right));
4343 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4344 /* assign the amsops */
4345 aopOp (left,ic,FALSE);
4346 aopOp (right,ic,FALSE);
4347 aopOp (result,ic,TRUE);
4349 genCmp(right, left, result, ifx, sign);
4351 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4352 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4353 freeAsmop(result,NULL,ic,TRUE);
4356 /*-----------------------------------------------------------------*/
4357 /* genCmpLt - less than comparisons */
4358 /*-----------------------------------------------------------------*/
4359 static void genCmpLt (iCode *ic, iCode *ifx)
4361 operand *left, *right, *result;
4362 sym_link *letype , *retype;
4365 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4367 right= IC_RIGHT(ic);
4368 result = IC_RESULT(ic);
4370 letype = getSpec(operandType(left));
4371 retype =getSpec(operandType(right));
4372 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4374 /* assign the amsops */
4375 aopOp (left,ic,FALSE);
4376 aopOp (right,ic,FALSE);
4377 aopOp (result,ic,TRUE);
4379 genCmp(left, right, result, ifx, sign);
4381 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4382 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4383 freeAsmop(result,NULL,ic,TRUE);
4386 /*-----------------------------------------------------------------*/
4387 /* genc16bit2lit - compare a 16 bit value to a literal */
4388 /*-----------------------------------------------------------------*/
4389 static void genc16bit2lit(operand *op, int lit, int offset)
4393 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4394 if( (lit&0xff) == 0)
4399 switch( BYTEofLONG(lit,i)) {
4401 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4404 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4407 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4410 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4411 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4416 switch( BYTEofLONG(lit,i)) {
4418 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4422 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4426 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4429 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4431 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4437 /*-----------------------------------------------------------------*/
4438 /* gencjneshort - compare and jump if not equal */
4439 /*-----------------------------------------------------------------*/
4440 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4442 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4444 int res_offset = 0; /* the result may be a different size then left or right */
4445 int res_size = AOP_SIZE(result);
4449 unsigned long lit = 0L;
4450 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4451 DEBUGpic14_AopType(__LINE__,left,right,result);
4453 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4454 resolveIfx(&rIfx,ifx);
4455 lbl = newiTempLabel(NULL);
4458 /* if the left side is a literal or
4459 if the right is in a pointer register and left
4461 if ((AOP_TYPE(left) == AOP_LIT) ||
4462 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4467 if(AOP_TYPE(right) == AOP_LIT)
4468 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4470 /* if the right side is a literal then anything goes */
4471 if (AOP_TYPE(right) == AOP_LIT &&
4472 AOP_TYPE(left) != AOP_DIR ) {
4475 genc16bit2lit(left, lit, 0);
4477 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4482 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4483 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4485 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4489 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4491 if(res_offset < res_size-1)
4499 /* if the right side is in a register or in direct space or
4500 if the left is a pointer register & right is not */
4501 else if (AOP_TYPE(right) == AOP_REG ||
4502 AOP_TYPE(right) == AOP_DIR ||
4503 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4504 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4505 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4506 int lbl_key = lbl->key;
4509 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4510 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4512 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4513 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4514 __FUNCTION__,__LINE__);
4518 /* switch(size) { */
4520 /* genc16bit2lit(left, lit, 0); */
4522 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4527 if((AOP_TYPE(left) == AOP_DIR) &&
4528 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4530 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4531 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4533 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4535 switch (lit & 0xff) {
4537 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4540 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4541 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4542 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4546 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4547 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4548 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4549 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4553 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4554 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4559 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4562 if(AOP_TYPE(result) == AOP_CRY) {
4563 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4568 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4570 /* fix me. probably need to check result size too */
4571 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4576 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4577 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4584 if(res_offset < res_size-1)
4589 } else if(AOP_TYPE(right) == AOP_REG &&
4590 AOP_TYPE(left) != AOP_DIR){
4593 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4594 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4595 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4600 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4602 if(res_offset < res_size-1)
4607 /* right is a pointer reg need both a & b */
4609 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4611 pic14_emitcode("mov","b,%s",l);
4612 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4613 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4618 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4620 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4622 emitpLabel(lbl->key);
4624 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4631 /*-----------------------------------------------------------------*/
4632 /* gencjne - compare and jump if not equal */
4633 /*-----------------------------------------------------------------*/
4634 static void gencjne(operand *left, operand *right, iCode *ifx)
4636 symbol *tlbl = newiTempLabel(NULL);
4638 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4639 gencjneshort(left, right, lbl);
4641 pic14_emitcode("mov","a,%s",one);
4642 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4643 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4644 pic14_emitcode("clr","a");
4645 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4647 emitpLabel(lbl->key);
4648 emitpLabel(tlbl->key);
4653 /*-----------------------------------------------------------------*/
4654 /* genCmpEq - generates code for equal to */
4655 /*-----------------------------------------------------------------*/
4656 static void genCmpEq (iCode *ic, iCode *ifx)
4658 operand *left, *right, *result;
4659 unsigned long lit = 0L;
4662 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4665 DEBUGpic14_emitcode ("; ifx is non-null","");
4667 DEBUGpic14_emitcode ("; ifx is null","");
4669 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4670 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4671 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4673 size = max(AOP_SIZE(left),AOP_SIZE(right));
4675 DEBUGpic14_AopType(__LINE__,left,right,result);
4677 /* if literal, literal on the right or
4678 if the right is in a pointer register and left
4680 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4681 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4682 operand *tmp = right ;
4688 if(ifx && !AOP_SIZE(result)){
4690 /* if they are both bit variables */
4691 if (AOP_TYPE(left) == AOP_CRY &&
4692 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4693 if(AOP_TYPE(right) == AOP_LIT){
4694 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4696 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4697 pic14_emitcode("cpl","c");
4698 } else if(lit == 1L) {
4699 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4701 pic14_emitcode("clr","c");
4703 /* AOP_TYPE(right) == AOP_CRY */
4705 symbol *lbl = newiTempLabel(NULL);
4706 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4707 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4708 pic14_emitcode("cpl","c");
4709 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4711 /* if true label then we jump if condition
4713 tlbl = newiTempLabel(NULL);
4714 if ( IC_TRUE(ifx) ) {
4715 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4716 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4718 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4719 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4721 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4724 /* left and right are both bit variables, result is carry */
4727 resolveIfx(&rIfx,ifx);
4729 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4730 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4731 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4732 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4737 /* They're not both bit variables. Is the right a literal? */
4738 if(AOP_TYPE(right) == AOP_LIT) {
4739 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4744 switch(lit & 0xff) {
4746 if ( IC_TRUE(ifx) ) {
4747 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4749 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4751 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4752 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4756 if ( IC_TRUE(ifx) ) {
4757 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4759 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4761 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4762 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4766 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4768 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4773 /* end of size == 1 */
4777 genc16bit2lit(left,lit,offset);
4780 /* end of size == 2 */
4785 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4786 emitpcode(POC_IORFW,popGet(AOP(left),1));
4787 emitpcode(POC_IORFW,popGet(AOP(left),2));
4788 emitpcode(POC_IORFW,popGet(AOP(left),3));
4792 /* search for patterns that can be optimized */
4794 genc16bit2lit(left,lit,0);
4797 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4799 genc16bit2lit(left,lit,2);
4801 emitpcode(POC_IORFW,popGet(AOP(left),2));
4802 emitpcode(POC_IORFW,popGet(AOP(left),3));
4815 } else if(AOP_TYPE(right) == AOP_CRY ) {
4816 /* we know the left is not a bit, but that the right is */
4817 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4818 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4819 popGet(AOP(right),offset));
4820 emitpcode(POC_XORLW,popGetLit(1));
4822 /* if the two are equal, then W will be 0 and the Z bit is set
4823 * we could test Z now, or go ahead and check the high order bytes if
4824 * the variable we're comparing is larger than a byte. */
4827 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4829 if ( IC_TRUE(ifx) ) {
4831 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4832 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4835 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4836 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4840 /* They're both variables that are larger than bits */
4843 tlbl = newiTempLabel(NULL);
4846 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4847 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4849 if ( IC_TRUE(ifx) ) {
4852 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4853 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4856 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4857 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4861 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4862 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4866 if(s>1 && IC_TRUE(ifx)) {
4867 emitpLabel(tlbl->key);
4868 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4872 /* mark the icode as generated */
4877 /* if they are both bit variables */
4878 if (AOP_TYPE(left) == AOP_CRY &&
4879 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4880 if(AOP_TYPE(right) == AOP_LIT){
4881 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4883 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4884 pic14_emitcode("cpl","c");
4885 } else if(lit == 1L) {
4886 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4888 pic14_emitcode("clr","c");
4890 /* AOP_TYPE(right) == AOP_CRY */
4892 symbol *lbl = newiTempLabel(NULL);
4893 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4894 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4895 pic14_emitcode("cpl","c");
4896 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4899 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4900 pic14_outBitC(result);
4904 genIfxJump (ifx,"c");
4907 /* if the result is used in an arithmetic operation
4908 then put the result in place */
4909 pic14_outBitC(result);
4912 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4913 gencjne(left,right,result,ifx);
4916 gencjne(left,right,newiTempLabel(NULL));
4918 if(IC_TRUE(ifx)->key)
4919 gencjne(left,right,IC_TRUE(ifx)->key);
4921 gencjne(left,right,IC_FALSE(ifx)->key);
4925 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4926 aopPut(AOP(result),"a",0);
4931 genIfxJump (ifx,"a");
4935 /* if the result is used in an arithmetic operation
4936 then put the result in place */
4938 if (AOP_TYPE(result) != AOP_CRY)
4939 pic14_outAcc(result);
4941 /* leave the result in acc */
4945 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4946 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4947 freeAsmop(result,NULL,ic,TRUE);
4950 /*-----------------------------------------------------------------*/
4951 /* ifxForOp - returns the icode containing the ifx for operand */
4952 /*-----------------------------------------------------------------*/
4953 static iCode *ifxForOp ( operand *op, iCode *ic )
4955 /* if true symbol then needs to be assigned */
4956 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4957 if (IS_TRUE_SYMOP(op))
4960 /* if this has register type condition and
4961 the next instruction is ifx with the same operand
4962 and live to of the operand is upto the ifx only then */
4964 ic->next->op == IFX &&
4965 IC_COND(ic->next)->key == op->key &&
4966 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4970 ic->next->op == IFX &&
4971 IC_COND(ic->next)->key == op->key) {
4972 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4976 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4978 ic->next->op == IFX)
4979 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
4982 ic->next->op == IFX &&
4983 IC_COND(ic->next)->key == op->key) {
4984 DEBUGpic14_emitcode ("; "," key is okay");
4985 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
4986 OP_SYMBOL(op)->liveTo,
4993 /*-----------------------------------------------------------------*/
4994 /* genAndOp - for && operation */
4995 /*-----------------------------------------------------------------*/
4996 static void genAndOp (iCode *ic)
4998 operand *left,*right, *result;
5001 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5002 /* note here that && operations that are in an
5003 if statement are taken away by backPatchLabels
5004 only those used in arthmetic operations remain */
5005 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5006 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5007 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5009 DEBUGpic14_AopType(__LINE__,left,right,result);
5011 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5012 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5013 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5015 /* if both are bit variables */
5016 /* if (AOP_TYPE(left) == AOP_CRY && */
5017 /* AOP_TYPE(right) == AOP_CRY ) { */
5018 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5019 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5020 /* pic14_outBitC(result); */
5022 /* tlbl = newiTempLabel(NULL); */
5023 /* pic14_toBoolean(left); */
5024 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5025 /* pic14_toBoolean(right); */
5026 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5027 /* pic14_outBitAcc(result); */
5030 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5031 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5032 freeAsmop(result,NULL,ic,TRUE);
5036 /*-----------------------------------------------------------------*/
5037 /* genOrOp - for || operation */
5038 /*-----------------------------------------------------------------*/
5041 modified this code, but it doesn't appear to ever get called
5044 static void genOrOp (iCode *ic)
5046 operand *left,*right, *result;
5049 /* note here that || operations that are in an
5050 if statement are taken away by backPatchLabels
5051 only those used in arthmetic operations remain */
5052 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5053 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5054 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5055 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5057 DEBUGpic14_AopType(__LINE__,left,right,result);
5059 /* if both are bit variables */
5060 if (AOP_TYPE(left) == AOP_CRY &&
5061 AOP_TYPE(right) == AOP_CRY ) {
5062 pic14_emitcode("clrc","");
5063 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5064 AOP(left)->aopu.aop_dir,
5065 AOP(left)->aopu.aop_dir);
5066 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5067 AOP(right)->aopu.aop_dir,
5068 AOP(right)->aopu.aop_dir);
5069 pic14_emitcode("setc","");
5072 tlbl = newiTempLabel(NULL);
5073 pic14_toBoolean(left);
5075 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5076 pic14_toBoolean(right);
5077 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5079 pic14_outBitAcc(result);
5082 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5083 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5084 freeAsmop(result,NULL,ic,TRUE);
5087 /*-----------------------------------------------------------------*/
5088 /* isLiteralBit - test if lit == 2^n */
5089 /*-----------------------------------------------------------------*/
5090 static int isLiteralBit(unsigned long lit)
5092 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5093 0x100L,0x200L,0x400L,0x800L,
5094 0x1000L,0x2000L,0x4000L,0x8000L,
5095 0x10000L,0x20000L,0x40000L,0x80000L,
5096 0x100000L,0x200000L,0x400000L,0x800000L,
5097 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5098 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5101 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5102 for(idx = 0; idx < 32; idx++)
5108 /*-----------------------------------------------------------------*/
5109 /* continueIfTrue - */
5110 /*-----------------------------------------------------------------*/
5111 static void continueIfTrue (iCode *ic)
5113 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5115 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5119 /*-----------------------------------------------------------------*/
5121 /*-----------------------------------------------------------------*/
5122 static void jumpIfTrue (iCode *ic)
5124 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5126 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5130 /*-----------------------------------------------------------------*/
5131 /* jmpTrueOrFalse - */
5132 /*-----------------------------------------------------------------*/
5133 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5135 // ugly but optimized by peephole
5136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5138 symbol *nlbl = newiTempLabel(NULL);
5139 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5140 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5141 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5142 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5145 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5146 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5151 /*-----------------------------------------------------------------*/
5152 /* genAnd - code for and */
5153 /*-----------------------------------------------------------------*/
5154 static void genAnd (iCode *ic, iCode *ifx)
5156 operand *left, *right, *result;
5158 unsigned long lit = 0L;
5163 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5164 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5165 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5166 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5168 resolveIfx(&rIfx,ifx);
5170 /* if left is a literal & right is not then exchange them */
5171 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5172 AOP_NEEDSACC(left)) {
5173 operand *tmp = right ;
5178 /* if result = right then exchange them */
5179 if(pic14_sameRegs(AOP(result),AOP(right))){
5180 operand *tmp = right ;
5185 /* if right is bit then exchange them */
5186 if (AOP_TYPE(right) == AOP_CRY &&
5187 AOP_TYPE(left) != AOP_CRY){
5188 operand *tmp = right ;
5192 if(AOP_TYPE(right) == AOP_LIT)
5193 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5195 size = AOP_SIZE(result);
5197 DEBUGpic14_AopType(__LINE__,left,right,result);
5200 // result = bit & yy;
5201 if (AOP_TYPE(left) == AOP_CRY){
5202 // c = bit & literal;
5203 if(AOP_TYPE(right) == AOP_LIT){
5205 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5208 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5211 if(size && (AOP_TYPE(result) == AOP_CRY)){
5212 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5215 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5219 pic14_emitcode("clr","c");
5222 if (AOP_TYPE(right) == AOP_CRY){
5224 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5225 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5228 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5230 pic14_emitcode("rrc","a");
5231 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5237 pic14_outBitC(result);
5239 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5240 genIfxJump(ifx, "c");
5244 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5245 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5246 if((AOP_TYPE(right) == AOP_LIT) &&
5247 (AOP_TYPE(result) == AOP_CRY) &&
5248 (AOP_TYPE(left) != AOP_CRY)){
5249 int posbit = isLiteralBit(lit);
5253 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5256 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5261 while (posbit > 7) {
5265 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5266 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5267 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5274 symbol *tlbl = newiTempLabel(NULL);
5275 int sizel = AOP_SIZE(left);
5277 pic14_emitcode("setb","c");
5279 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5280 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5282 if((posbit = isLiteralBit(bytelit)) != 0)
5283 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5285 if(bytelit != 0x0FFL)
5286 pic14_emitcode("anl","a,%s",
5287 aopGet(AOP(right),offset,FALSE,TRUE));
5288 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5293 // bit = left & literal
5295 pic14_emitcode("clr","c");
5296 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5298 // if(left & literal)
5301 jmpTrueOrFalse(ifx, tlbl);
5305 pic14_outBitC(result);
5309 /* if left is same as result */
5310 if(pic14_sameRegs(AOP(result),AOP(left))){
5312 for(;size--; offset++,lit>>=8) {
5313 if(AOP_TYPE(right) == AOP_LIT){
5314 switch(lit & 0xff) {
5316 /* and'ing with 0 has clears the result */
5317 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5320 /* and'ing with 0xff is a nop when the result and left are the same */
5325 int p = my_powof2( (~lit) & 0xff );
5327 /* only one bit is set in the literal, so use a bcf instruction */
5328 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5331 if(know_W != (int)(lit&0xff))
5332 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5334 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5339 if (AOP_TYPE(left) == AOP_ACC) {
5340 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5342 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5343 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5350 // left & result in different registers
5351 if(AOP_TYPE(result) == AOP_CRY){
5353 // if(size), result in bit
5354 // if(!size && ifx), conditional oper: if(left & right)
5355 symbol *tlbl = newiTempLabel(NULL);
5356 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5358 pic14_emitcode("setb","c");
5360 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5361 pic14_emitcode("anl","a,%s",
5362 aopGet(AOP(left),offset,FALSE,FALSE));
5363 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5368 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5369 pic14_outBitC(result);
5371 jmpTrueOrFalse(ifx, tlbl);
5373 for(;(size--);offset++) {
5375 // result = left & right
5376 if(AOP_TYPE(right) == AOP_LIT){
5377 int t = (lit >> (offset*8)) & 0x0FFL;
5380 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5383 if(AOP_TYPE(left) != AOP_ACC) {
5384 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5386 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5389 if(AOP_TYPE(left) == AOP_ACC) {
5390 emitpcode(POC_ANDLW, popGetLit(t));
5392 emitpcode(POC_MOVLW, popGetLit(t));
5393 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5395 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5400 if (AOP_TYPE(left) == AOP_ACC) {
5401 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5403 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5404 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5406 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5412 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5413 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5414 freeAsmop(result,NULL,ic,TRUE);
5417 /*-----------------------------------------------------------------*/
5418 /* genOr - code for or */
5419 /*-----------------------------------------------------------------*/
5420 static void genOr (iCode *ic, iCode *ifx)
5422 operand *left, *right, *result;
5424 unsigned long lit = 0L;
5426 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5428 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5429 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5430 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5432 DEBUGpic14_AopType(__LINE__,left,right,result);
5434 /* if left is a literal & right is not then exchange them */
5435 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5436 AOP_NEEDSACC(left)) {
5437 operand *tmp = right ;
5442 /* if result = right then exchange them */
5443 if(pic14_sameRegs(AOP(result),AOP(right))){
5444 operand *tmp = right ;
5449 /* if right is bit then exchange them */
5450 if (AOP_TYPE(right) == AOP_CRY &&
5451 AOP_TYPE(left) != AOP_CRY){
5452 operand *tmp = right ;
5457 DEBUGpic14_AopType(__LINE__,left,right,result);
5459 if(AOP_TYPE(right) == AOP_LIT)
5460 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5462 size = AOP_SIZE(result);
5466 if (AOP_TYPE(left) == AOP_CRY){
5467 if(AOP_TYPE(right) == AOP_LIT){
5468 // c = bit & literal;
5470 // lit != 0 => result = 1
5471 if(AOP_TYPE(result) == AOP_CRY){
5473 emitpcode(POC_BSF, popGet(AOP(result),0));
5474 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5475 // AOP(result)->aopu.aop_dir,
5476 // AOP(result)->aopu.aop_dir);
5478 continueIfTrue(ifx);
5482 // lit == 0 => result = left
5483 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5485 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5488 if (AOP_TYPE(right) == AOP_CRY){
5489 if(pic14_sameRegs(AOP(result),AOP(left))){
5491 emitpcode(POC_BCF, popGet(AOP(result),0));
5492 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5493 emitpcode(POC_BSF, popGet(AOP(result),0));
5495 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5496 AOP(result)->aopu.aop_dir,
5497 AOP(result)->aopu.aop_dir);
5498 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5499 AOP(right)->aopu.aop_dir,
5500 AOP(right)->aopu.aop_dir);
5501 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5502 AOP(result)->aopu.aop_dir,
5503 AOP(result)->aopu.aop_dir);
5505 if( AOP_TYPE(result) == AOP_ACC) {
5506 emitpcode(POC_MOVLW, popGetLit(0));
5507 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5508 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5509 emitpcode(POC_MOVLW, popGetLit(1));
5513 emitpcode(POC_BCF, popGet(AOP(result),0));
5514 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5515 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5516 emitpcode(POC_BSF, popGet(AOP(result),0));
5518 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5519 AOP(result)->aopu.aop_dir,
5520 AOP(result)->aopu.aop_dir);
5521 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5522 AOP(right)->aopu.aop_dir,
5523 AOP(right)->aopu.aop_dir);
5524 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5525 AOP(left)->aopu.aop_dir,
5526 AOP(left)->aopu.aop_dir);
5527 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5528 AOP(result)->aopu.aop_dir,
5529 AOP(result)->aopu.aop_dir);
5534 symbol *tlbl = newiTempLabel(NULL);
5535 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5538 emitpcode(POC_BCF, popGet(AOP(result),0));
5539 if( AOP_TYPE(right) == AOP_ACC) {
5540 emitpcode(POC_IORLW, popGetLit(0));
5542 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5543 emitpcode(POC_BSF, popGet(AOP(result),0));
5548 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5549 pic14_emitcode(";XXX setb","c");
5550 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5551 AOP(left)->aopu.aop_dir,tlbl->key+100);
5552 pic14_toBoolean(right);
5553 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5554 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5555 jmpTrueOrFalse(ifx, tlbl);
5559 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5566 pic14_outBitC(result);
5568 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5569 genIfxJump(ifx, "c");
5573 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5574 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5575 if((AOP_TYPE(right) == AOP_LIT) &&
5576 (AOP_TYPE(result) == AOP_CRY) &&
5577 (AOP_TYPE(left) != AOP_CRY)){
5579 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5582 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5584 continueIfTrue(ifx);
5587 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5588 // lit = 0, result = boolean(left)
5590 pic14_emitcode(";XXX setb","c");
5591 pic14_toBoolean(right);
5593 symbol *tlbl = newiTempLabel(NULL);
5594 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5596 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5598 genIfxJump (ifx,"a");
5602 pic14_outBitC(result);
5606 /* if left is same as result */
5607 if(pic14_sameRegs(AOP(result),AOP(left))){
5609 for(;size--; offset++,lit>>=8) {
5610 if(AOP_TYPE(right) == AOP_LIT){
5611 if((lit & 0xff) == 0)
5612 /* or'ing with 0 has no effect */
5615 int p = my_powof2(lit & 0xff);
5617 /* only one bit is set in the literal, so use a bsf instruction */
5619 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5621 if(know_W != (int)(lit & 0xff))
5622 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5623 know_W = lit & 0xff;
5624 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5629 if (AOP_TYPE(left) == AOP_ACC) {
5630 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5631 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5633 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5634 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5636 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5637 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5643 // left & result in different registers
5644 if(AOP_TYPE(result) == AOP_CRY){
5646 // if(size), result in bit
5647 // if(!size && ifx), conditional oper: if(left | right)
5648 symbol *tlbl = newiTempLabel(NULL);
5649 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5650 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5654 pic14_emitcode(";XXX setb","c");
5656 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5657 pic14_emitcode(";XXX orl","a,%s",
5658 aopGet(AOP(left),offset,FALSE,FALSE));
5659 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5664 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5665 pic14_outBitC(result);
5667 jmpTrueOrFalse(ifx, tlbl);
5668 } else for(;(size--);offset++){
5670 // result = left | right
5671 if(AOP_TYPE(right) == AOP_LIT){
5672 int t = (lit >> (offset*8)) & 0x0FFL;
5675 if (AOP_TYPE(left) != AOP_ACC) {
5676 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5678 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5682 if (AOP_TYPE(left) == AOP_ACC) {
5683 emitpcode(POC_IORLW, popGetLit(t));
5685 emitpcode(POC_MOVLW, popGetLit(t));
5686 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5688 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5693 // faster than result <- left, anl result,right
5694 // and better if result is SFR
5695 if (AOP_TYPE(left) == AOP_ACC) {
5696 emitpcode(POC_IORFW,popGet(AOP(right),offset));
5698 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5699 emitpcode(POC_IORFW,popGet(AOP(left),offset));
5701 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5706 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5707 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5708 freeAsmop(result,NULL,ic,TRUE);
5711 /*-----------------------------------------------------------------*/
5712 /* genXor - code for xclusive or */
5713 /*-----------------------------------------------------------------*/
5714 static void genXor (iCode *ic, iCode *ifx)
5716 operand *left, *right, *result;
5718 unsigned long lit = 0L;
5720 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5722 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5723 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5724 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5726 /* if left is a literal & right is not ||
5727 if left needs acc & right does not */
5728 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5729 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5730 operand *tmp = right ;
5735 /* if result = right then exchange them */
5736 if(pic14_sameRegs(AOP(result),AOP(right))){
5737 operand *tmp = right ;
5742 /* if right is bit then exchange them */
5743 if (AOP_TYPE(right) == AOP_CRY &&
5744 AOP_TYPE(left) != AOP_CRY){
5745 operand *tmp = right ;
5749 if(AOP_TYPE(right) == AOP_LIT)
5750 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5752 size = AOP_SIZE(result);
5756 if (AOP_TYPE(left) == AOP_CRY){
5757 if(AOP_TYPE(right) == AOP_LIT){
5758 // c = bit & literal;
5760 // lit>>1 != 0 => result = 1
5761 if(AOP_TYPE(result) == AOP_CRY){
5763 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5764 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5766 continueIfTrue(ifx);
5769 pic14_emitcode("setb","c");
5773 // lit == 0, result = left
5774 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5776 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5778 // lit == 1, result = not(left)
5779 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5780 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5781 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5782 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5785 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5786 pic14_emitcode("cpl","c");
5793 symbol *tlbl = newiTempLabel(NULL);
5794 if (AOP_TYPE(right) == AOP_CRY){
5796 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5799 int sizer = AOP_SIZE(right);
5801 // if val>>1 != 0, result = 1
5802 pic14_emitcode("setb","c");
5804 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5806 // test the msb of the lsb
5807 pic14_emitcode("anl","a,#0xfe");
5808 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5812 pic14_emitcode("rrc","a");
5814 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5815 pic14_emitcode("cpl","c");
5816 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5821 pic14_outBitC(result);
5823 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5824 genIfxJump(ifx, "c");
5828 if(pic14_sameRegs(AOP(result),AOP(left))){
5829 /* if left is same as result */
5830 for(;size--; offset++) {
5831 if(AOP_TYPE(right) == AOP_LIT){
5832 int t = (lit >> (offset*8)) & 0x0FFL;
5836 if (IS_AOP_PREG(left)) {
5837 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5838 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5839 aopPut(AOP(result),"a",offset);
5841 emitpcode(POC_MOVLW, popGetLit(t));
5842 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5843 pic14_emitcode("xrl","%s,%s",
5844 aopGet(AOP(left),offset,FALSE,TRUE),
5845 aopGet(AOP(right),offset,FALSE,FALSE));
5848 if (AOP_TYPE(left) == AOP_ACC)
5849 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5851 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5852 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5854 if (IS_AOP_PREG(left)) {
5855 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5856 aopPut(AOP(result),"a",offset);
5858 pic14_emitcode("xrl","%s,a",
5859 aopGet(AOP(left),offset,FALSE,TRUE));
5865 // left & result in different registers
5866 if(AOP_TYPE(result) == AOP_CRY){
5868 // if(size), result in bit
5869 // if(!size && ifx), conditional oper: if(left ^ right)
5870 symbol *tlbl = newiTempLabel(NULL);
5871 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5873 pic14_emitcode("setb","c");
5875 if((AOP_TYPE(right) == AOP_LIT) &&
5876 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5877 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5879 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5880 pic14_emitcode("xrl","a,%s",
5881 aopGet(AOP(left),offset,FALSE,FALSE));
5883 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5888 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5889 pic14_outBitC(result);
5891 jmpTrueOrFalse(ifx, tlbl);
5892 } else for(;(size--);offset++){
5894 // result = left & right
5895 if(AOP_TYPE(right) == AOP_LIT){
5896 int t = (lit >> (offset*8)) & 0x0FFL;
5899 if (AOP_TYPE(left) != AOP_ACC) {
5900 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5902 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5903 pic14_emitcode("movf","%s,w",
5904 aopGet(AOP(left),offset,FALSE,FALSE));
5905 pic14_emitcode("movwf","%s",
5906 aopGet(AOP(result),offset,FALSE,FALSE));
5909 if (AOP_TYPE(left) == AOP_ACC) {
5910 emitpcode(POC_XORLW, popGetLit(t));
5912 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5914 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5917 if (AOP_TYPE(left) == AOP_ACC) {
5918 emitpcode(POC_XORLW, popGetLit(t));
5920 emitpcode(POC_MOVLW, popGetLit(t));
5921 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5923 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5924 pic14_emitcode("movlw","0x%x",t);
5925 pic14_emitcode("xorwf","%s,w",
5926 aopGet(AOP(left),offset,FALSE,FALSE));
5927 pic14_emitcode("movwf","%s",
5928 aopGet(AOP(result),offset,FALSE,FALSE));
5934 // faster than result <- left, anl result,right
5935 // and better if result is SFR
5936 if (AOP_TYPE(left) == AOP_ACC) {
5937 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5939 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5940 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5942 if ( AOP_TYPE(result) != AOP_ACC){
5943 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5949 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5950 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5951 freeAsmop(result,NULL,ic,TRUE);
5954 /*-----------------------------------------------------------------*/
5955 /* genInline - write the inline code out */
5956 /*-----------------------------------------------------------------*/
5957 static void genInline (iCode *ic)
5959 char *buffer, *bp, *bp1;
5961 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5963 _G.inLine += (!options.asmpeep);
5965 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
5966 strcpy(buffer,IC_INLINE(ic));
5968 /* emit each line as a code */
5974 addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
5982 /* print label, use this special format with NULL directive
5983 * to denote that the argument should not be indented with tab */
5984 addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process
5991 if ((bp1 != bp) && *bp1)
5992 addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process
5996 _G.inLine -= (!options.asmpeep);
5999 /*-----------------------------------------------------------------*/
6000 /* genRRC - rotate right with carry */
6001 /*-----------------------------------------------------------------*/
6002 static void genRRC (iCode *ic)
6004 operand *left , *result ;
6005 int size, offset = 0, same;
6007 /* rotate right with carry */
6009 result=IC_RESULT(ic);
6010 aopOp (left,ic,FALSE);
6011 aopOp (result,ic,FALSE);
6013 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6015 same = pic14_sameRegs(AOP(result),AOP(left));
6017 size = AOP_SIZE(result);
6019 /* get the lsb and put it into the carry */
6020 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6027 emitpcode(POC_RRF, popGet(AOP(left),offset));
6029 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6030 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6036 freeAsmop(left,NULL,ic,TRUE);
6037 freeAsmop(result,NULL,ic,TRUE);
6040 /*-----------------------------------------------------------------*/
6041 /* genRLC - generate code for rotate left with carry */
6042 /*-----------------------------------------------------------------*/
6043 static void genRLC (iCode *ic)
6045 operand *left , *result ;
6046 int size, offset = 0;
6049 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6050 /* rotate right with carry */
6052 result=IC_RESULT(ic);
6053 aopOp (left,ic,FALSE);
6054 aopOp (result,ic,FALSE);
6056 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6058 same = pic14_sameRegs(AOP(result),AOP(left));
6060 /* move it to the result */
6061 size = AOP_SIZE(result);
6063 /* get the msb and put it into the carry */
6064 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6071 emitpcode(POC_RLF, popGet(AOP(left),offset));
6073 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6074 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6081 freeAsmop(left,NULL,ic,TRUE);
6082 freeAsmop(result,NULL,ic,TRUE);
6085 /*-----------------------------------------------------------------*/
6086 /* genGetHbit - generates code get highest order bit */
6087 /*-----------------------------------------------------------------*/
6088 static void genGetHbit (iCode *ic)
6090 operand *left, *result;
6092 result=IC_RESULT(ic);
6093 aopOp (left,ic,FALSE);
6094 aopOp (result,ic,FALSE);
6096 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6097 /* get the highest order byte into a */
6098 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6099 if(AOP_TYPE(result) == AOP_CRY){
6100 pic14_emitcode("rlc","a");
6101 pic14_outBitC(result);
6104 pic14_emitcode("rl","a");
6105 pic14_emitcode("anl","a,#0x01");
6106 pic14_outAcc(result);
6110 freeAsmop(left,NULL,ic,TRUE);
6111 freeAsmop(result,NULL,ic,TRUE);
6114 /*-----------------------------------------------------------------*/
6115 /* AccRol - rotate left accumulator by known count */
6116 /*-----------------------------------------------------------------*/
6117 static void AccRol (operand *op,int offset,int shCount)
6119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6120 shCount &= 0x0007; // shCount : 0..7
6125 pic14_emitcode("rl","a");
6126 emitpcode(POC_RLF,popGet(AOP(op),offset));
6129 pic14_emitcode("rl","a");
6130 pic14_emitcode("rl","a");
6131 emitpcode(POC_RLF,popGet(AOP(op),offset));
6132 emitpcode(POC_RLF,popGet(AOP(op),offset));
6135 pic14_emitcode("swap","a");
6136 pic14_emitcode("rr","a");
6137 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6138 emitpcode(POC_RRF,popGet(AOP(op),offset));
6141 pic14_emitcode("swap","a");
6142 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6145 pic14_emitcode("swap","a");
6146 pic14_emitcode("rl","a");
6147 emitpcode(POC_SWAPF,popGet(AOP(op),offset));
6148 emitpcode(POC_RLF,popGet(AOP(op),offset));
6151 pic14_emitcode("rr","a");
6152 pic14_emitcode("rr","a");
6153 emitpcode(POC_RRF,popGet(AOP(op),offset));
6154 emitpcode(POC_RRF,popGet(AOP(op),offset));
6157 pic14_emitcode("rr","a");
6158 emitpcode(POC_RRF,popGet(AOP(op),offset));
6163 /*-----------------------------------------------------------------*/
6164 /* AccLsh - left shift accumulator by known count */
6165 /*-----------------------------------------------------------------*/
6166 static void AccLsh (operand *op,int offset,int shCount)
6168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6172 pic14_emitcode("add","a,acc");
6174 emitpcode(POC_RLF,popGet(AOP(op),offset));
6177 pic14_emitcode("add","a,acc");
6179 emitpcode(POC_RLF,popGet(AOP(op),offset));
6180 pic14_emitcode("add","a,acc");
6182 emitpcode(POC_RLF,popGet(AOP(op),offset));
6187 /* rotate left accumulator */
6188 AccRol(op,offset,shCount);
6189 /* and kill the lower order bits */
6190 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6191 emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
6197 /*-----------------------------------------------------------------*/
6198 /* AccRsh - right shift accumulator by known count */
6199 /*-----------------------------------------------------------------*/
6200 static void AccRsh (operand *op,int offset,int shCount)
6202 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6206 pic14_emitcode("rrc","a");
6208 /* rotate right accumulator */
6209 AccRol(op,offset,8 - shCount);
6210 /* and kill the higher order bits */
6211 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6217 /*-----------------------------------------------------------------*/
6218 /* AccSRsh - signed right shift accumulator by known count */
6219 /*-----------------------------------------------------------------*/
6220 static void AccSRsh (int shCount)
6223 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6226 pic14_emitcode("mov","c,acc.7");
6227 pic14_emitcode("rrc","a");
6228 } else if(shCount == 2){
6229 pic14_emitcode("mov","c,acc.7");
6230 pic14_emitcode("rrc","a");
6231 pic14_emitcode("mov","c,acc.7");
6232 pic14_emitcode("rrc","a");
6234 tlbl = newiTempLabel(NULL);
6235 /* rotate right accumulator */
6236 AccRol(8 - shCount);
6237 /* and kill the higher order bits */
6238 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6239 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6240 pic14_emitcode("orl","a,#0x%02x",
6241 (unsigned char)~SRMask[shCount]);
6242 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6247 /*-----------------------------------------------------------------*/
6248 /* shiftR1Left2Result - shift right one byte from left to result */
6249 /*-----------------------------------------------------------------*/
6250 static void shiftR1Left2ResultSigned (operand *left, int offl,
6251 operand *result, int offr,
6256 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6258 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6262 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6264 emitpcode(POC_RRF, popGet(AOP(result),offr));
6266 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6267 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6273 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6275 emitpcode(POC_RRF, popGet(AOP(result),offr));
6277 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6278 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6280 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6281 emitpcode(POC_RRF, popGet(AOP(result),offr));
6287 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6289 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6290 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6293 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6294 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6295 emitpcode(POC_ANDLW, popGetLit(0x1f));
6297 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6298 emitpcode(POC_IORLW, popGetLit(0xe0));
6300 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6304 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6305 emitpcode(POC_ANDLW, popGetLit(0x0f));
6306 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6307 emitpcode(POC_IORLW, popGetLit(0xf0));
6308 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6312 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6314 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6315 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6317 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6318 emitpcode(POC_ANDLW, popGetLit(0x07));
6319 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6320 emitpcode(POC_IORLW, popGetLit(0xf8));
6321 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6326 emitpcode(POC_MOVLW, popGetLit(0x00));
6327 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6328 emitpcode(POC_MOVLW, popGetLit(0xfe));
6329 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6330 emitpcode(POC_IORLW, popGetLit(0x01));
6331 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6333 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6334 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6335 emitpcode(POC_DECF, popGet(AOP(result),offr));
6336 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6337 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6343 emitpcode(POC_MOVLW, popGetLit(0x00));
6344 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6345 emitpcode(POC_MOVLW, popGetLit(0xff));
6346 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6348 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6349 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6350 emitpcode(POC_DECF, popGet(AOP(result),offr));
6358 /*-----------------------------------------------------------------*/
6359 /* shiftR1Left2Result - shift right one byte from left to result */
6360 /*-----------------------------------------------------------------*/
6361 static void shiftR1Left2Result (operand *left, int offl,
6362 operand *result, int offr,
6363 int shCount, int sign)
6367 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6369 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6371 /* Copy the msb into the carry if signed. */
6373 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6383 emitpcode(POC_RRF, popGet(AOP(result),offr));
6385 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6386 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6392 emitpcode(POC_RRF, popGet(AOP(result),offr));
6394 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6395 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6398 emitpcode(POC_RRF, popGet(AOP(result),offr));
6403 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6405 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6406 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6409 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6410 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6411 emitpcode(POC_ANDLW, popGetLit(0x1f));
6412 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6416 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6417 emitpcode(POC_ANDLW, popGetLit(0x0f));
6418 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6423 emitpcode(POC_ANDLW, popGetLit(0x0f));
6424 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6426 emitpcode(POC_RRF, popGet(AOP(result),offr));
6431 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6432 emitpcode(POC_ANDLW, popGetLit(0x80));
6433 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6434 emitpcode(POC_RLF, popGet(AOP(result),offr));
6435 emitpcode(POC_RLF, popGet(AOP(result),offr));
6440 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6441 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6442 emitpcode(POC_RLF, popGet(AOP(result),offr));
6451 /*-----------------------------------------------------------------*/
6452 /* shiftL1Left2Result - shift left one byte from left to result */
6453 /*-----------------------------------------------------------------*/
6454 static void shiftL1Left2Result (operand *left, int offl,
6455 operand *result, int offr, int shCount)
6460 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6462 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6463 DEBUGpic14_emitcode ("; ***","same = %d",same);
6464 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6466 /* shift left accumulator */
6467 //AccLsh(shCount); // don't comment out just yet...
6468 // aopPut(AOP(result),"a",offr);
6472 /* Shift left 1 bit position */
6473 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6475 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6477 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6478 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6482 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6483 emitpcode(POC_ANDLW,popGetLit(0x7e));
6484 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6485 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6488 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6489 emitpcode(POC_ANDLW,popGetLit(0x3e));
6490 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6491 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6492 emitpcode(POC_RLF, popGet(AOP(result),offr));
6495 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6496 emitpcode(POC_ANDLW, popGetLit(0xf0));
6497 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6500 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6501 emitpcode(POC_ANDLW, popGetLit(0xf0));
6502 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6503 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6506 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6507 emitpcode(POC_ANDLW, popGetLit(0x30));
6508 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6509 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6510 emitpcode(POC_RLF, popGet(AOP(result),offr));
6513 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6514 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6515 emitpcode(POC_RRF, popGet(AOP(result),offr));
6519 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6524 /*-----------------------------------------------------------------*/
6525 /* movLeft2Result - move byte from left to result */
6526 /*-----------------------------------------------------------------*/
6527 static void movLeft2Result (operand *left, int offl,
6528 operand *result, int offr)
6531 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6532 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6533 l = aopGet(AOP(left),offl,FALSE,FALSE);
6535 if (*l == '@' && (IS_AOP_PREG(result))) {
6536 pic14_emitcode("mov","a,%s",l);
6537 aopPut(AOP(result),"a",offr);
6539 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6540 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6545 /*-----------------------------------------------------------------*/
6546 /* shiftL2Left2Result - shift left two bytes from left to result */
6547 /*-----------------------------------------------------------------*/
6548 static void shiftL2Left2Result (operand *left, int offl,
6549 operand *result, int offr, int shCount)
6553 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6555 if(pic14_sameRegs(AOP(result), AOP(left))) {
6563 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6564 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6565 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6569 emitpcode(POC_RLF, popGet(AOP(result),offr));
6570 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6576 emitpcode(POC_MOVLW, popGetLit(0x0f));
6577 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6578 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6579 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6580 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6581 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6582 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6584 emitpcode(POC_RLF, popGet(AOP(result),offr));
6585 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6589 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6590 emitpcode(POC_RRF, popGet(AOP(result),offr));
6591 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6592 emitpcode(POC_RRF, popGet(AOP(result),offr));
6593 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6594 emitpcode(POC_ANDLW,popGetLit(0xc0));
6595 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6596 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6597 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6598 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6601 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6602 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6603 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6604 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6605 emitpcode(POC_RRF, popGet(AOP(result),offr));
6615 /* note, use a mov/add for the shift since the mov has a
6616 chance of getting optimized out */
6617 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6618 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6619 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6620 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6621 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6625 emitpcode(POC_RLF, popGet(AOP(result),offr));
6626 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6632 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6633 emitpcode(POC_ANDLW, popGetLit(0xF0));
6634 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6635 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6636 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6637 emitpcode(POC_ANDLW, popGetLit(0xF0));
6638 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6639 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6643 emitpcode(POC_RLF, popGet(AOP(result),offr));
6644 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6648 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6649 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6650 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6651 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6653 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6654 emitpcode(POC_RRF, popGet(AOP(result),offr));
6655 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6656 emitpcode(POC_ANDLW,popGetLit(0xc0));
6657 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6658 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6659 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6660 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6663 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6664 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6665 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6666 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6667 emitpcode(POC_RRF, popGet(AOP(result),offr));
6672 /*-----------------------------------------------------------------*/
6673 /* shiftR2Left2Result - shift right two bytes from left to result */
6674 /*-----------------------------------------------------------------*/
6675 static void shiftR2Left2Result (operand *left, int offl,
6676 operand *result, int offr,
6677 int shCount, int sign)
6681 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6682 same = pic14_sameRegs(AOP(result), AOP(left));
6684 if(same && ((offl + MSB16) == offr)){
6686 /* don't crash result[offr] */
6687 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6688 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6691 movLeft2Result(left,offl, result, offr);
6692 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6695 /* a:x >> shCount (x = lsb(result))*/
6698 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6700 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6709 emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16));
6714 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6715 emitpcode(POC_RRF,popGet(AOP(result),offr));
6717 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6718 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6719 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6720 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6725 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6728 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6729 emitpcode(POC_RRF,popGet(AOP(result),offr));
6736 emitpcode(POC_MOVLW, popGetLit(0xf0));
6737 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6738 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6740 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6741 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6742 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6743 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6745 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6746 emitpcode(POC_ANDLW, popGetLit(0x0f));
6747 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6749 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6750 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6751 emitpcode(POC_ANDLW, popGetLit(0xf0));
6752 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6753 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6757 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6758 emitpcode(POC_RRF, popGet(AOP(result),offr));
6762 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6763 emitpcode(POC_BTFSC,
6764 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6765 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6773 emitpcode(POC_RLF, popGet(AOP(result),offr));
6774 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6776 emitpcode(POC_RLF, popGet(AOP(result),offr));
6777 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6778 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6779 emitpcode(POC_ANDLW,popGetLit(0x03));
6781 emitpcode(POC_BTFSC,
6782 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6783 emitpcode(POC_IORLW,popGetLit(0xfc));
6785 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6786 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6787 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6788 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6790 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6791 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6792 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6793 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6794 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6795 emitpcode(POC_RLF, popGet(AOP(result),offr));
6796 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6797 emitpcode(POC_ANDLW,popGetLit(0x03));
6799 emitpcode(POC_BTFSC,
6800 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6801 emitpcode(POC_IORLW,popGetLit(0xfc));
6803 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6804 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6811 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6812 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6813 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6814 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6817 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6819 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6824 /*-----------------------------------------------------------------*/
6825 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6826 /*-----------------------------------------------------------------*/
6827 static void shiftLLeftOrResult (operand *left, int offl,
6828 operand *result, int offr, int shCount)
6830 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6831 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6832 /* shift left accumulator */
6833 AccLsh(left,offl,shCount);
6834 /* or with result */
6835 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6836 /* back to result */
6837 aopPut(AOP(result),"a",offr);
6840 /*-----------------------------------------------------------------*/
6841 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6842 /*-----------------------------------------------------------------*/
6843 static void shiftRLeftOrResult (operand *left, int offl,
6844 operand *result, int offr, int shCount)
6846 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6847 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6848 /* shift right accumulator */
6849 AccRsh(left,offl,shCount);
6850 /* or with result */
6851 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6852 /* back to result */
6853 aopPut(AOP(result),"a",offr);
6856 /*-----------------------------------------------------------------*/
6857 /* genlshOne - left shift a one byte quantity by known count */
6858 /*-----------------------------------------------------------------*/
6859 static void genlshOne (operand *result, operand *left, int shCount)
6861 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6862 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6865 /*-----------------------------------------------------------------*/
6866 /* genlshTwo - left shift two bytes by known amount != 0 */
6867 /*-----------------------------------------------------------------*/
6868 static void genlshTwo (operand *result,operand *left, int shCount)
6872 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6873 size = pic14_getDataSize(result);
6875 /* if shCount >= 8 */
6881 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6883 movLeft2Result(left, LSB, result, MSB16);
6885 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6888 /* 1 <= shCount <= 7 */
6891 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6893 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6897 /*-----------------------------------------------------------------*/
6898 /* shiftLLong - shift left one long from left to result */
6899 /* offl = LSB or MSB16 */
6900 /*-----------------------------------------------------------------*/
6901 static void shiftLLong (operand *left, operand *result, int offr )
6904 int size = AOP_SIZE(result);
6906 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6907 if(size >= LSB+offr){
6908 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6910 pic14_emitcode("add","a,acc");
6911 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6912 size >= MSB16+offr && offr != LSB )
6913 pic14_emitcode("xch","a,%s",
6914 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6916 aopPut(AOP(result),"a",LSB+offr);
6919 if(size >= MSB16+offr){
6920 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6921 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6924 pic14_emitcode("rlc","a");
6925 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6926 size >= MSB24+offr && offr != LSB)
6927 pic14_emitcode("xch","a,%s",
6928 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6930 aopPut(AOP(result),"a",MSB16+offr);
6933 if(size >= MSB24+offr){
6934 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6935 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6938 pic14_emitcode("rlc","a");
6939 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6940 size >= MSB32+offr && offr != LSB )
6941 pic14_emitcode("xch","a,%s",
6942 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6944 aopPut(AOP(result),"a",MSB24+offr);
6947 if(size > MSB32+offr){
6948 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6949 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6952 pic14_emitcode("rlc","a");
6953 aopPut(AOP(result),"a",MSB32+offr);
6956 aopPut(AOP(result),zero,LSB);
6959 /*-----------------------------------------------------------------*/
6960 /* genlshFour - shift four byte by a known amount != 0 */
6961 /*-----------------------------------------------------------------*/
6962 static void genlshFour (operand *result, operand *left, int shCount)
6966 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6967 size = AOP_SIZE(result);
6969 /* if shifting more that 3 bytes */
6970 if (shCount >= 24 ) {
6973 /* lowest order of left goes to the highest
6974 order of the destination */
6975 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6977 movLeft2Result(left, LSB, result, MSB32);
6978 aopPut(AOP(result),zero,LSB);
6979 aopPut(AOP(result),zero,MSB16);
6980 aopPut(AOP(result),zero,MSB32);
6984 /* more than two bytes */
6985 else if ( shCount >= 16 ) {
6986 /* lower order two bytes goes to higher order two bytes */
6988 /* if some more remaining */
6990 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
6992 movLeft2Result(left, MSB16, result, MSB32);
6993 movLeft2Result(left, LSB, result, MSB24);
6995 aopPut(AOP(result),zero,MSB16);
6996 aopPut(AOP(result),zero,LSB);
7000 /* if more than 1 byte */
7001 else if ( shCount >= 8 ) {
7002 /* lower order three bytes goes to higher order three bytes */
7006 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7008 movLeft2Result(left, LSB, result, MSB16);
7010 else{ /* size = 4 */
7012 movLeft2Result(left, MSB24, result, MSB32);
7013 movLeft2Result(left, MSB16, result, MSB24);
7014 movLeft2Result(left, LSB, result, MSB16);
7015 aopPut(AOP(result),zero,LSB);
7017 else if(shCount == 1)
7018 shiftLLong(left, result, MSB16);
7020 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7021 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7022 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7023 aopPut(AOP(result),zero,LSB);
7028 /* 1 <= shCount <= 7 */
7029 else if(shCount <= 2){
7030 shiftLLong(left, result, LSB);
7032 shiftLLong(result, result, LSB);
7034 /* 3 <= shCount <= 7, optimize */
7036 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7037 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7038 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7042 /*-----------------------------------------------------------------*/
7043 /* genLeftShiftLiteral - left shifting by known count */
7044 /*-----------------------------------------------------------------*/
7045 static void genLeftShiftLiteral (operand *left,
7050 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7053 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7054 freeAsmop(right,NULL,ic,TRUE);
7056 aopOp(left,ic,FALSE);
7057 aopOp(result,ic,FALSE);
7059 size = getSize(operandType(result));
7062 pic14_emitcode("; shift left ","result %d, left %d",size,
7066 /* I suppose that the left size >= result size */
7069 movLeft2Result(left, size, result, size);
7073 else if(shCount >= (size * 8))
7075 aopPut(AOP(result),zero,size);
7079 genlshOne (result,left,shCount);
7084 genlshTwo (result,left,shCount);
7088 genlshFour (result,left,shCount);
7092 freeAsmop(left,NULL,ic,TRUE);
7093 freeAsmop(result,NULL,ic,TRUE);
7096 /*-----------------------------------------------------------------*
7097 * genMultiAsm - repeat assembly instruction for size of register.
7098 * if endian == 1, then the high byte (i.e base address + size of
7099 * register) is used first else the low byte is used first;
7100 *-----------------------------------------------------------------*/
7101 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7106 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7119 emitpcode(poc, popGet(AOP(reg),offset));
7124 /*-----------------------------------------------------------------*/
7125 /* genLeftShift - generates code for left shifting */
7126 /*-----------------------------------------------------------------*/
7127 static void genLeftShift (iCode *ic)
7129 operand *left,*right, *result;
7131 unsigned long lit = 0L;
7133 symbol *tlbl , *tlbl1;
7136 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7138 right = IC_RIGHT(ic);
7140 result = IC_RESULT(ic);
7142 aopOp(right,ic,FALSE);
7144 /* if the shift count is known then do it
7145 as efficiently as possible */
7146 if (AOP_TYPE(right) == AOP_LIT) {
7147 genLeftShiftLiteral (left,right,result,ic);
7151 /* shift count is unknown then we have to form
7152 a loop get the loop count in B : Note: we take
7153 only the lower order byte since shifting
7154 more that 32 bits make no sense anyway, ( the
7155 largest size of an object can be only 32 bits ) */
7158 aopOp(left,ic,FALSE);
7159 aopOp(result,ic,FALSE);
7161 /* now move the left to the result if they are not the
7163 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7164 AOP_SIZE(result) > 1) {
7166 size = AOP_SIZE(result);
7169 l = aopGet(AOP(left),offset,FALSE,TRUE);
7170 if (*l == '@' && (IS_AOP_PREG(result))) {
7172 pic14_emitcode("mov","a,%s",l);
7173 aopPut(AOP(result),"a",offset);
7175 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7176 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7177 //aopPut(AOP(result),l,offset);
7183 if(AOP_TYPE(left) == AOP_LIT)
7184 lit = (unsigned long)floatFromVal (AOP(left)->aopu.aop_lit);
7186 size = AOP_SIZE(result);
7188 /* if it is only one byte then */
7190 if(optimized_for_speed && AOP_TYPE(left)!=AOP_LIT) {
7191 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7192 emitpcode(POC_ANDLW, popGetLit(0xf0));
7193 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7194 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7195 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7196 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7197 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7198 emitpcode(POC_RLFW, popGet(AOP(result),0));
7199 emitpcode(POC_ANDLW, popGetLit(0xfe));
7200 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7201 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7202 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7205 tlbl = newiTempLabel(NULL);
7206 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7207 if (AOP_TYPE(left) == AOP_LIT)
7208 emitpcode(POC_MOVLW, popGetLit(lit));
7210 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7211 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7214 emitpcode(POC_COMFW, popGet(AOP(right),0));
7215 emitpcode(POC_RRF, popGet(AOP(result),0));
7216 emitpLabel(tlbl->key);
7217 emitpcode(POC_RLF, popGet(AOP(result),0));
7218 emitpcode(POC_ADDLW, popGetLit(1));
7220 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7225 if (pic14_sameRegs(AOP(left),AOP(result))) {
7227 tlbl = newiTempLabel(NULL);
7228 emitpcode(POC_COMFW, popGet(AOP(right),0));
7229 genMultiAsm(POC_RRF, result, size,1);
7230 emitpLabel(tlbl->key);
7231 genMultiAsm(POC_RLF, result, size,0);
7232 emitpcode(POC_ADDLW, popGetLit(1));
7234 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7238 //tlbl = newiTempLabel(NULL);
7240 //tlbl1 = newiTempLabel(NULL);
7242 //reAdjustPreg(AOP(result));
7244 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7245 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7246 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7248 //pic14_emitcode("add","a,acc");
7249 //aopPut(AOP(result),"a",offset++);
7251 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7253 // pic14_emitcode("rlc","a");
7254 // aopPut(AOP(result),"a",offset++);
7256 //reAdjustPreg(AOP(result));
7258 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7259 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7262 tlbl = newiTempLabel(NULL);
7263 tlbl1= newiTempLabel(NULL);
7265 size = AOP_SIZE(result);
7268 pctemp = popGetTempReg(); /* grab a temporary working register. */
7270 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7272 /* offset should be 0, 1 or 3 */
7273 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7275 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7277 emitpcode(POC_MOVWF, pctemp);
7280 emitpLabel(tlbl->key);
7283 emitpcode(POC_RLF, popGet(AOP(result),0));
7285 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7287 emitpcode(POC_DECFSZ, pctemp);
7288 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7289 emitpLabel(tlbl1->key);
7291 popReleaseTempReg(pctemp);
7295 freeAsmop (right,NULL,ic,TRUE);
7296 freeAsmop(left,NULL,ic,TRUE);
7297 freeAsmop(result,NULL,ic,TRUE);
7300 /*-----------------------------------------------------------------*/
7301 /* genrshOne - right shift a one byte quantity by known count */
7302 /*-----------------------------------------------------------------*/
7303 static void genrshOne (operand *result, operand *left,
7304 int shCount, int sign)
7306 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7307 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7310 /*-----------------------------------------------------------------*/
7311 /* genrshTwo - right shift two bytes by known amount != 0 */
7312 /*-----------------------------------------------------------------*/
7313 static void genrshTwo (operand *result,operand *left,
7314 int shCount, int sign)
7316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7317 /* if shCount >= 8 */
7321 shiftR1Left2Result(left, MSB16, result, LSB,
7324 movLeft2Result(left, MSB16, result, LSB);
7326 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7329 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7330 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7334 /* 1 <= shCount <= 7 */
7336 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7339 /*-----------------------------------------------------------------*/
7340 /* shiftRLong - shift right one long from left to result */
7341 /* offl = LSB or MSB16 */
7342 /*-----------------------------------------------------------------*/
7343 static void shiftRLong (operand *left, int offl,
7344 operand *result, int sign)
7346 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7348 pic14_emitcode("clr","c");
7349 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7351 pic14_emitcode("mov","c,acc.7");
7352 pic14_emitcode("rrc","a");
7353 aopPut(AOP(result),"a",MSB32-offl);
7355 /* add sign of "a" */
7356 addSign(result, MSB32, sign);
7358 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7359 pic14_emitcode("rrc","a");
7360 aopPut(AOP(result),"a",MSB24-offl);
7362 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7363 pic14_emitcode("rrc","a");
7364 aopPut(AOP(result),"a",MSB16-offl);
7367 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7368 pic14_emitcode("rrc","a");
7369 aopPut(AOP(result),"a",LSB);
7373 /*-----------------------------------------------------------------*/
7374 /* genrshFour - shift four byte by a known amount != 0 */
7375 /*-----------------------------------------------------------------*/
7376 static void genrshFour (operand *result, operand *left,
7377 int shCount, int sign)
7379 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7380 /* if shifting more that 3 bytes */
7381 if(shCount >= 24 ) {
7384 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7386 movLeft2Result(left, MSB32, result, LSB);
7388 addSign(result, MSB16, sign);
7390 else if(shCount >= 16){
7393 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7395 movLeft2Result(left, MSB24, result, LSB);
7396 movLeft2Result(left, MSB32, result, MSB16);
7398 addSign(result, MSB24, sign);
7400 else if(shCount >= 8){
7403 shiftRLong(left, MSB16, result, sign);
7404 else if(shCount == 0){
7405 movLeft2Result(left, MSB16, result, LSB);
7406 movLeft2Result(left, MSB24, result, MSB16);
7407 movLeft2Result(left, MSB32, result, MSB24);
7408 addSign(result, MSB32, sign);
7411 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7412 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7413 /* the last shift is signed */
7414 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7415 addSign(result, MSB32, sign);
7418 else{ /* 1 <= shCount <= 7 */
7420 shiftRLong(left, LSB, result, sign);
7422 shiftRLong(result, LSB, result, sign);
7425 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7426 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7427 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7432 /*-----------------------------------------------------------------*/
7433 /* genRightShiftLiteral - right shifting by known count */
7434 /*-----------------------------------------------------------------*/
7435 static void genRightShiftLiteral (operand *left,
7441 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7444 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7445 freeAsmop(right,NULL,ic,TRUE);
7447 aopOp(left,ic,FALSE);
7448 aopOp(result,ic,FALSE);
7451 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7455 lsize = pic14_getDataSize(left);
7456 res_size = pic14_getDataSize(result);
7457 /* test the LEFT size !!! */
7459 /* I suppose that the left size >= result size */
7462 movLeft2Result(left, lsize, result, res_size);
7465 else if(shCount >= (lsize * 8)){
7468 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7470 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7471 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7476 emitpcode(POC_MOVLW, popGetLit(0));
7477 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7478 emitpcode(POC_MOVLW, popGetLit(0xff));
7480 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7485 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7492 genrshOne (result,left,shCount,sign);
7496 genrshTwo (result,left,shCount,sign);
7500 genrshFour (result,left,shCount,sign);
7508 freeAsmop(left,NULL,ic,TRUE);
7509 freeAsmop(result,NULL,ic,TRUE);
7512 /*-----------------------------------------------------------------*/
7513 /* genSignedRightShift - right shift of signed number */
7514 /*-----------------------------------------------------------------*/
7515 static void genSignedRightShift (iCode *ic)
7517 operand *right, *left, *result;
7520 symbol *tlbl, *tlbl1 ;
7523 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7525 /* we do it the hard way put the shift count in b
7526 and loop thru preserving the sign */
7527 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7529 right = IC_RIGHT(ic);
7531 result = IC_RESULT(ic);
7533 aopOp(right,ic,FALSE);
7534 aopOp(left,ic,FALSE);
7535 aopOp(result,ic,FALSE);
7538 if ( AOP_TYPE(right) == AOP_LIT) {
7539 genRightShiftLiteral (left,right,result,ic,1);
7542 /* shift count is unknown then we have to form
7543 a loop get the loop count in B : Note: we take
7544 only the lower order byte since shifting
7545 more that 32 bits make no sense anyway, ( the
7546 largest size of an object can be only 32 bits ) */
7548 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7549 //pic14_emitcode("inc","b");
7550 //freeAsmop (right,NULL,ic,TRUE);
7551 //aopOp(left,ic,FALSE);
7552 //aopOp(result,ic,FALSE);
7554 /* now move the left to the result if they are not the
7556 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7557 AOP_SIZE(result) > 1) {
7559 size = AOP_SIZE(result);
7563 l = aopGet(AOP(left),offset,FALSE,TRUE);
7564 if (*l == '@' && IS_AOP_PREG(result)) {
7565 pic14_emitcode("mov","a,%s",l);
7566 aopPut(AOP(result),"a",offset);
7568 aopPut(AOP(result),l,offset);
7570 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7571 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7577 /* mov the highest order bit to OVR */
7578 tlbl = newiTempLabel(NULL);
7579 tlbl1= newiTempLabel(NULL);
7581 size = AOP_SIZE(result);
7584 pctemp = popGetTempReg(); /* grab a temporary working register. */
7586 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7588 /* offset should be 0, 1 or 3 */
7589 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7591 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7593 emitpcode(POC_MOVWF, pctemp);
7596 emitpLabel(tlbl->key);
7598 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7599 emitpcode(POC_RRF, popGet(AOP(result),offset));
7602 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7605 emitpcode(POC_DECFSZ, pctemp);
7606 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7607 emitpLabel(tlbl1->key);
7609 popReleaseTempReg(pctemp);
7611 size = AOP_SIZE(result);
7613 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7614 pic14_emitcode("rlc","a");
7615 pic14_emitcode("mov","ov,c");
7616 /* if it is only one byte then */
7618 l = aopGet(AOP(left),0,FALSE,FALSE);
7620 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7621 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7622 pic14_emitcode("mov","c,ov");
7623 pic14_emitcode("rrc","a");
7624 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7625 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7626 aopPut(AOP(result),"a",0);
7630 reAdjustPreg(AOP(result));
7631 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7632 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7633 pic14_emitcode("mov","c,ov");
7635 l = aopGet(AOP(result),offset,FALSE,FALSE);
7637 pic14_emitcode("rrc","a");
7638 aopPut(AOP(result),"a",offset--);
7640 reAdjustPreg(AOP(result));
7641 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7642 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7647 freeAsmop(left,NULL,ic,TRUE);
7648 freeAsmop(result,NULL,ic,TRUE);
7649 freeAsmop(right,NULL,ic,TRUE);
7652 /*-----------------------------------------------------------------*/
7653 /* genRightShift - generate code for right shifting */
7654 /*-----------------------------------------------------------------*/
7655 static void genRightShift (iCode *ic)
7657 operand *right, *left, *result;
7661 symbol *tlbl, *tlbl1 ;
7663 /* if signed then we do it the hard way preserve the
7664 sign bit moving it inwards */
7665 retype = getSpec(operandType(IC_RESULT(ic)));
7666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7668 if (!SPEC_USIGN(retype)) {
7669 genSignedRightShift (ic);
7673 /* signed & unsigned types are treated the same : i.e. the
7674 signed is NOT propagated inwards : quoting from the
7675 ANSI - standard : "for E1 >> E2, is equivalent to division
7676 by 2**E2 if unsigned or if it has a non-negative value,
7677 otherwise the result is implementation defined ", MY definition
7678 is that the sign does not get propagated */
7680 right = IC_RIGHT(ic);
7682 result = IC_RESULT(ic);
7684 aopOp(right,ic,FALSE);
7686 /* if the shift count is known then do it
7687 as efficiently as possible */
7688 if (AOP_TYPE(right) == AOP_LIT) {
7689 genRightShiftLiteral (left,right,result,ic, 0);
7693 /* shift count is unknown then we have to form
7694 a loop get the loop count in B : Note: we take
7695 only the lower order byte since shifting
7696 more that 32 bits make no sense anyway, ( the
7697 largest size of an object can be only 32 bits ) */
7699 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7700 pic14_emitcode("inc","b");
7701 aopOp(left,ic,FALSE);
7702 aopOp(result,ic,FALSE);
7704 /* now move the left to the result if they are not the
7706 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7707 AOP_SIZE(result) > 1) {
7709 size = AOP_SIZE(result);
7712 l = aopGet(AOP(left),offset,FALSE,TRUE);
7713 if (*l == '@' && IS_AOP_PREG(result)) {
7715 pic14_emitcode("mov","a,%s",l);
7716 aopPut(AOP(result),"a",offset);
7718 aopPut(AOP(result),l,offset);
7723 tlbl = newiTempLabel(NULL);
7724 tlbl1= newiTempLabel(NULL);
7725 size = AOP_SIZE(result);
7728 /* if it is only one byte then */
7731 tlbl = newiTempLabel(NULL);
7732 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7733 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7734 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7737 emitpcode(POC_COMFW, popGet(AOP(right),0));
7738 emitpcode(POC_RLF, popGet(AOP(result),0));
7739 emitpLabel(tlbl->key);
7740 emitpcode(POC_RRF, popGet(AOP(result),0));
7741 emitpcode(POC_ADDLW, popGetLit(1));
7743 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7748 reAdjustPreg(AOP(result));
7749 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7750 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7753 l = aopGet(AOP(result),offset,FALSE,FALSE);
7755 pic14_emitcode("rrc","a");
7756 aopPut(AOP(result),"a",offset--);
7758 reAdjustPreg(AOP(result));
7760 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7761 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7764 freeAsmop(left,NULL,ic,TRUE);
7765 freeAsmop (right,NULL,ic,TRUE);
7766 freeAsmop(result,NULL,ic,TRUE);
7769 /*-----------------------------------------------------------------*/
7770 /* genUnpackBits - generates code for unpacking bits */
7771 /*-----------------------------------------------------------------*/
7772 static void genUnpackBits (operand *result, operand *left, char *rname, int ptype, iCode *ifx)
7775 int offset = 0; /* result byte offset */
7776 int rsize; /* result size */
7777 int rlen = 0; /* remaining bitfield length */
7778 sym_link *etype; /* bitfield type information */
7779 int blen; /* bitfield length */
7780 int bstr; /* bitfield starting bit within byte */
7782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7783 etype = getSpec(operandType(result));
7784 rsize = getSize (operandType (result));
7785 blen = SPEC_BLEN (etype);
7786 bstr = SPEC_BSTR (etype);
7788 /* single bit field case */
7790 if (ifx) { /* that is for an if statement */
7793 resolveIfx(&rIfx,ifx);
7794 if (ptype == -1) /* direct */
7795 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7797 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7798 emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
7799 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
7803 if (ptype == -1) /* direct */
7804 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7806 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7807 emitpcode(POC_BTFSC,pcop);
7808 emitpcode(POC_BSF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7810 if (ptype == -1) /* direct */
7811 pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
7813 pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
7814 emitpcode(POC_BTFSS,pcop);
7815 emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
7820 /* read the first byte */
7825 // pic14_emitcode("mov","a,@%s",rname);
7826 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
7830 pic14_emitcode("movx","a,@%s",rname);
7834 pic14_emitcode("movx","a,@dptr");
7838 pic14_emitcode("clr","a");
7839 pic14_emitcode("movc","a","@a+dptr");
7843 pic14_emitcode("lcall","__gptrget");
7847 /* if we have bitdisplacement then it fits */
7848 /* into this byte completely or if length is */
7849 /* less than a byte */
7850 if ((shCnt = SPEC_BSTR(etype)) || blen <= 8) {
7852 /* shift right acc */
7853 AccRsh(left,0,shCnt);
7855 pic14_emitcode("anl","a,#0x%02x",
7856 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7857 aopPut(AOP(result),"a",offset);
7861 /* bit field did not fit in a byte */
7862 rlen = SPEC_BLEN(etype) - 8;
7863 aopPut(AOP(result),"a",offset++);
7870 pic14_emitcode("inc","%s",rname);
7871 pic14_emitcode("mov","a,@%s",rname);
7875 pic14_emitcode("inc","%s",rname);
7876 pic14_emitcode("movx","a,@%s",rname);
7880 pic14_emitcode("inc","dptr");
7881 pic14_emitcode("movx","a,@dptr");
7885 pic14_emitcode("clr","a");
7886 pic14_emitcode("inc","dptr");
7887 pic14_emitcode("movc","a","@a+dptr");
7891 pic14_emitcode("inc","dptr");
7892 pic14_emitcode("lcall","__gptrget");
7897 /* if we are done */
7901 aopPut(AOP(result),"a",offset++);
7906 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7907 aopPut(AOP(result),"a",offset);
7914 /*-----------------------------------------------------------------*/
7915 /* genDataPointerGet - generates code when ptr offset is known */
7916 /*-----------------------------------------------------------------*/
7917 static void genDataPointerGet (operand *left,
7921 int size , offset = 0;
7924 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7927 /* optimization - most of the time, left and result are the same
7928 * address, but different types. for the pic code, we could omit
7932 aopOp(result,ic,TRUE);
7934 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7936 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7938 size = AOP_SIZE(result);
7941 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7945 freeAsmop(left,NULL,ic,TRUE);
7946 freeAsmop(result,NULL,ic,TRUE);
7949 /*-----------------------------------------------------------------*/
7950 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7951 /*-----------------------------------------------------------------*/
7952 static void genNearPointerGet (operand *left,
7957 sym_link *ltype = operandType(left);
7958 sym_link *rtype = operandType(result);
7959 sym_link *retype= getSpec(rtype); /* bitfield type information */
7963 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7966 aopOp(left,ic,FALSE);
7968 /* if left is rematerialisable and
7969 result is not bit variable type and
7970 the left is pointer to data space i.e
7971 lower 128 bytes of space */
7972 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7973 !IS_BITVAR(retype) &&
7974 DCL_TYPE(ltype) == POINTER) {
7975 //genDataPointerGet (left,result,ic);
7979 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7980 aopOp (result,ic,FALSE);
7982 /* Check if can access directly instead of via a pointer */
7983 if (PCOP(AOP(left))->type == PO_LITERAL && AOP_SIZE(result) == 1) {
7987 /* If the pointer value is not in a the FSR then need to put it in */
7988 if (!AOP_INPREG(AOP(left)) && !direct) {
7989 /* otherwise get a free pointer register */
7990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7991 if (PCOP(AOP(result))->type == PO_LITERAL)
7992 emitpcode(POC_MOVLW, popGet(AOP(left),0));
7994 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7995 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8000 /* if bitfield then unpack the bits */
8001 if (IS_BITFIELD(retype))
8002 genUnpackBits (result,left,"indf",direct?-1:POINTER,ifxForOp(IC_RESULT(ic),ic));
8004 /* we have can just get the values */
8005 int size = AOP_SIZE(result);
8008 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8012 emitpcode(POC_MOVWF,popGet(AOP(left),0));
8014 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8015 if (AOP_TYPE(result) == AOP_LIT) {
8016 emitpcode(POC_MOVLW,popGet(AOP(result),offset));
8018 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
8020 if (size && !direct)
8021 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8026 /* now some housekeeping stuff */
8028 /* we had to allocate for this iCode */
8029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8030 freeAsmop(NULL,aop,ic,TRUE);
8032 /* we did not allocate which means left
8033 already in a pointer register, then
8034 if size > 0 && this could be used again
8035 we have to point it back to where it
8037 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8038 if (AOP_SIZE(result) > 1 &&
8039 !OP_SYMBOL(left)->remat &&
8040 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8042 int size = AOP_SIZE(result) - 1;
8044 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8049 freeAsmop(left,NULL,ic,TRUE);
8050 freeAsmop(result,NULL,ic,TRUE);
8054 /*-----------------------------------------------------------------*/
8055 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8056 /*-----------------------------------------------------------------*/
8057 static void genPagedPointerGet (operand *left,
8064 sym_link *rtype, *retype;
8066 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8068 rtype = operandType(result);
8069 retype= getSpec(rtype);
8071 aopOp(left,ic,FALSE);
8073 /* if the value is already in a pointer register
8074 then don't need anything more */
8075 if (!AOP_INPREG(AOP(left))) {
8076 /* otherwise get a free pointer register */
8078 preg = getFreePtr(ic,&aop,FALSE);
8079 pic14_emitcode("mov","%s,%s",
8081 aopGet(AOP(left),0,FALSE,TRUE));
8082 rname = preg->name ;
8084 rname = aopGet(AOP(left),0,FALSE,FALSE);
8086 freeAsmop(left,NULL,ic,TRUE);
8087 aopOp (result,ic,FALSE);
8089 /* if bitfield then unpack the bits */
8090 if (IS_BITFIELD(retype))
8091 genUnpackBits (result,left,rname,PPOINTER,0);
8093 /* we have can just get the values */
8094 int size = AOP_SIZE(result);
8099 pic14_emitcode("movx","a,@%s",rname);
8100 aopPut(AOP(result),"a",offset);
8105 pic14_emitcode("inc","%s",rname);
8109 /* now some housekeeping stuff */
8111 /* we had to allocate for this iCode */
8112 freeAsmop(NULL,aop,ic,TRUE);
8114 /* we did not allocate which means left
8115 already in a pointer register, then
8116 if size > 0 && this could be used again
8117 we have to point it back to where it
8119 if (AOP_SIZE(result) > 1 &&
8120 !OP_SYMBOL(left)->remat &&
8121 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8123 int size = AOP_SIZE(result) - 1;
8125 pic14_emitcode("dec","%s",rname);
8130 freeAsmop(result,NULL,ic,TRUE);
8135 /*-----------------------------------------------------------------*/
8136 /* genFarPointerGet - gget value from far space */
8137 /*-----------------------------------------------------------------*/
8138 static void genFarPointerGet (operand *left,
8139 operand *result, iCode *ic)
8142 sym_link *retype = getSpec(operandType(result));
8144 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8146 aopOp(left,ic,FALSE);
8148 /* if the operand is already in dptr
8149 then we do nothing else we move the value to dptr */
8150 if (AOP_TYPE(left) != AOP_STR) {
8151 /* if this is remateriazable */
8152 if (AOP_TYPE(left) == AOP_IMMD)
8153 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8154 else { /* we need to get it byte by byte */
8155 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8156 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8157 if (options.model == MODEL_FLAT24)
8159 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8163 /* so dptr know contains the address */
8164 freeAsmop(left,NULL,ic,TRUE);
8165 aopOp(result,ic,FALSE);
8167 /* if bit then unpack */
8168 if (IS_BITFIELD(retype))
8169 genUnpackBits(result,left,"dptr",FPOINTER,0);
8171 size = AOP_SIZE(result);
8175 pic14_emitcode("movx","a,@dptr");
8176 aopPut(AOP(result),"a",offset++);
8178 pic14_emitcode("inc","dptr");
8182 freeAsmop(result,NULL,ic,TRUE);
8185 /*-----------------------------------------------------------------*/
8186 /* genCodePointerGet - get value from code space */
8187 /*-----------------------------------------------------------------*/
8188 static void genCodePointerGet (operand *left,
8189 operand *result, iCode *ic)
8192 sym_link *retype = getSpec(operandType(result));
8194 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8196 aopOp(left,ic,FALSE);
8198 /* if the operand is already in dptr
8199 then we do nothing else we move the value to dptr */
8200 if (AOP_TYPE(left) != AOP_STR) {
8201 /* if this is remateriazable */
8202 if (AOP_TYPE(left) == AOP_IMMD)
8203 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8204 else { /* we need to get it byte by byte */
8205 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8206 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8207 if (options.model == MODEL_FLAT24)
8209 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8213 /* so dptr know contains the address */
8214 freeAsmop(left,NULL,ic,TRUE);
8215 aopOp(result,ic,FALSE);
8217 /* if bit then unpack */
8218 if (IS_BITFIELD(retype))
8219 genUnpackBits(result,left,"dptr",CPOINTER,0);
8221 size = AOP_SIZE(result);
8225 pic14_emitcode("clr","a");
8226 pic14_emitcode("movc","a,@a+dptr");
8227 aopPut(AOP(result),"a",offset++);
8229 pic14_emitcode("inc","dptr");
8233 freeAsmop(result,NULL,ic,TRUE);
8236 /*-----------------------------------------------------------------*/
8237 /* genGenPointerGet - gget value from generic pointer space */
8238 /*-----------------------------------------------------------------*/
8239 static void genGenPointerGet (operand *left,
8240 operand *result, iCode *ic)
8243 sym_link *retype = getSpec(operandType(result));
8245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8246 aopOp(left,ic,FALSE);
8247 aopOp(result,ic,FALSE);
8250 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8252 /* if the operand is already in dptr
8253 then we do nothing else we move the value to dptr */
8254 // if (AOP_TYPE(left) != AOP_STR) {
8255 /* if this is remateriazable */
8256 if (AOP_TYPE(left) == AOP_IMMD) {
8257 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8258 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8260 else { /* we need to get it byte by byte */
8262 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8263 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8265 size = AOP_SIZE(result);
8269 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8270 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8272 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8277 /* so dptr know contains the address */
8279 /* if bit then unpack */
8280 //if (IS_BITFIELD(retype))
8281 // genUnpackBits(result,"dptr",GPOINTER);
8284 freeAsmop(left,NULL,ic,TRUE);
8285 freeAsmop(result,NULL,ic,TRUE);
8289 /*-----------------------------------------------------------------*/
8290 /* genConstPointerGet - get value from const generic pointer space */
8291 /*-----------------------------------------------------------------*/
8292 static void genConstPointerGet (operand *left,
8293 operand *result, iCode *ic)
8295 //sym_link *retype = getSpec(operandType(result));
8296 symbol *albl = newiTempLabel(NULL);
8297 symbol *blbl = newiTempLabel(NULL);
8301 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8302 aopOp(left,ic,FALSE);
8303 aopOp(result,ic,FALSE);
8306 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8308 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8310 emitpcode(POC_CALL,popGetLabel(albl->key));
8311 pcop = popGetLabel(blbl->key);
8312 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8313 emitpcode(POC_GOTO,pcop);
8314 emitpLabel(albl->key);
8316 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8318 emitpcode(poc,popGet(AOP(left),1));
8319 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8320 emitpcode(poc,popGet(AOP(left),0));
8321 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8323 emitpLabel(blbl->key);
8325 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8328 freeAsmop(left,NULL,ic,TRUE);
8329 freeAsmop(result,NULL,ic,TRUE);
8332 /*-----------------------------------------------------------------*/
8333 /* genPointerGet - generate code for pointer get */
8334 /*-----------------------------------------------------------------*/
8335 static void genPointerGet (iCode *ic)
8337 operand *left, *result ;
8338 sym_link *type, *etype;
8341 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8344 result = IC_RESULT(ic) ;
8346 /* depending on the type of pointer we need to
8347 move it to the correct pointer register */
8348 type = operandType(left);
8349 etype = getSpec(type);
8351 if (IS_PTR_CONST(type))
8352 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8354 /* if left is of type of pointer then it is simple */
8355 if (IS_PTR(type) && !IS_FUNC(type->next))
8356 p_type = DCL_TYPE(type);
8358 /* we have to go by the storage class */
8359 p_type = PTR_TYPE(SPEC_OCLS(etype));
8361 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8363 if (SPEC_OCLS(etype)->codesp ) {
8364 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8365 //p_type = CPOINTER ;
8368 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8369 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8370 /*p_type = FPOINTER ;*/
8372 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8373 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8374 /* p_type = PPOINTER; */
8376 if (SPEC_OCLS(etype) == idata )
8377 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8378 /* p_type = IPOINTER; */
8380 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8381 /* p_type = POINTER ; */
8384 /* now that we have the pointer type we assign
8385 the pointer values */
8390 genNearPointerGet (left,result,ic);
8394 genPagedPointerGet(left,result,ic);
8398 genFarPointerGet (left,result,ic);
8402 genConstPointerGet (left,result,ic);
8403 //pic14_emitcodePointerGet (left,result,ic);
8407 if (IS_PTR_CONST(type))
8408 genConstPointerGet (left,result,ic);
8410 genGenPointerGet (left,result,ic);
8416 /*-----------------------------------------------------------------*/
8417 /* emitPtrByteGet - for legacy 8051 emits code to get a byte into */
8418 /* A through a pointer register (R0, R1, or DPTR). The original */
8419 /* value of A can be preserved in B. */
8420 /* PIC has to use INDF register. */
8421 /*-----------------------------------------------------------------*/
8423 emitPtrByteGet (char *rname, int p_type, bool preserveAinB)
8430 pic14_emitcode ("mov", "b,a");
8431 // pic14_emitcode ("mov", "a,@%s", rname);
8432 emitpcode(POC_MOVFW, popCopyReg(&pc_indf));
8437 pic14_emitcode ("mov", "b,a");
8438 pic14_emitcode ("movx", "a,@%s", rname);
8443 pic14_emitcode ("mov", "b,a");
8444 pic14_emitcode ("movx", "a,@dptr");
8449 pic14_emitcode ("mov", "b,a");
8450 pic14_emitcode ("clr", "a");
8451 pic14_emitcode ("movc", "a,@a+dptr");
8457 pic14_emitcode ("push", "b");
8458 pic14_emitcode ("push", "acc");
8460 pic14_emitcode ("lcall", "__gptrget");
8462 pic14_emitcode ("pop", "b");
8467 /*-----------------------------------------------------------------*/
8468 /* emitPtrByteSet - emits code to set a byte from src through a */
8469 /* pointer register INDF (legacy 8051 uses R0, R1, or DPTR). */
8470 /*-----------------------------------------------------------------*/
8472 emitPtrByteSet (char *rname, int p_type, char *src)
8481 pic14_emitcode ("mov", "@%s,a", rname);
8484 // pic14_emitcode ("mov", "@%s,%s", rname, src);
8485 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8490 pic14_emitcode ("movx", "@%s,a", rname);
8495 pic14_emitcode ("movx", "@dptr,a");
8500 pic14_emitcode ("lcall", "__gptrput");
8505 /*-----------------------------------------------------------------*/
8506 /* genPackBits - generates code for packed bit storage */
8507 /*-----------------------------------------------------------------*/
8508 static void genPackBits(sym_link *etype,operand *result,operand *right,char *rname,int p_type)
8510 int offset = 0; /* source byte offset */
8511 int rlen = 0; /* remaining bitfield length */
8512 int blen; /* bitfield length */
8513 int bstr; /* bitfield starting bit within byte */
8514 int litval; /* source literal value (if AOP_LIT) */
8515 unsigned char mask; /* bitmask within current byte */
8517 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8519 blen = SPEC_BLEN (etype);
8520 bstr = SPEC_BSTR (etype);
8522 /* If the bitfield length is less than a byte */
8525 mask = ((unsigned char) (0xFF << (blen + bstr)) |
8526 (unsigned char) (0xFF >> (8 - bstr)));
8528 if (AOP_TYPE (right) == AOP_LIT)
8530 /* Case with a bitfield length <8 and literal source
8532 int lit = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8536 if (AOP(result)->type == AOP_PCODE)
8537 pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
8539 pcop = popGet(AOP(result),0);
8540 emitpcode(lit?POC_BSF:POC_BCF,pcop);
8542 emitpcode(lit?POC_BSF:POC_BCF,popCopyReg(&pc_indf));
8546 litval = lit << bstr;
8547 litval &= (~mask) & 0xff;
8549 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8551 emitPtrByteGet (rname, p_type, FALSE);
8552 if ((mask|litval)!=0xff)
8553 emitpcode(POC_ANDLW,popGetLit(mask));
8555 emitpcode(POC_IORLW,popGetLit(litval));
8562 /* Note more efficient code, of pre clearing bit then only setting it if required, can only be done if it is known that the result is not a SFR */
8563 emitpcode(POC_RLF,popGet(AOP(right),0));
8565 emitpcode(POC_BCF,popGet(AOP(result),0));
8567 emitpcode(POC_BSF,popGet(AOP(result),0));
8568 } else if (p_type!=GPOINTER) {
8569 /* Case with a bitfield length == 1 and no generic pointer
8571 if (AOP_TYPE (right) == AOP_CRY)
8572 pic14_emitcode ("mov", "c,%s", AOP(right)->aopu.aop_dir);
8575 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8576 pic14_emitcode ("rrc","a");
8578 emitPtrByteGet (rname, p_type, FALSE);
8579 pic14_emitcode ("mov","acc.%d,c",bstr);
8585 /* Case with a bitfield length < 8 and arbitrary source
8587 MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
8588 /* shift and mask source value */
8589 AccLsh (right,0,bstr);
8590 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8591 emitpcode(POC_ANDLW, popGetLit((~mask) & 0xff));
8593 //pushedB = pushB ();
8595 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8597 emitPtrByteGet (rname, p_type, TRUE);
8599 pic14_emitcode ("anl", "a,#0x%02x", mask);
8600 pic14_emitcode ("orl", "a,b");
8601 emitpcode(POC_ANDLW,popGetLit(mask));
8602 emitpcode(POC_IORFW,popGet(AOP(right),0));
8603 if (p_type == GPOINTER)
8604 pic14_emitcode ("pop", "b");
8611 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8613 emitPtrByteSet (rname, p_type, "a");
8617 /* Bit length is greater than 7 bits. In this case, copy */
8618 /* all except the partial byte at the end */
8619 for (rlen=blen;rlen>=8;rlen-=8)
8621 emitPtrByteSet (rname, p_type,
8622 aopGet (AOP (right), offset++, FALSE, TRUE) );
8624 pic14_emitcode ("inc", "%s", rname);
8627 /* If there was a partial byte at the end */
8630 mask = (((unsigned char) -1 << rlen) & 0xff);
8632 if (AOP_TYPE (right) == AOP_LIT)
8634 /* Case with partial byte and literal source
8636 litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
8637 litval >>= (blen-rlen);
8638 litval &= (~mask) & 0xff;
8639 emitPtrByteGet (rname, p_type, FALSE);
8640 if ((mask|litval)!=0xff)
8641 pic14_emitcode ("anl","a,#0x%02x", mask);
8643 pic14_emitcode ("orl","a,#0x%02x", litval);
8648 /* Case with partial byte and arbitrary source
8650 MOVA (aopGet (AOP (right), offset++, FALSE, FALSE));
8651 pic14_emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
8653 //pushedB = pushB ();
8654 /* transfer A to B and get next byte */
8655 emitPtrByteGet (rname, p_type, TRUE);
8657 pic14_emitcode ("anl", "a,#0x%02x", mask);
8658 pic14_emitcode ("orl", "a,b");
8659 if (p_type == GPOINTER)
8660 pic14_emitcode ("pop", "b");
8664 emitPtrByteSet (rname, p_type, "a");
8669 /*-----------------------------------------------------------------*/
8670 /* SetIrp - Set IRP bit */
8671 /*-----------------------------------------------------------------*/
8672 void SetIrp(operand *result) {
8673 if (AOP_TYPE(result) == AOP_LIT) {
8674 unsigned lit = (unsigned)operandLitValue(result);
8675 emitpcode((lit&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8677 if (PCOP(AOP(result))->type == PO_LITERAL) {
8678 int addrs = PCOL(AOP(result))->lit;
8679 emitpcode((addrs&0x100)?POC_BSF:POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8681 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT)); /* always ensure this is clear as it may have previouly been set */
8682 if(AOP_SIZE(result) > 1) {
8683 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8684 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8690 /*-----------------------------------------------------------------*/
8691 /* genDataPointerSet - remat pointer to data space */
8692 /*-----------------------------------------------------------------*/
8693 static void genDataPointerSet(operand *right,
8697 int size, offset = 0 ;
8698 char *l, buffer[256];
8700 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8701 aopOp(right,ic,FALSE);
8703 l = aopGet(AOP(result),0,FALSE,TRUE);
8704 size = AOP_SIZE(right);
8706 if ( AOP_TYPE(result) == AOP_PCODE) {
8707 fprintf(stderr,"genDataPointerSet %s, %d\n",
8708 AOP(result)->aopu.pcop->name,
8709 PCOI(AOP(result)->aopu.pcop)->offset);
8713 // tsd, was l+1 - the underline `_' prefix was being stripped
8716 sprintf(buffer,"(%s + %d)",l,offset);
8717 fprintf(stderr,"oops %s\n",buffer);
8719 sprintf(buffer,"%s",l);
8721 if (AOP_TYPE(right) == AOP_LIT) {
8722 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8723 lit = lit >> (8*offset);
8725 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8726 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8728 emitpcode(POC_CLRF, popGet(AOP(result),0));
8731 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8732 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8738 freeAsmop(right,NULL,ic,TRUE);
8739 freeAsmop(result,NULL,ic,TRUE);
8742 /*-----------------------------------------------------------------*/
8743 /* genNearPointerSet - pic14_emitcode for near pointer put */
8744 /*-----------------------------------------------------------------*/
8745 static void genNearPointerSet (operand *right,
8750 sym_link *ptype = operandType(result);
8751 sym_link *retype = getSpec(operandType(right));
8752 sym_link *letype = getSpec(ptype);
8756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8757 aopOp(result,ic,FALSE);
8760 /* if the result is rematerializable &
8761 in data space & not a bit variable */
8762 //if (AOP_TYPE(result) == AOP_IMMD &&
8763 if (AOP_TYPE(result) == AOP_PCODE &&
8764 DCL_TYPE(ptype) == POINTER &&
8765 !IS_BITVAR (retype) &&
8766 !IS_BITVAR (letype)) {
8767 genDataPointerSet (right,result,ic);
8768 freeAsmop(result,NULL,ic,TRUE);
8772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8773 aopOp(right,ic,FALSE);
8774 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8776 /* Check if can access directly instead of via a pointer */
8777 if (PCOP(AOP(result))->type == PO_LITERAL && AOP_SIZE(right) == 1) {
8781 /* If the pointer value is not in a the FSR then need to put it in */
8782 if (!AOP_INPREG(AOP(result)) && !direct) {
8783 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8784 if (PCOP(AOP(result))->type == PO_LITERAL)
8785 emitpcode(POC_MOVLW, popGet(AOP(result),0));
8787 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8788 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8791 /* Must set/reset IRP bit for use with FSR. */
8792 /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
8796 /* if bitfield then unpack the bits */
8797 if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
8798 genPackBits ((IS_BITFIELD (retype) ? retype : letype), result, right, "indf", direct?-1:POINTER);
8800 /* we have can just get the values */
8801 int size = AOP_SIZE(right);
8804 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8806 char *l = aopGet(AOP(right),offset,FALSE,TRUE);
8808 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8810 if (AOP_TYPE(right) == AOP_LIT) {
8811 emitpcode(POC_MOVLW,popGet(AOP(right),offset));
8813 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
8816 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8818 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8820 if (size && !direct)
8821 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8826 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8827 /* now some housekeeping stuff */
8829 /* we had to allocate for this iCode */
8830 freeAsmop(NULL,aop,ic,TRUE);
8832 /* we did not allocate which means left
8833 already in a pointer register, then
8834 if size > 0 && this could be used again
8835 we have to point it back to where it
8837 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8838 if (AOP_SIZE(right) > 1 &&
8839 !OP_SYMBOL(result)->remat &&
8840 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8842 int size = AOP_SIZE(right) - 1;
8844 emitpcode(POC_DECF, popCopyReg(&pc_fsr));
8848 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8851 freeAsmop(right,NULL,ic,TRUE);
8852 freeAsmop(result,NULL,ic,TRUE);
8855 /*-----------------------------------------------------------------*/
8856 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8857 /*-----------------------------------------------------------------*/
8858 static void genPagedPointerSet (operand *right,
8867 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8869 retype= getSpec(operandType(right));
8871 aopOp(result,ic,FALSE);
8873 /* if the value is already in a pointer register
8874 then don't need anything more */
8875 if (!AOP_INPREG(AOP(result))) {
8876 /* otherwise get a free pointer register */
8878 preg = getFreePtr(ic,&aop,FALSE);
8879 pic14_emitcode("mov","%s,%s",
8881 aopGet(AOP(result),0,FALSE,TRUE));
8882 rname = preg->name ;
8884 rname = aopGet(AOP(result),0,FALSE,FALSE);
8886 freeAsmop(result,NULL,ic,TRUE);
8887 aopOp (right,ic,FALSE);
8889 /* if bitfield then unpack the bits */
8890 if (IS_BITFIELD(retype))
8891 genPackBits (retype,result,right,rname,PPOINTER);
8893 /* we have can just get the values */
8894 int size = AOP_SIZE(right);
8898 l = aopGet(AOP(right),offset,FALSE,TRUE);
8901 pic14_emitcode("movx","@%s,a",rname);
8904 pic14_emitcode("inc","%s",rname);
8910 /* now some housekeeping stuff */
8912 /* we had to allocate for this iCode */
8913 freeAsmop(NULL,aop,ic,TRUE);
8915 /* we did not allocate which means left
8916 already in a pointer register, then
8917 if size > 0 && this could be used again
8918 we have to point it back to where it
8920 if (AOP_SIZE(right) > 1 &&
8921 !OP_SYMBOL(result)->remat &&
8922 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8924 int size = AOP_SIZE(right) - 1;
8926 pic14_emitcode("dec","%s",rname);
8931 freeAsmop(right,NULL,ic,TRUE);
8936 /*-----------------------------------------------------------------*/
8937 /* genFarPointerSet - set value from far space */
8938 /*-----------------------------------------------------------------*/
8939 static void genFarPointerSet (operand *right,
8940 operand *result, iCode *ic)
8943 sym_link *retype = getSpec(operandType(right));
8945 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8946 aopOp(result,ic,FALSE);
8948 /* if the operand is already in dptr
8949 then we do nothing else we move the value to dptr */
8950 if (AOP_TYPE(result) != AOP_STR) {
8951 /* if this is remateriazable */
8952 if (AOP_TYPE(result) == AOP_IMMD)
8953 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8954 else { /* we need to get it byte by byte */
8955 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8956 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8957 if (options.model == MODEL_FLAT24)
8959 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8963 /* so dptr know contains the address */
8964 freeAsmop(result,NULL,ic,TRUE);
8965 aopOp(right,ic,FALSE);
8967 /* if bit then unpack */
8968 if (IS_BITFIELD(retype))
8969 genPackBits(retype,result,right,"dptr",FPOINTER);
8971 size = AOP_SIZE(right);
8975 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8977 pic14_emitcode("movx","@dptr,a");
8979 pic14_emitcode("inc","dptr");
8983 freeAsmop(right,NULL,ic,TRUE);
8986 /*-----------------------------------------------------------------*/
8987 /* genGenPointerSet - set value from generic pointer space */
8988 /*-----------------------------------------------------------------*/
8989 static void genGenPointerSet (operand *right,
8990 operand *result, iCode *ic)
8992 sym_link *ptype = operandType(result);
8993 sym_link *retype = getSpec(operandType(right));
8994 sym_link *letype = getSpec (ptype);
8996 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8998 aopOp(result,ic,FALSE);
8999 aopOp(right,ic,FALSE);
9001 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9003 /* if the operand is already in dptr
9004 then we do nothing else we move the value to dptr */
9005 if (AOP_TYPE(result) != AOP_STR) {
9006 /* if this is remateriazable */
9007 if (AOP_TYPE(result) == AOP_IMMD) {
9008 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
9009 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
9012 emitpcode(POC_MOVFW,popGet(AOP(result),0));
9013 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9015 /* Must set/reset IRP bit for use with FSR. */
9016 /* Note only do this once - assuming that never need to cross a bank boundary at address 0x100. */
9021 /* if bitfield then unpack the bits */
9022 if (IS_BITFIELD (retype) || IS_BITFIELD (letype)) {
9023 genPackBits ((IS_BITFIELD (retype) ? retype : letype),result, right, "indf", POINTER);
9025 /* we have can just get the values */
9026 int size = AOP_SIZE(right);
9029 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9031 char *l = aopGet(AOP(right),offset,FALSE,TRUE);
9033 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
9035 if (AOP_TYPE(right) == AOP_LIT) {
9036 emitpcode(POC_MOVLW,popGet(AOP(right),offset));
9038 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
9040 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9043 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9048 freeAsmop(right,NULL,ic,TRUE);
9049 freeAsmop(result,NULL,ic,TRUE);
9052 /*-----------------------------------------------------------------*/
9053 /* genPointerSet - stores the value into a pointer location */
9054 /*-----------------------------------------------------------------*/
9055 static void genPointerSet (iCode *ic)
9057 operand *right, *result ;
9058 sym_link *type, *etype;
9061 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9063 right = IC_RIGHT(ic);
9064 result = IC_RESULT(ic) ;
9066 /* depending on the type of pointer we need to
9067 move it to the correct pointer register */
9068 type = operandType(result);
9069 etype = getSpec(type);
9070 /* if left is of type of pointer then it is simple */
9071 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9072 p_type = DCL_TYPE(type);
9075 /* we have to go by the storage class */
9076 p_type = PTR_TYPE(SPEC_OCLS(etype));
9078 /* if (SPEC_OCLS(etype)->codesp ) { */
9079 /* p_type = CPOINTER ; */
9082 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9083 /* p_type = FPOINTER ; */
9085 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9086 /* p_type = PPOINTER ; */
9088 /* if (SPEC_OCLS(etype) == idata ) */
9089 /* p_type = IPOINTER ; */
9091 /* p_type = POINTER ; */
9094 /* now that we have the pointer type we assign
9095 the pointer values */
9100 genNearPointerSet (right,result,ic);
9104 genPagedPointerSet (right,result,ic);
9108 genFarPointerSet (right,result,ic);
9112 genGenPointerSet (right,result,ic);
9116 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9117 "genPointerSet: illegal pointer type");
9121 /*-----------------------------------------------------------------*/
9122 /* genIfx - generate code for Ifx statement */
9123 /*-----------------------------------------------------------------*/
9124 static void genIfx (iCode *ic, iCode *popIc)
9126 operand *cond = IC_COND(ic);
9129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9131 aopOp(cond,ic,FALSE);
9133 /* get the value into acc */
9134 if (AOP_TYPE(cond) != AOP_CRY)
9135 pic14_toBoolean(cond);
9138 /* the result is now in the accumulator */
9139 freeAsmop(cond,NULL,ic,TRUE);
9141 /* if there was something to be popped then do it */
9145 /* if the condition is a bit variable */
9146 if (isbit && IS_ITEMP(cond) &&
9148 genIfxJump(ic,SPIL_LOC(cond)->rname);
9149 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9152 if (isbit && !IS_ITEMP(cond))
9153 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9161 /*-----------------------------------------------------------------*/
9162 /* genAddrOf - generates code for address of */
9163 /*-----------------------------------------------------------------*/
9164 static void genAddrOf (iCode *ic)
9166 operand *right, *result, *left;
9169 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9172 //aopOp(IC_RESULT(ic),ic,FALSE);
9174 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9175 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9176 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9178 DEBUGpic14_AopType(__LINE__,left,right,result);
9180 size = AOP_SIZE(IC_RESULT(ic));
9184 /* fixing bug #863624, reported from (errolv) */
9185 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9186 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9189 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9190 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9195 freeAsmop(left,NULL,ic,FALSE);
9196 freeAsmop(result,NULL,ic,TRUE);
9201 /*-----------------------------------------------------------------*/
9202 /* genFarFarAssign - assignment when both are in far space */
9203 /*-----------------------------------------------------------------*/
9204 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9206 int size = AOP_SIZE(right);
9209 /* first push the right side on to the stack */
9211 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9213 pic14_emitcode ("push","acc");
9216 freeAsmop(right,NULL,ic,FALSE);
9217 /* now assign DPTR to result */
9218 aopOp(result,ic,FALSE);
9219 size = AOP_SIZE(result);
9221 pic14_emitcode ("pop","acc");
9222 aopPut(AOP(result),"a",--offset);
9224 freeAsmop(result,NULL,ic,FALSE);
9229 /*-----------------------------------------------------------------*/
9230 /* genAssign - generate code for assignment */
9231 /*-----------------------------------------------------------------*/
9232 static void genAssign (iCode *ic)
9234 operand *result, *right;
9235 int size, offset,know_W;
9236 unsigned long lit = 0L;
9238 result = IC_RESULT(ic);
9239 right = IC_RIGHT(ic) ;
9241 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9243 /* if they are the same */
9244 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9247 aopOp(right,ic,FALSE);
9248 aopOp(result,ic,TRUE);
9250 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9252 /* if they are the same registers */
9253 if (pic14_sameRegs(AOP(right),AOP(result)))
9256 /* if the result is a bit */
9257 if (AOP_TYPE(result) == AOP_CRY) {
9259 /* if the right size is a literal then
9260 we know what the value is */
9261 if (AOP_TYPE(right) == AOP_LIT) {
9263 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9264 popGet(AOP(result),0));
9266 if (((int) operandLitValue(right)))
9267 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9268 AOP(result)->aopu.aop_dir,
9269 AOP(result)->aopu.aop_dir);
9271 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9272 AOP(result)->aopu.aop_dir,
9273 AOP(result)->aopu.aop_dir);
9277 /* the right is also a bit variable */
9278 if (AOP_TYPE(right) == AOP_CRY) {
9279 emitpcode(POC_BCF, popGet(AOP(result),0));
9280 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9281 emitpcode(POC_BSF, popGet(AOP(result),0));
9283 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9284 AOP(result)->aopu.aop_dir,
9285 AOP(result)->aopu.aop_dir);
9286 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9287 AOP(right)->aopu.aop_dir,
9288 AOP(right)->aopu.aop_dir);
9289 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9290 AOP(result)->aopu.aop_dir,
9291 AOP(result)->aopu.aop_dir);
9296 emitpcode(POC_BCF, popGet(AOP(result),0));
9297 pic14_toBoolean(right);
9299 emitpcode(POC_BSF, popGet(AOP(result),0));
9300 //aopPut(AOP(result),"a",0);
9304 /* bit variables done */
9306 size = AOP_SIZE(result);
9308 if(AOP_TYPE(right) == AOP_LIT)
9309 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9311 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9313 if(aopIdx(AOP(result),0) == 4) {
9314 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9315 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9316 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9319 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9324 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9325 if(AOP_TYPE(right) == AOP_LIT) {
9327 if(know_W != (int)(lit&0xff))
9328 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9330 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9332 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9336 } else if (AOP_TYPE(right) == AOP_CRY) {
9337 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9339 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9340 emitpcode(POC_INCF, popGet(AOP(result),0));
9343 mov2w (AOP(right), offset);
9344 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9352 freeAsmop (right,NULL,ic,FALSE);
9353 freeAsmop (result,NULL,ic,TRUE);
9356 /*-----------------------------------------------------------------*/
9357 /* genJumpTab - genrates code for jump table */
9358 /*-----------------------------------------------------------------*/
9359 static void genJumpTab (iCode *ic)
9364 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9366 aopOp(IC_JTCOND(ic),ic,FALSE);
9367 /* get the condition into accumulator */
9368 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9370 /* multiply by three */
9371 pic14_emitcode("add","a,acc");
9372 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9374 jtab = newiTempLabel(NULL);
9375 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9376 pic14_emitcode("jmp","@a+dptr");
9377 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9379 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9380 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9381 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9382 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9384 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9385 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9386 emitpLabel(jtab->key);
9388 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9390 /* now generate the jump labels */
9391 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9392 jtab = setNextItem(IC_JTLABELS(ic))) {
9393 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9394 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9400 /*-----------------------------------------------------------------*/
9401 /* genMixedOperation - gen code for operators between mixed types */
9402 /*-----------------------------------------------------------------*/
9404 TSD - Written for the PIC port - but this unfortunately is buggy.
9405 This routine is good in that it is able to efficiently promote
9406 types to different (larger) sizes. Unfortunately, the temporary
9407 variables that are optimized out by this routine are sometimes
9408 used in other places. So until I know how to really parse the
9409 iCode tree, I'm going to not be using this routine :(.
9411 static int genMixedOperation (iCode *ic)
9414 operand *result = IC_RESULT(ic);
9415 sym_link *ctype = operandType(IC_LEFT(ic));
9416 operand *right = IC_RIGHT(ic);
9422 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9424 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9430 nextright = IC_RIGHT(nextic);
9431 nextleft = IC_LEFT(nextic);
9432 nextresult = IC_RESULT(nextic);
9434 aopOp(right,ic,FALSE);
9435 aopOp(result,ic,FALSE);
9436 aopOp(nextright, nextic, FALSE);
9437 aopOp(nextleft, nextic, FALSE);
9438 aopOp(nextresult, nextic, FALSE);
9440 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9446 pic14_emitcode(";remove right +","");
9448 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9454 pic14_emitcode(";remove left +","");
9458 big = AOP_SIZE(nextleft);
9459 small = AOP_SIZE(nextright);
9461 switch(nextic->op) {
9464 pic14_emitcode(";optimize a +","");
9465 /* if unsigned or not an integral type */
9466 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9467 pic14_emitcode(";add a bit to something","");
9470 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9472 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9473 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9474 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9476 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9484 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9485 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9486 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9489 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9491 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9492 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9493 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9494 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9495 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9498 pic14_emitcode("rlf","known_zero,w");
9505 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9506 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9507 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9509 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9519 freeAsmop(right,NULL,ic,TRUE);
9520 freeAsmop(result,NULL,ic,TRUE);
9521 freeAsmop(nextright,NULL,ic,TRUE);
9522 freeAsmop(nextleft,NULL,ic,TRUE);
9524 nextic->generated = 1;
9531 /*-----------------------------------------------------------------*/
9532 /* genCast - gen code for casting */
9533 /*-----------------------------------------------------------------*/
9534 static void genCast (iCode *ic)
9536 operand *result = IC_RESULT(ic);
9537 sym_link *ctype = operandType(IC_LEFT(ic));
9538 sym_link *rtype = operandType(IC_RIGHT(ic));
9539 operand *right = IC_RIGHT(ic);
9542 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9543 /* if they are equivalent then do nothing */
9544 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9547 aopOp(right,ic,FALSE) ;
9548 aopOp(result,ic,FALSE);
9550 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9552 /* if the result is a bit */
9553 if (AOP_TYPE(result) == AOP_CRY) {
9554 /* if the right size is a literal then
9555 we know what the value is */
9556 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9557 if (AOP_TYPE(right) == AOP_LIT) {
9559 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9560 popGet(AOP(result),0));
9562 if (((int) operandLitValue(right)))
9563 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9564 AOP(result)->aopu.aop_dir,
9565 AOP(result)->aopu.aop_dir);
9567 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9568 AOP(result)->aopu.aop_dir,
9569 AOP(result)->aopu.aop_dir);
9574 /* the right is also a bit variable */
9575 if (AOP_TYPE(right) == AOP_CRY) {
9578 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9580 pic14_emitcode("clrc","");
9581 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9582 AOP(right)->aopu.aop_dir,
9583 AOP(right)->aopu.aop_dir);
9584 aopPut(AOP(result),"c",0);
9589 if (AOP_TYPE(right) == AOP_REG) {
9590 emitpcode(POC_BCF, popGet(AOP(result),0));
9591 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9592 emitpcode(POC_BSF, popGet(AOP(result),0));
9594 pic14_toBoolean(right);
9595 aopPut(AOP(result),"a",0);
9599 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9601 size = AOP_SIZE(result);
9603 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9605 emitpcode(POC_CLRF, popGet(AOP(result),0));
9606 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9607 emitpcode(POC_INCF, popGet(AOP(result),0));
9610 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9615 /* if they are the same size : or less */
9616 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9618 /* if they are in the same place */
9619 if (pic14_sameRegs(AOP(right),AOP(result)))
9622 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9623 if (IS_PTR_CONST(rtype))
9624 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9625 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9626 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9628 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9629 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9630 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9631 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9632 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9633 if(AOP_SIZE(result) <2)
9634 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9638 /* if they in different places then copy */
9639 size = AOP_SIZE(result);
9642 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9643 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9645 //aopPut(AOP(result),
9646 // aopGet(AOP(right),offset,FALSE,FALSE),
9656 /* if the result is of type pointer */
9657 if (IS_PTR(ctype)) {
9660 sym_link *type = operandType(right);
9661 sym_link *etype = getSpec(type);
9662 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9664 /* pointer to generic pointer */
9665 if (IS_GENPTR(ctype)) {
9669 p_type = DCL_TYPE(type);
9671 /* we have to go by the storage class */
9672 p_type = PTR_TYPE(SPEC_OCLS(etype));
9674 /* if (SPEC_OCLS(etype)->codesp ) */
9675 /* p_type = CPOINTER ; */
9677 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9678 /* p_type = FPOINTER ; */
9680 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9681 /* p_type = PPOINTER; */
9683 /* if (SPEC_OCLS(etype) == idata ) */
9684 /* p_type = IPOINTER ; */
9686 /* p_type = POINTER ; */
9689 /* the first two bytes are known */
9690 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9691 size = GPTRSIZE - 1;
9694 if(offset < AOP_SIZE(right)) {
9695 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9696 if ((AOP_TYPE(right) == AOP_PCODE) &&
9697 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9698 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9699 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9702 aopGet(AOP(right),offset,FALSE,FALSE),
9706 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9709 /* the last byte depending on type */
9713 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9716 pic14_emitcode(";BUG!? ","%d",__LINE__);
9720 pic14_emitcode(";BUG!? ","%d",__LINE__);
9724 pic14_emitcode(";BUG!? ","%d",__LINE__);
9729 /* this should never happen */
9730 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9731 "got unknown pointer type");
9734 //aopPut(AOP(result),l, GPTRSIZE - 1);
9738 /* just copy the pointers */
9739 size = AOP_SIZE(result);
9743 aopGet(AOP(right),offset,FALSE,FALSE),
9752 /* so we now know that the size of destination is greater
9753 than the size of the source.
9754 Now, if the next iCode is an operator then we might be
9755 able to optimize the operation without performing a cast.
9757 if(genMixedOperation(ic))
9760 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9762 /* we move to result for the size of source */
9763 size = AOP_SIZE(right);
9766 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9767 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9771 /* now depending on the sign of the destination */
9772 size = AOP_SIZE(result) - AOP_SIZE(right);
9773 /* if unsigned or not an integral type */
9774 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9776 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9778 /* we need to extend the sign :{ */
9781 /* Save one instruction of casting char to int */
9782 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9783 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9784 emitpcode(POC_DECF, popGet(AOP(result),offset));
9786 emitpcodeNULLop(POC_CLRW);
9789 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9791 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9793 emitpcode(POC_MOVLW, popGetLit(0xff));
9796 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9801 freeAsmop(right,NULL,ic,TRUE);
9802 freeAsmop(result,NULL,ic,TRUE);
9806 /*-----------------------------------------------------------------*/
9807 /* genDjnz - generate decrement & jump if not zero instrucion */
9808 /*-----------------------------------------------------------------*/
9809 static int genDjnz (iCode *ic, iCode *ifx)
9812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9817 /* if the if condition has a false label
9818 then we cannot save */
9822 /* if the minus is not of the form
9824 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9825 !IS_OP_LITERAL(IC_RIGHT(ic)))
9828 if (operandLitValue(IC_RIGHT(ic)) != 1)
9831 /* if the size of this greater than one then no
9833 if (getSize(operandType(IC_RESULT(ic))) > 1)
9836 /* otherwise we can save BIG */
9837 lbl = newiTempLabel(NULL);
9838 lbl1= newiTempLabel(NULL);
9840 aopOp(IC_RESULT(ic),ic,FALSE);
9842 if (IS_AOP_PREG(IC_RESULT(ic))) {
9843 pic14_emitcode("dec","%s",
9844 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9845 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9846 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9850 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9851 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9853 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9854 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9857 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9858 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9859 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9860 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9863 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9868 /*-----------------------------------------------------------------*/
9869 /* genReceive - generate code for a receive iCode */
9870 /*-----------------------------------------------------------------*/
9871 static void genReceive (iCode *ic)
9873 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9875 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9876 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9877 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9879 int size = getSize(operandType(IC_RESULT(ic)));
9880 int offset = fReturnSizePic - size;
9882 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9883 fReturn[fReturnSizePic - offset - 1] : "acc"));
9886 aopOp(IC_RESULT(ic),ic,FALSE);
9887 size = AOP_SIZE(IC_RESULT(ic));
9890 pic14_emitcode ("pop","acc");
9891 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9896 aopOp(IC_RESULT(ic),ic,FALSE);
9898 assignResultValue(IC_RESULT(ic));
9901 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9904 /*-----------------------------------------------------------------*/
9905 /* genDummyRead - generate code for dummy read of volatiles */
9906 /*-----------------------------------------------------------------*/
9908 genDummyRead (iCode * ic)
9910 pic14_emitcode ("; genDummyRead","");
9911 pic14_emitcode ("; not implemented","");
9916 /*-----------------------------------------------------------------*/
9917 /* genpic14Code - generate code for pic14 based controllers */
9918 /*-----------------------------------------------------------------*/
9920 * At this point, ralloc.c has gone through the iCode and attempted
9921 * to optimize in a way suitable for a PIC. Now we've got to generate
9922 * PIC instructions that correspond to the iCode.
9924 * Once the instructions are generated, we'll pass through both the
9925 * peep hole optimizer and the pCode optimizer.
9926 *-----------------------------------------------------------------*/
9928 void genpic14Code (iCode *lic)
9933 lineHead = lineCurr = NULL;
9935 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9938 /* if debug information required */
9939 if (options.debug && currFunc) {
9941 debugFile->writeFunction (currFunc, lic);
9946 for (ic = lic ; ic ; ic = ic->next ) {
9948 DEBUGpic14_emitcode(";ic","");
9949 if ( cln != ic->lineno ) {
9950 if ( options.debug ) {
9951 debugFile->writeCLine (ic);
9954 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9955 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9956 printCLine(ic->filename, ic->lineno));
9958 if (!options.noCcodeInAsm) {
9960 newpCodeCSource(ic->lineno,
9962 printCLine(ic->filename, ic->lineno)));
9968 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9970 /* if the result is marked as
9971 spilt and rematerializable or code for
9972 this has already been generated then
9974 if (resultRemat(ic) || ic->generated )
9977 /* depending on the operation */
9996 /* IPOP happens only when trying to restore a
9997 spilt live range, if there is an ifx statement
9998 following this pop then the if statement might
9999 be using some of the registers being popped which
10000 would destory the contents of the register so
10001 we need to check for this condition and handle it */
10003 ic->next->op == IFX &&
10004 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10005 genIfx (ic->next,ic);
10023 genEndFunction (ic);
10043 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10060 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10064 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10071 /* note these two are xlated by algebraic equivalence
10072 during parsing SDCC.y */
10073 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10074 "got '>=' or '<=' shouldn't have come here");
10078 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10090 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10094 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10098 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10122 genRightShift (ic);
10125 case GET_VALUE_AT_ADDRESS:
10130 if (POINTER_SET(ic))
10157 addSet(&_G.sendSet,ic);
10160 case DUMMY_READ_VOLATILE:
10170 /* now we are ready to call the
10171 peep hole optimizer */
10172 if (!options.nopeep) {
10173 peepHole (&lineHead);
10175 /* now do the actual printing */
10176 printLine (lineHead,codeOutFile);
10179 DFPRINTF((stderr,"printing pBlock\n\n"));
10180 printpBlock(stdout,pb);