1 /*-------------------------------------------------------------------------
2 SDCCgen51.c - source file for code generation for 8051
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
40 #include "SDCCpeeph.h"
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
56 /* max_key keeps track of the largest label number used in
57 a function. This is then used to adjust the label offset
58 for the next function.
61 static int GpsuedoStkPtr=0;
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
70 /* this is the down and dirty file with all kinds of
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
75 static char *zero = "#0x00";
76 static char *one = "#0x01";
77 static char *spname = "sp";
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
84 static char *accUse[] = {"a","b"};
86 //static short rbank = -1;
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
101 typedef struct resolvedIfx {
102 symbol *lbl; /* pointer to a label */
103 int condition; /* true or false ifx */
104 int generated; /* set true when the code associated with the ifx
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
116 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
123 /*-----------------------------------------------------------------*/
124 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
125 /* exponent of 2 is returned, otherwise -1 is */
127 /* note that this is similar to the function `powof2' in SDCCsymt */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
135 if( (num & (num-1)) == 0) {
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
151 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
153 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155 ((left) ? AopType(AOP_TYPE(left)) : "-"),
156 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157 ((right) ? AopType(AOP_TYPE(right)) : "-"),
158 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159 ((result) ? AOP_SIZE(result) : 0));
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
180 char lb[INITIAL_INLINEASM];
190 sprintf(lb,"%s\t",inst);
192 sprintf(lb,"%s",inst);
193 vsprintf(lb+(strlen(lb)),fmt,ap);
197 while (isspace(*lbp)) lbp++;
200 lineCurr = (lineCurr ?
201 connectLine(lineCurr,newLineNode(lb)) :
202 (lineHead = newLineNode(lb)));
203 lineCurr->isInline = _G.inLine;
204 lineCurr->isDebug = _G.debugLine;
206 addpCode2pBlock(pb,newpCodeCharP(lb));
212 void emitpLabel(int key)
214 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
221 addpCode2pBlock(pb,newpCode(poc,pcop));
223 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
226 void emitpcodeNULLop(PIC_OPCODE poc)
229 addpCode2pBlock(pb,newpCode(poc,NULL));
233 /*-----------------------------------------------------------------*/
234 /* pic14_emitcode - writes the code into a file : for now it is simple */
235 /*-----------------------------------------------------------------*/
236 void pic14_emitcode (char *inst,char *fmt, ...)
239 char lb[INITIAL_INLINEASM];
246 sprintf(lb,"%s\t",inst);
248 sprintf(lb,"%s",inst);
249 vsprintf(lb+(strlen(lb)),fmt,ap);
253 while (isspace(*lbp)) lbp++;
256 lineCurr = (lineCurr ?
257 connectLine(lineCurr,newLineNode(lb)) :
258 (lineHead = newLineNode(lb)));
259 lineCurr->isInline = _G.inLine;
260 lineCurr->isDebug = _G.debugLine;
263 addpCode2pBlock(pb,newpCodeCharP(lb));
269 /*-----------------------------------------------------------------*/
270 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/
271 /*-----------------------------------------------------------------*/
272 static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
274 bool r0iu = FALSE , r1iu = FALSE;
275 bool r0ou = FALSE , r1ou = FALSE;
277 /* the logic: if r0 & r1 used in the instruction
278 then we are in trouble otherwise */
280 /* first check if r0 & r1 are used by this
281 instruction, in which case we are in trouble */
282 if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
283 (r1iu = bitVectBitValue(ic->rUsed,R1_IDX)))
288 r0ou = bitVectBitValue(ic->rMask,R0_IDX);
289 r1ou = bitVectBitValue(ic->rMask,R1_IDX);
291 /* if no usage of r0 then return it */
292 if (!r0iu && !r0ou) {
293 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
294 (*aopp)->type = AOP_R0;
296 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
299 /* if no usage of r1 then return it */
300 if (!r1iu && !r1ou) {
301 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
302 (*aopp)->type = AOP_R1;
304 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R1_IDX);
307 /* now we know they both have usage */
308 /* if r0 not used in this instruction */
310 /* push it if not already pushed */
312 //pic14_emitcode ("push","%s",
313 // pic14_regWithIdx(R0_IDX)->dname);
317 ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
318 (*aopp)->type = AOP_R0;
320 return (*aopp)->aopu.aop_ptr = pic14_regWithIdx(R0_IDX);
323 /* if r1 not used then */
326 /* push it if not already pushed */
328 //pic14_emitcode ("push","%s",
329 // pic14_regWithIdx(R1_IDX)->dname);
333 ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
334 (*aopp)->type = AOP_R1;
335 return pic14_regWithIdx(R1_IDX);
339 /* I said end of world but not quite end of world yet */
340 /* if this is a result then we can push it on the stack*/
342 (*aopp)->type = AOP_STK;
346 /* other wise this is true end of the world */
347 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
348 "getFreePtr should never reach here");
352 /*-----------------------------------------------------------------*/
353 /* newAsmop - creates a new asmOp */
354 /*-----------------------------------------------------------------*/
355 asmop *newAsmop (short type)
359 aop = Safe_calloc(1,sizeof(asmop));
364 static void genSetDPTR(int n)
368 pic14_emitcode(";", "Select standard DPTR");
369 pic14_emitcode("mov", "dps, #0x00");
373 pic14_emitcode(";", "Select alternate DPTR");
374 pic14_emitcode("mov", "dps, #0x01");
378 /*-----------------------------------------------------------------*/
379 /* resolveIfx - converts an iCode ifx into a form more useful for */
380 /* generating code */
381 /*-----------------------------------------------------------------*/
382 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
387 // DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
389 resIfx->condition = 1; /* assume that the ifx is true */
390 resIfx->generated = 0; /* indicate that the ifx has not been used */
393 resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
395 DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
396 __FUNCTION__,__LINE__,resIfx->lbl->key);
400 resIfx->lbl = IC_TRUE(ifx);
402 resIfx->lbl = IC_FALSE(ifx);
403 resIfx->condition = 0;
407 DEBUGpic14_emitcode("; ***","ifx true is non-null");
409 DEBUGpic14_emitcode("; ***","ifx false is non-null");
413 // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
416 /*-----------------------------------------------------------------*/
417 /* pointerCode - returns the code for a pointer type */
418 /*-----------------------------------------------------------------*/
419 static int pointerCode (sym_link *etype)
422 return PTR_TYPE(SPEC_OCLS(etype));
426 /*-----------------------------------------------------------------*/
427 /* aopForSym - for a true symbol */
428 /*-----------------------------------------------------------------*/
429 static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
432 memmap *space= SPEC_OCLS(sym->etype);
434 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
435 /* if already has one */
439 /* assign depending on the storage class */
440 /* if it is on the stack or indirectly addressable */
441 /* space we need to assign either r0 or r1 to it */
442 if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
443 sym->aop = aop = newAsmop(0);
444 aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
445 aop->size = getSize(sym->type);
447 /* now assign the address of the variable to
448 the pointer register */
449 if (aop->type != AOP_STK) {
453 pic14_emitcode("push","acc");
455 pic14_emitcode("mov","a,_bp");
456 pic14_emitcode("add","a,#0x%02x",
458 ((char)(sym->stack - _G.nRegsSaved )) :
459 ((char)sym->stack)) & 0xff);
460 pic14_emitcode("mov","%s,a",
461 aop->aopu.aop_ptr->name);
464 pic14_emitcode("pop","acc");
466 pic14_emitcode("mov","%s,#%s",
467 aop->aopu.aop_ptr->name,
469 aop->paged = space->paged;
471 aop->aopu.aop_stk = sym->stack;
475 if (sym->onStack && options.stack10bit)
477 /* It's on the 10 bit stack, which is located in
481 //DEBUGpic14_emitcode(";","%d",__LINE__);
484 pic14_emitcode("push","acc");
486 pic14_emitcode("mov","a,_bp");
487 pic14_emitcode("add","a,#0x%02x",
489 ((char)(sym->stack - _G.nRegsSaved )) :
490 ((char)sym->stack)) & 0xff);
493 pic14_emitcode ("mov","dpx1,#0x40");
494 pic14_emitcode ("mov","dph1,#0x00");
495 pic14_emitcode ("mov","dpl1, a");
499 pic14_emitcode("pop","acc");
501 sym->aop = aop = newAsmop(AOP_DPTR2);
502 aop->size = getSize(sym->type);
506 //DEBUGpic14_emitcode(";","%d",__LINE__);
507 /* if in bit space */
508 if (IN_BITSPACE(space)) {
509 sym->aop = aop = newAsmop (AOP_CRY);
510 aop->aopu.aop_dir = sym->rname ;
511 aop->size = getSize(sym->type);
512 //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
515 /* if it is in direct space */
516 if (IN_DIRSPACE(space)) {
517 sym->aop = aop = newAsmop (AOP_DIR);
518 aop->aopu.aop_dir = sym->rname ;
519 aop->size = getSize(sym->type);
520 DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size);
524 /* special case for a function */
525 if (IS_FUNC(sym->type)) {
527 sym->aop = aop = newAsmop(AOP_PCODE);
528 aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
529 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
530 PCOI(aop->aopu.pcop)->_function = 1;
531 PCOI(aop->aopu.pcop)->index = 0;
532 aop->size = FPTRSIZE;
534 sym->aop = aop = newAsmop(AOP_IMMD);
535 aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
536 strcpy(aop->aopu.aop_immd,sym->rname);
537 aop->size = FPTRSIZE;
539 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
544 /* only remaining is far space */
545 /* in which case DPTR gets the address */
546 sym->aop = aop = newAsmop(AOP_PCODE);
548 aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
549 PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
550 PCOI(aop->aopu.pcop)->index = 0;
552 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
553 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
555 allocDirReg (IC_LEFT(ic));
557 aop->size = FPTRSIZE;
559 DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
560 sym->aop = aop = newAsmop(AOP_DPTR);
561 pic14_emitcode ("mov","dptr,#%s", sym->rname);
562 aop->size = getSize(sym->type);
564 DEBUGpic14_emitcode(";","%d size = %d",__LINE__,aop->size);
567 /* if it is in code space */
568 if (IN_CODESPACE(space))
574 /*-----------------------------------------------------------------*/
575 /* aopForRemat - rematerialzes an object */
576 /*-----------------------------------------------------------------*/
577 static asmop *aopForRemat (operand *op) // x symbol *sym)
579 symbol *sym = OP_SYMBOL(op);
581 asmop *aop = newAsmop(AOP_PCODE);
585 ic = sym->rematiCode;
587 DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__);
588 if(IS_OP_POINTER(op)) {
589 DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__);
593 val += (int) operandLitValue(IC_RIGHT(ic));
594 } else if (ic->op == '-') {
595 val -= (int) operandLitValue(IC_RIGHT(ic));
599 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
602 offset = OP_SYMBOL(IC_LEFT(ic))->offset;
603 aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
604 PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
605 PCOI(aop->aopu.pcop)->index = val;
607 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
608 __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname,
609 val, IS_PTR_CONST(operandType(op)));
611 // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic))));
613 allocDirReg (IC_LEFT(ic));
618 int aopIdx (asmop *aop, int offset)
623 if(aop->type != AOP_REG)
626 return aop->aopu.aop_reg[offset]->rIdx;
629 /*-----------------------------------------------------------------*/
630 /* regsInCommon - two operands have some registers in common */
631 /*-----------------------------------------------------------------*/
632 static bool regsInCommon (operand *op1, operand *op2)
637 /* if they have registers in common */
638 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
641 sym1 = OP_SYMBOL(op1);
642 sym2 = OP_SYMBOL(op2);
644 if (sym1->nRegs == 0 || sym2->nRegs == 0)
647 for (i = 0 ; i < sym1->nRegs ; i++) {
652 for (j = 0 ; j < sym2->nRegs ;j++ ) {
656 if (sym2->regs[j] == sym1->regs[i])
664 /*-----------------------------------------------------------------*/
665 /* operandsEqu - equivalent */
666 /*-----------------------------------------------------------------*/
667 static bool operandsEqu ( operand *op1, operand *op2)
671 /* if they not symbols */
672 if (!IS_SYMOP(op1) || !IS_SYMOP(op2))
675 sym1 = OP_SYMBOL(op1);
676 sym2 = OP_SYMBOL(op2);
678 /* if both are itemps & one is spilt
679 and the other is not then false */
680 if (IS_ITEMP(op1) && IS_ITEMP(op2) &&
681 sym1->isspilt != sym2->isspilt )
684 /* if they are the same */
688 if (strcmp(sym1->rname,sym2->rname) == 0)
692 /* if left is a tmp & right is not */
696 (sym1->usl.spillLoc == sym2))
703 (sym2->usl.spillLoc == sym1))
709 /*-----------------------------------------------------------------*/
710 /* pic14_sameRegs - two asmops have the same registers */
711 /*-----------------------------------------------------------------*/
712 bool pic14_sameRegs (asmop *aop1, asmop *aop2 )
719 if (aop1->type != AOP_REG ||
720 aop2->type != AOP_REG )
723 if (aop1->size != aop2->size )
726 for (i = 0 ; i < aop1->size ; i++ )
727 if (aop1->aopu.aop_reg[i] !=
728 aop2->aopu.aop_reg[i] )
734 /*-----------------------------------------------------------------*/
735 /* aopOp - allocates an asmop for an operand : */
736 /*-----------------------------------------------------------------*/
737 void aopOp (operand *op, iCode *ic, bool result)
746 // DEBUGpic14_emitcode(";","%d",__LINE__);
747 /* if this a literal */
748 if (IS_OP_LITERAL(op)) {
749 op->aop = aop = newAsmop(AOP_LIT);
750 aop->aopu.aop_lit = op->operand.valOperand;
751 aop->size = getSize(operandType(op));
756 sym_link *type = operandType(op);
757 if(IS_PTR_CONST(type))
758 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
761 /* if already has a asmop then continue */
765 /* if the underlying symbol has a aop */
766 if (IS_SYMOP(op) && OP_SYMBOL(op)->aop) {
767 DEBUGpic14_emitcode(";","%d",__LINE__);
768 op->aop = OP_SYMBOL(op)->aop;
772 /* if this is a true symbol */
773 if (IS_TRUE_SYMOP(op)) {
774 //DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
775 op->aop = aopForSym(ic,OP_SYMBOL(op),result);
779 /* this is a temporary : this has
785 e) can be a return use only */
790 /* if the type is a conditional */
791 if (sym->regType == REG_CND) {
792 aop = op->aop = sym->aop = newAsmop(AOP_CRY);
797 /* if it is spilt then two situations
799 b) has a spill location */
800 if (sym->isspilt || sym->nRegs == 0) {
802 DEBUGpic14_emitcode(";","%d",__LINE__);
803 /* rematerialize it NOW */
806 sym->aop = op->aop = aop =
808 aop->size = getSize(sym->type);
809 //DEBUGpic14_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd);
815 aop = op->aop = sym->aop = newAsmop(AOP_ACC);
816 aop->size = getSize(sym->type);
817 for ( i = 0 ; i < 2 ; i++ )
818 aop->aopu.aop_str[i] = accUse[i];
819 DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
824 if(sym->isptr) { // && sym->uptr
825 aop = op->aop = sym->aop = newAsmop(AOP_PCODE);
826 aop->aopu.pcop = newpCodeOp(NULL,PO_GPR_POINTER); //popCopyReg(&pc_fsr);
828 //PCOI(aop->aopu.pcop)->_const = 0;
829 //PCOI(aop->aopu.pcop)->index = 0;
831 DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
832 __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const);
834 //allocDirReg (IC_LEFT(ic));
836 aop->size = getSize(sym->type);
837 DEBUGpic14_emitcode(";","%d",__LINE__);
844 aop = op->aop = sym->aop = newAsmop(AOP_STR);
845 aop->size = getSize(sym->type);
846 for ( i = 0 ; i < fReturnSizePic ; i++ )
847 aop->aopu.aop_str[i] = fReturn[i];
849 DEBUGpic14_emitcode(";","%d",__LINE__);
854 /* else spill location */
855 if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
856 /* force a new aop if sizes differ */
857 sym->usl.spillLoc->aop = NULL;
859 DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
860 __FUNCTION__,__LINE__,
861 sym->usl.spillLoc->rname,
862 sym->rname, sym->usl.spillLoc->offset);
864 sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
865 //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
866 aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
868 sym->usl.spillLoc->offset);
869 aop->size = getSize(sym->type);
875 sym_link *type = operandType(op);
876 if(IS_PTR_CONST(type))
877 DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
880 /* must be in a register */
881 DEBUGpic14_emitcode(";","%d register type nRegs=%d",__LINE__,sym->nRegs);
882 sym->aop = op->aop = aop = newAsmop(AOP_REG);
883 aop->size = sym->nRegs;
884 for ( i = 0 ; i < sym->nRegs ;i++)
885 aop->aopu.aop_reg[i] = sym->regs[i];
888 /*-----------------------------------------------------------------*/
889 /* freeAsmop - free up the asmop given to an operand */
890 /*----------------------------------------------------------------*/
891 void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
908 /* depending on the asmop type only three cases need work AOP_RO
909 , AOP_R1 && AOP_STK */
915 pic14_emitcode ("pop","ar0");
919 bitVectUnSetBit(ic->rUsed,R0_IDX);
925 pic14_emitcode ("pop","ar1");
929 bitVectUnSetBit(ic->rUsed,R1_IDX);
935 int stk = aop->aopu.aop_stk + aop->size;
936 bitVectUnSetBit(ic->rUsed,R0_IDX);
937 bitVectUnSetBit(ic->rUsed,R1_IDX);
939 getFreePtr(ic,&aop,FALSE);
941 if (options.stack10bit)
943 /* I'm not sure what to do here yet... */
946 "*** Warning: probably generating bad code for "
947 "10 bit stack mode.\n");
951 pic14_emitcode ("mov","a,_bp");
952 pic14_emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
953 pic14_emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
955 pic14_emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
959 pic14_emitcode("pop","acc");
960 pic14_emitcode("mov","@%s,a",aop->aopu.aop_ptr->name);
962 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
965 freeAsmop(op,NULL,ic,TRUE);
967 pic14_emitcode("pop","ar0");
972 pic14_emitcode("pop","ar1");
980 /* all other cases just dealloc */
984 OP_SYMBOL(op)->aop = NULL;
985 /* if the symbol has a spill */
987 SPIL_LOC(op)->aop = NULL;
992 /*-----------------------------------------------------------------*/
993 /* aopGet - for fetching value of the aop */
994 /*-----------------------------------------------------------------*/
995 char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
1000 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1001 /* offset is greater than
1003 if (offset > (aop->size - 1) &&
1004 aop->type != AOP_LIT)
1007 /* depending on type */
1008 switch (aop->type) {
1012 DEBUGpic14_emitcode(";","%d",__LINE__);
1013 /* if we need to increment it */
1014 while (offset > aop->coff) {
1015 pic14_emitcode ("inc","%s",aop->aopu.aop_ptr->name);
1019 while (offset < aop->coff) {
1020 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1024 aop->coff = offset ;
1026 pic14_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name);
1027 return (dname ? "acc" : "a");
1029 sprintf(s,"@%s",aop->aopu.aop_ptr->name);
1030 rs = Safe_calloc(1,strlen(s)+1);
1036 DEBUGpic14_emitcode(";","%d",__LINE__);
1037 if (aop->type == AOP_DPTR2)
1042 while (offset > aop->coff) {
1043 pic14_emitcode ("inc","dptr");
1047 while (offset < aop->coff) {
1048 pic14_emitcode("lcall","__decdptr");
1054 pic14_emitcode("clr","a");
1055 pic14_emitcode("movc","a,@a+dptr");
1058 pic14_emitcode("movx","a,@dptr");
1061 if (aop->type == AOP_DPTR2)
1066 return (dname ? "acc" : "a");
1071 sprintf (s,"%s",aop->aopu.aop_immd);
1074 sprintf(s,"(%s >> %d)",
1079 aop->aopu.aop_immd);
1080 DEBUGpic14_emitcode(";","%d immd %s",__LINE__,s);
1081 rs = Safe_calloc(1,strlen(s)+1);
1087 sprintf(s,"(%s + %d)",
1090 DEBUGpic14_emitcode(";","oops AOP_DIR did this %s\n",s);
1092 sprintf(s,"%s",aop->aopu.aop_dir);
1093 rs = Safe_calloc(1,strlen(s)+1);
1099 // return aop->aopu.aop_reg[offset]->dname;
1101 return aop->aopu.aop_reg[offset]->name;
1104 //pic14_emitcode(";","%d",__LINE__);
1105 return aop->aopu.aop_dir;
1108 DEBUGpic14_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__);
1109 return "AOP_accumulator_bug";
1112 sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset));
1113 rs = Safe_calloc(1,strlen(s)+1);
1118 aop->coff = offset ;
1119 if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
1122 DEBUGpic14_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
1124 return aop->aopu.aop_str[offset];
1128 pCodeOp *pcop = aop->aopu.pcop;
1129 DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop));
1131 DEBUGpic14_emitcode(";","%s offset %d",pcop->name,PCOI(pcop)->offset);
1132 //sprintf(s,"(%s+0x%02x)", pcop->name,PCOI(aop->aopu.pcop)->offset);
1133 sprintf(s,"%s", pcop->name);
1135 sprintf(s,"0x%02x", PCOI(aop->aopu.pcop)->offset);
1138 rs = Safe_calloc(1,strlen(s)+1);
1144 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1145 "aopget got unsupported aop->type");
1150 /*-----------------------------------------------------------------*/
1151 /* popGetTempReg - create a new temporary pCodeOp */
1152 /*-----------------------------------------------------------------*/
1153 pCodeOp *popGetTempReg(void)
1158 pcop = newpCodeOp(NULL, PO_GPR_TEMP);
1159 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
1160 PCOR(pcop)->r->wasUsed=1;
1161 PCOR(pcop)->r->isFree=0;
1167 /*-----------------------------------------------------------------*/
1168 /* popGetTempReg - create a new temporary pCodeOp */
1169 /*-----------------------------------------------------------------*/
1170 void popReleaseTempReg(pCodeOp *pcop)
1173 if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r)
1174 PCOR(pcop)->r->isFree = 1;
1177 /*-----------------------------------------------------------------*/
1178 /* popGetLabel - create a new pCodeOp of type PO_LABEL */
1179 /*-----------------------------------------------------------------*/
1180 pCodeOp *popGetLabel(unsigned int key)
1183 DEBUGpic14_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset);
1188 return newpCodeOpLabel(NULL,key+100+labelOffset);
1191 /*-----------------------------------------------------------------*/
1192 /* popCopyReg - copy a pcode operator */
1193 /*-----------------------------------------------------------------*/
1194 pCodeOp *popCopyReg(pCodeOpReg *pc)
1198 pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
1199 pcor->pcop.type = pc->pcop.type;
1201 if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
1202 fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
1204 pcor->pcop.name = NULL;
1207 pcor->rIdx = pc->rIdx;
1210 //DEBUGpic14_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx);
1214 /*-----------------------------------------------------------------*/
1215 /* popGet - asm operator to pcode operator conversion */
1216 /*-----------------------------------------------------------------*/
1217 pCodeOp *popGetLit(unsigned int lit)
1220 return newpCodeOpLit(lit);
1224 /*-----------------------------------------------------------------*/
1225 /* popGetImmd - asm operator to pcode immediate conversion */
1226 /*-----------------------------------------------------------------*/
1227 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1230 return newpCodeOpImmd(name, offset,index, 0, is_func);
1234 /*-----------------------------------------------------------------*/
1235 /* popGet - asm operator to pcode operator conversion */
1236 /*-----------------------------------------------------------------*/
1237 pCodeOp *popGetWithString(char *str)
1243 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1247 pcop = newpCodeOp(str,PO_STR);
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 pCodeOp *popRegFromIdx(int rIdx)
1288 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1289 __FUNCTION__,__LINE__,rIdx);
1291 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1293 PCOR(pcop)->rIdx = rIdx;
1294 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1295 PCOR(pcop)->r->isFree = 0;
1296 PCOR(pcop)->r->wasUsed = 1;
1298 pcop->type = PCOR(pcop)->r->pc_type;
1303 /*-----------------------------------------------------------------*/
1304 /* popGet - asm operator to pcode operator conversion */
1305 /*-----------------------------------------------------------------*/
1306 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1308 //char *s = buffer ;
1313 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1314 /* offset is greater than
1317 if (offset > (aop->size - 1) &&
1318 aop->type != AOP_LIT)
1319 return NULL; //zero;
1321 /* depending on type */
1322 switch (aop->type) {
1329 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1333 DEBUGpic14_emitcode(";","%d",__LINE__);
1334 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1337 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1339 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1340 pcop->type = PO_DIR;
1344 sprintf(s,"(%s + %d)",
1348 sprintf(s,"%s",aop->aopu.aop_dir);
1349 pcop->name = Safe_calloc(1,strlen(s)+1);
1350 strcpy(pcop->name,s);
1352 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1353 strcpy(pcop->name,aop->aopu.aop_dir);
1354 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1355 if(PCOR(pcop)->r == NULL) {
1356 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1357 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1358 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1360 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1362 PCOR(pcop)->instance = offset;
1369 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1371 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1372 PCOR(pcop)->rIdx = rIdx;
1373 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1374 PCOR(pcop)->r->wasUsed=1;
1375 PCOR(pcop)->r->isFree=0;
1377 PCOR(pcop)->instance = offset;
1378 pcop->type = PCOR(pcop)->r->pc_type;
1379 //rs = aop->aopu.aop_reg[offset]->name;
1380 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1385 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1386 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1387 //if(PCOR(pcop)->r == NULL)
1388 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1392 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1395 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1396 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1398 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1399 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1400 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1401 pcop->type = PCOR(pcop)->r->pc_type;
1402 pcop->name = PCOR(pcop)->r->name;
1408 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1410 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1411 pcop = pCodeOpCopy(aop->aopu.pcop);
1412 PCOI(pcop)->offset = offset;
1416 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1417 "popGet got unsupported aop->type");
1420 /*-----------------------------------------------------------------*/
1421 /* aopPut - puts a string for a aop */
1422 /*-----------------------------------------------------------------*/
1423 void aopPut (asmop *aop, char *s, int offset)
1428 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1430 if (aop->size && offset > ( aop->size - 1)) {
1431 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1432 "aopPut got offset > aop->size");
1436 /* will assign value to value */
1437 /* depending on where it is ofcourse */
1438 switch (aop->type) {
1441 sprintf(d,"(%s + %d)",
1442 aop->aopu.aop_dir,offset);
1443 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1446 sprintf(d,"%s",aop->aopu.aop_dir);
1449 DEBUGpic14_emitcode(";","%d",__LINE__);
1451 pic14_emitcode("movf","%s,w",s);
1452 pic14_emitcode("movwf","%s",d);
1455 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1456 if(offset >= aop->size) {
1457 emitpcode(POC_CLRF,popGet(aop,offset));
1460 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1463 emitpcode(POC_MOVWF,popGet(aop,offset));
1470 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1471 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1474 strcmp(s,"r0") == 0 ||
1475 strcmp(s,"r1") == 0 ||
1476 strcmp(s,"r2") == 0 ||
1477 strcmp(s,"r3") == 0 ||
1478 strcmp(s,"r4") == 0 ||
1479 strcmp(s,"r5") == 0 ||
1480 strcmp(s,"r6") == 0 ||
1481 strcmp(s,"r7") == 0 )
1482 pic14_emitcode("mov","%s,%s ; %d",
1483 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1487 if(strcmp(s,"W")==0 )
1488 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1490 pic14_emitcode("movwf","%s",
1491 aop->aopu.aop_reg[offset]->name);
1493 if(strcmp(s,zero)==0) {
1494 emitpcode(POC_CLRF,popGet(aop,offset));
1496 } else if(strcmp(s,"W")==0) {
1497 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1498 pcop->type = PO_GPR_REGISTER;
1500 PCOR(pcop)->rIdx = -1;
1501 PCOR(pcop)->r = NULL;
1503 DEBUGpic14_emitcode(";","%d",__LINE__);
1504 pcop->name = Safe_strdup(s);
1505 emitpcode(POC_MOVFW,pcop);
1506 emitpcode(POC_MOVWF,popGet(aop,offset));
1507 } else if(strcmp(s,one)==0) {
1508 emitpcode(POC_CLRF,popGet(aop,offset));
1509 emitpcode(POC_INCF,popGet(aop,offset));
1511 emitpcode(POC_MOVWF,popGet(aop,offset));
1519 if (aop->type == AOP_DPTR2)
1525 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1526 "aopPut writting to code space");
1530 while (offset > aop->coff) {
1532 pic14_emitcode ("inc","dptr");
1535 while (offset < aop->coff) {
1537 pic14_emitcode("lcall","__decdptr");
1542 /* if not in accumulater */
1545 pic14_emitcode ("movx","@dptr,a");
1547 if (aop->type == AOP_DPTR2)
1555 while (offset > aop->coff) {
1557 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1559 while (offset < aop->coff) {
1561 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1567 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1572 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1574 if (strcmp(s,"r0") == 0 ||
1575 strcmp(s,"r1") == 0 ||
1576 strcmp(s,"r2") == 0 ||
1577 strcmp(s,"r3") == 0 ||
1578 strcmp(s,"r4") == 0 ||
1579 strcmp(s,"r5") == 0 ||
1580 strcmp(s,"r6") == 0 ||
1581 strcmp(s,"r7") == 0 ) {
1583 sprintf(buffer,"a%s",s);
1584 pic14_emitcode("mov","@%s,%s",
1585 aop->aopu.aop_ptr->name,buffer);
1587 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1592 if (strcmp(s,"a") == 0)
1593 pic14_emitcode("push","acc");
1595 pic14_emitcode("push","%s",s);
1600 /* if bit variable */
1601 if (!aop->aopu.aop_dir) {
1602 pic14_emitcode("clr","a");
1603 pic14_emitcode("rlc","a");
1606 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1609 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1612 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1614 lbl = newiTempLabel(NULL);
1616 if (strcmp(s,"a")) {
1619 pic14_emitcode("clr","c");
1620 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1621 pic14_emitcode("cpl","c");
1622 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1623 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1630 if (strcmp(aop->aopu.aop_str[offset],s))
1631 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1636 if (!offset && (strcmp(s,"acc") == 0))
1639 if (strcmp(aop->aopu.aop_str[offset],s))
1640 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1644 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1645 "aopPut got unsupported aop->type");
1651 /*-----------------------------------------------------------------*/
1652 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1653 /*-----------------------------------------------------------------*/
1654 void mov2w (asmop *aop, int offset)
1660 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1662 if ( aop->type == AOP_PCODE ||
1663 aop->type == AOP_LIT ||
1664 aop->type == AOP_IMMD )
1665 emitpcode(POC_MOVLW,popGet(aop,offset));
1667 emitpcode(POC_MOVFW,popGet(aop,offset));
1671 /*-----------------------------------------------------------------*/
1672 /* reAdjustPreg - points a register back to where it should */
1673 /*-----------------------------------------------------------------*/
1674 static void reAdjustPreg (asmop *aop)
1678 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1680 if ((size = aop->size) <= 1)
1683 switch (aop->type) {
1687 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1691 if (aop->type == AOP_DPTR2)
1697 pic14_emitcode("lcall","__decdptr");
1700 if (aop->type == AOP_DPTR2)
1710 /*-----------------------------------------------------------------*/
1711 /* genNotFloat - generates not for float operations */
1712 /*-----------------------------------------------------------------*/
1713 static void genNotFloat (operand *op, operand *res)
1719 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1720 /* we will put 127 in the first byte of
1722 aopPut(AOP(res),"#127",0);
1723 size = AOP_SIZE(op) - 1;
1726 l = aopGet(op->aop,offset++,FALSE,FALSE);
1730 pic14_emitcode("orl","a,%s",
1732 offset++,FALSE,FALSE));
1734 tlbl = newiTempLabel(NULL);
1736 tlbl = newiTempLabel(NULL);
1737 aopPut(res->aop,one,1);
1738 pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
1739 aopPut(res->aop,zero,1);
1740 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
1742 size = res->aop->size - 2;
1744 /* put zeros in the rest */
1746 aopPut(res->aop,zero,offset++);
1750 /*-----------------------------------------------------------------*/
1751 /* opIsGptr: returns non-zero if the passed operand is */
1752 /* a generic pointer type. */
1753 /*-----------------------------------------------------------------*/
1754 static int opIsGptr(operand *op)
1756 sym_link *type = operandType(op);
1758 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1759 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1767 /*-----------------------------------------------------------------*/
1768 /* pic14_getDataSize - get the operand data size */
1769 /*-----------------------------------------------------------------*/
1770 int pic14_getDataSize(operand *op)
1772 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1775 return AOP_SIZE(op);
1777 // tsd- in the pic port, the genptr size is 1, so this code here
1778 // fails. ( in the 8051 port, the size was 4).
1781 size = AOP_SIZE(op);
1782 if (size == GPTRSIZE)
1784 sym_link *type = operandType(op);
1785 if (IS_GENPTR(type))
1787 /* generic pointer; arithmetic operations
1788 * should ignore the high byte (pointer type).
1791 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1798 /*-----------------------------------------------------------------*/
1799 /* pic14_outAcc - output Acc */
1800 /*-----------------------------------------------------------------*/
1801 void pic14_outAcc(operand *result)
1804 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1805 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1808 size = pic14_getDataSize(result);
1810 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1813 /* unsigned or positive */
1815 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1820 /*-----------------------------------------------------------------*/
1821 /* pic14_outBitC - output a bit C */
1822 /*-----------------------------------------------------------------*/
1823 void pic14_outBitC(operand *result)
1826 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1827 /* if the result is bit */
1828 if (AOP_TYPE(result) == AOP_CRY)
1829 aopPut(AOP(result),"c",0);
1831 pic14_emitcode("clr","a ; %d", __LINE__);
1832 pic14_emitcode("rlc","a");
1833 pic14_outAcc(result);
1837 /*-----------------------------------------------------------------*/
1838 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1839 /*-----------------------------------------------------------------*/
1840 void pic14_toBoolean(operand *oper)
1842 int size = AOP_SIZE(oper) - 1;
1845 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1847 if ( AOP_TYPE(oper) != AOP_ACC) {
1848 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1851 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1856 /*-----------------------------------------------------------------*/
1857 /* genNot - generate code for ! operation */
1858 /*-----------------------------------------------------------------*/
1859 static void genNot (iCode *ic)
1862 sym_link *optype = operandType(IC_LEFT(ic));
1865 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1866 /* assign asmOps to operand & result */
1867 aopOp (IC_LEFT(ic),ic,FALSE);
1868 aopOp (IC_RESULT(ic),ic,TRUE);
1870 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1871 /* if in bit space then a special case */
1872 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1873 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1874 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1875 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1877 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1878 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1879 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1884 /* if type float then do float */
1885 if (IS_FLOAT(optype)) {
1886 genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
1890 size = AOP_SIZE(IC_RESULT(ic));
1892 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1893 emitpcode(POC_ANDLW,popGetLit(1));
1894 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1897 pic14_toBoolean(IC_LEFT(ic));
1899 tlbl = newiTempLabel(NULL);
1900 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1901 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1902 pic14_outBitC(IC_RESULT(ic));
1905 /* release the aops */
1906 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1907 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1911 /*-----------------------------------------------------------------*/
1912 /* genCpl - generate code for complement */
1913 /*-----------------------------------------------------------------*/
1914 static void genCpl (iCode *ic)
1916 operand *left, *result;
1920 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1921 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1922 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1924 /* if both are in bit space then
1926 if (AOP_TYPE(result) == AOP_CRY &&
1927 AOP_TYPE(left) == AOP_CRY ) {
1929 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1930 pic14_emitcode("cpl","c");
1931 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1935 size = AOP_SIZE(result);
1938 if(AOP_TYPE(left) == AOP_ACC)
1939 emitpcode(POC_XORLW, popGetLit(0xff));
1941 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1943 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1949 /* release the aops */
1950 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1951 freeAsmop(result,NULL,ic,TRUE);
1954 /*-----------------------------------------------------------------*/
1955 /* genUminusFloat - unary minus for floating points */
1956 /*-----------------------------------------------------------------*/
1957 static void genUminusFloat(operand *op,operand *result)
1959 int size ,offset =0 ;
1962 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1963 /* for this we just need to flip the
1964 first it then copy the rest in place */
1965 size = AOP_SIZE(op) - 1;
1966 l = aopGet(AOP(op),3,FALSE,FALSE);
1970 pic14_emitcode("cpl","acc.7");
1971 aopPut(AOP(result),"a",3);
1975 aopGet(AOP(op),offset,FALSE,FALSE),
1981 /*-----------------------------------------------------------------*/
1982 /* genUminus - unary minus code generation */
1983 /*-----------------------------------------------------------------*/
1984 static void genUminus (iCode *ic)
1987 sym_link *optype, *rtype;
1990 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1992 aopOp(IC_LEFT(ic),ic,FALSE);
1993 aopOp(IC_RESULT(ic),ic,TRUE);
1995 /* if both in bit space then special
1997 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1998 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
2000 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
2001 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
2002 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
2007 optype = operandType(IC_LEFT(ic));
2008 rtype = operandType(IC_RESULT(ic));
2010 /* if float then do float stuff */
2011 if (IS_FLOAT(optype)) {
2012 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
2016 /* otherwise subtract from zero by taking the 2's complement */
2017 size = AOP_SIZE(IC_LEFT(ic));
2019 for(i=0; i<size; i++) {
2020 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
2021 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
2023 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
2024 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
2028 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
2029 for(i=1; i<size; i++) {
2031 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
2035 /* release the aops */
2036 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
2037 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2040 /*-----------------------------------------------------------------*/
2041 /* saveRegisters - will look for a call and save the registers */
2042 /*-----------------------------------------------------------------*/
2043 static void saveRegisters(iCode *lic)
2050 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2052 for (ic = lic ; ic ; ic = ic->next)
2053 if (ic->op == CALL || ic->op == PCALL)
2057 fprintf(stderr,"found parameter push with no function call\n");
2061 /* if the registers have been saved already then
2063 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2066 /* find the registers in use at this time
2067 and push them away to safety */
2068 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2072 if (options.useXstack) {
2073 if (bitVectBitValue(rsave,R0_IDX))
2074 pic14_emitcode("mov","b,r0");
2075 pic14_emitcode("mov","r0,%s",spname);
2076 for (i = 0 ; i < pic14_nRegs ; i++) {
2077 if (bitVectBitValue(rsave,i)) {
2079 pic14_emitcode("mov","a,b");
2081 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2082 pic14_emitcode("movx","@r0,a");
2083 pic14_emitcode("inc","r0");
2086 pic14_emitcode("mov","%s,r0",spname);
2087 if (bitVectBitValue(rsave,R0_IDX))
2088 pic14_emitcode("mov","r0,b");
2090 //for (i = 0 ; i < pic14_nRegs ; i++) {
2091 // if (bitVectBitValue(rsave,i))
2092 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2095 dtype = operandType(IC_LEFT(ic));
2096 if (currFunc && dtype &&
2097 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2098 IFFUNC_ISISR(currFunc->type) &&
2101 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2104 /*-----------------------------------------------------------------*/
2105 /* unsaveRegisters - pop the pushed registers */
2106 /*-----------------------------------------------------------------*/
2107 static void unsaveRegisters (iCode *ic)
2112 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2113 /* find the registers in use at this time
2114 and push them away to safety */
2115 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2118 if (options.useXstack) {
2119 pic14_emitcode("mov","r0,%s",spname);
2120 for (i = pic14_nRegs ; i >= 0 ; i--) {
2121 if (bitVectBitValue(rsave,i)) {
2122 pic14_emitcode("dec","r0");
2123 pic14_emitcode("movx","a,@r0");
2125 pic14_emitcode("mov","b,a");
2127 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2131 pic14_emitcode("mov","%s,r0",spname);
2132 if (bitVectBitValue(rsave,R0_IDX))
2133 pic14_emitcode("mov","r0,b");
2135 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2136 // if (bitVectBitValue(rsave,i))
2137 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2143 /*-----------------------------------------------------------------*/
2145 /*-----------------------------------------------------------------*/
2146 static void pushSide(operand * oper, int size)
2150 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2152 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2153 if (AOP_TYPE(oper) != AOP_REG &&
2154 AOP_TYPE(oper) != AOP_DIR &&
2156 pic14_emitcode("mov","a,%s",l);
2157 pic14_emitcode("push","acc");
2159 pic14_emitcode("push","%s",l);
2164 /*-----------------------------------------------------------------*/
2165 /* assignResultValue - */
2166 /*-----------------------------------------------------------------*/
2167 static void assignResultValue(operand * oper)
2169 int size = AOP_SIZE(oper);
2171 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2173 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2175 if(!GpsuedoStkPtr) {
2176 /* The last byte in the assignment is in W */
2178 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2184 emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + Gstack_base_addr));
2186 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2191 /*-----------------------------------------------------------------*/
2192 /* genIpush - genrate code for pushing this gets a little complex */
2193 /*-----------------------------------------------------------------*/
2194 static void genIpush (iCode *ic)
2197 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2199 int size, offset = 0 ;
2203 /* if this is not a parm push : ie. it is spill push
2204 and spill push is always done on the local stack */
2205 if (!ic->parmPush) {
2207 /* and the item is spilt then do nothing */
2208 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2211 aopOp(IC_LEFT(ic),ic,FALSE);
2212 size = AOP_SIZE(IC_LEFT(ic));
2213 /* push it on the stack */
2215 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2220 pic14_emitcode("push","%s",l);
2225 /* this is a paramter push: in this case we call
2226 the routine to find the call and save those
2227 registers that need to be saved */
2230 /* then do the push */
2231 aopOp(IC_LEFT(ic),ic,FALSE);
2234 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2235 size = AOP_SIZE(IC_LEFT(ic));
2238 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2239 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2240 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2242 pic14_emitcode("mov","a,%s",l);
2243 pic14_emitcode("push","acc");
2245 pic14_emitcode("push","%s",l);
2248 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2252 /*-----------------------------------------------------------------*/
2253 /* genIpop - recover the registers: can happen only for spilling */
2254 /*-----------------------------------------------------------------*/
2255 static void genIpop (iCode *ic)
2257 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2262 /* if the temp was not pushed then */
2263 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2266 aopOp(IC_LEFT(ic),ic,FALSE);
2267 size = AOP_SIZE(IC_LEFT(ic));
2270 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2273 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2277 /*-----------------------------------------------------------------*/
2278 /* unsaverbank - restores the resgister bank from stack */
2279 /*-----------------------------------------------------------------*/
2280 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2282 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2288 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2290 if (options.useXstack) {
2292 r = getFreePtr(ic,&aop,FALSE);
2295 pic14_emitcode("mov","%s,_spx",r->name);
2296 pic14_emitcode("movx","a,@%s",r->name);
2297 pic14_emitcode("mov","psw,a");
2298 pic14_emitcode("dec","%s",r->name);
2301 pic14_emitcode ("pop","psw");
2304 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2305 if (options.useXstack) {
2306 pic14_emitcode("movx","a,@%s",r->name);
2307 //pic14_emitcode("mov","(%s+%d),a",
2308 // regspic14[i].base,8*bank+regspic14[i].offset);
2309 pic14_emitcode("dec","%s",r->name);
2312 pic14_emitcode("pop",""); //"(%s+%d)",
2313 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2316 if (options.useXstack) {
2318 pic14_emitcode("mov","_spx,%s",r->name);
2319 freeAsmop(NULL,aop,ic,TRUE);
2325 /*-----------------------------------------------------------------*/
2326 /* saverbank - saves an entire register bank on the stack */
2327 /*-----------------------------------------------------------------*/
2328 static void saverbank (int bank, iCode *ic, bool pushPsw)
2330 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2336 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2337 if (options.useXstack) {
2340 r = getFreePtr(ic,&aop,FALSE);
2341 pic14_emitcode("mov","%s,_spx",r->name);
2345 for (i = 0 ; i < pic14_nRegs ;i++) {
2346 if (options.useXstack) {
2347 pic14_emitcode("inc","%s",r->name);
2348 //pic14_emitcode("mov","a,(%s+%d)",
2349 // regspic14[i].base,8*bank+regspic14[i].offset);
2350 pic14_emitcode("movx","@%s,a",r->name);
2352 pic14_emitcode("push","");// "(%s+%d)",
2353 //regspic14[i].base,8*bank+regspic14[i].offset);
2357 if (options.useXstack) {
2358 pic14_emitcode("mov","a,psw");
2359 pic14_emitcode("movx","@%s,a",r->name);
2360 pic14_emitcode("inc","%s",r->name);
2361 pic14_emitcode("mov","_spx,%s",r->name);
2362 freeAsmop (NULL,aop,ic,TRUE);
2365 pic14_emitcode("push","psw");
2367 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2373 /*-----------------------------------------------------------------*/
2374 /* genCall - generates a call statement */
2375 /*-----------------------------------------------------------------*/
2376 static void genCall (iCode *ic)
2380 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2382 /* if caller saves & we have not saved then */
2386 /* if we are calling a function that is not using
2387 the same register bank then we need to save the
2388 destination registers on the stack */
2389 dtype = operandType(IC_LEFT(ic));
2390 if (currFunc && dtype &&
2391 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2392 IFFUNC_ISISR(currFunc->type) &&
2395 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2397 /* if send set is not empty the assign */
2400 /* For the Pic port, there is no data stack.
2401 * So parameters passed to functions are stored
2402 * in registers. (The pCode optimizer will get
2403 * rid of most of these :).
2405 int psuedoStkPtr=-1;
2406 int firstTimeThruLoop = 1;
2408 _G.sendSet = reverseSet(_G.sendSet);
2410 /* First figure how many parameters are getting passed */
2411 for (sic = setFirstItem(_G.sendSet) ; sic ;
2412 sic = setNextItem(_G.sendSet)) {
2414 aopOp(IC_LEFT(sic),sic,FALSE);
2415 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2416 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2419 for (sic = setFirstItem(_G.sendSet) ; sic ;
2420 sic = setNextItem(_G.sendSet)) {
2421 int size, offset = 0;
2423 aopOp(IC_LEFT(sic),sic,FALSE);
2424 size = AOP_SIZE(IC_LEFT(sic));
2427 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2428 AopType(AOP_TYPE(IC_LEFT(sic))));
2430 if(!firstTimeThruLoop) {
2431 /* If this is not the first time we've been through the loop
2432 * then we need to save the parameter in a temporary
2433 * register. The last byte of the last parameter is
2435 emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + Gstack_base_addr));
2438 firstTimeThruLoop=0;
2440 //if (strcmp(l,fReturn[offset])) {
2441 mov2w (AOP(IC_LEFT(sic)), offset);
2443 if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) ||
2444 ((AOP(IC_LEFT(sic))->type) == AOP_LIT) )
2445 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(sic)),offset));
2447 emitpcode(POC_MOVFW,popGet(AOP(IC_LEFT(sic)),offset));
2452 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2457 emitpcode(POC_CALL,popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ?
2458 OP_SYMBOL(IC_LEFT(ic))->rname :
2459 OP_SYMBOL(IC_LEFT(ic))->name));
2462 /* if we need assign a result value */
2463 if ((IS_ITEMP(IC_RESULT(ic)) &&
2464 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2465 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2466 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2469 aopOp(IC_RESULT(ic),ic,FALSE);
2472 assignResultValue(IC_RESULT(ic));
2474 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2475 AopType(AOP_TYPE(IC_RESULT(ic))));
2477 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2480 /* adjust the stack for parameters if
2482 if (ic->parmBytes) {
2484 if (ic->parmBytes > 3) {
2485 pic14_emitcode("mov","a,%s",spname);
2486 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2487 pic14_emitcode("mov","%s,a",spname);
2489 for ( i = 0 ; i < ic->parmBytes ;i++)
2490 pic14_emitcode("dec","%s",spname);
2494 /* if register bank was saved then pop them */
2496 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2498 /* if we hade saved some registers then unsave them */
2499 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2500 unsaveRegisters (ic);
2505 /*-----------------------------------------------------------------*/
2506 /* genPcall - generates a call by pointer statement */
2507 /*-----------------------------------------------------------------*/
2508 static void genPcall (iCode *ic)
2511 symbol *albl = newiTempLabel(NULL);
2512 symbol *blbl = newiTempLabel(NULL);
2516 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2517 /* if caller saves & we have not saved then */
2521 /* if we are calling a function that is not using
2522 the same register bank then we need to save the
2523 destination registers on the stack */
2524 dtype = operandType(IC_LEFT(ic));
2525 if (currFunc && dtype &&
2526 IFFUNC_ISISR(currFunc->type) &&
2527 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2528 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2531 aopOp(left,ic,FALSE);
2532 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2534 pushSide(IC_LEFT(ic), FPTRSIZE);
2536 /* if send set is not empty, assign parameters */
2539 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2540 /* no way to pass args - W always gets used to make the call */
2542 /* first idea - factor out a common helper function and call it.
2543 But don't know how to get it generated only once in its own block
2545 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2548 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2549 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2550 buffer = Safe_calloc(1,strlen(rname)+16);
2551 sprintf(buffer, "%s_goto_helper", rname);
2552 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2556 emitpcode(POC_CALL,popGetLabel(albl->key));
2557 emitpcode(POC_GOTO,popGetLabel(blbl->key));
2558 emitpLabel(albl->key);
2560 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2562 emitpcode(poc,popGet(AOP(left),1));
2563 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2564 emitpcode(poc,popGet(AOP(left),0));
2565 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2567 emitpLabel(blbl->key);
2569 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2571 /* if we need to assign a result value */
2572 if ((IS_ITEMP(IC_RESULT(ic)) &&
2573 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2574 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2575 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2578 aopOp(IC_RESULT(ic),ic,FALSE);
2581 assignResultValue(IC_RESULT(ic));
2583 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2586 /* if register bank was saved then unsave them */
2587 if (currFunc && dtype &&
2588 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2589 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2591 /* if we hade saved some registers then
2594 unsaveRegisters (ic);
2598 /*-----------------------------------------------------------------*/
2599 /* resultRemat - result is rematerializable */
2600 /*-----------------------------------------------------------------*/
2601 static int resultRemat (iCode *ic)
2603 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2604 if (SKIP_IC(ic) || ic->op == IFX)
2607 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2608 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2609 if (sym->remat && !POINTER_SET(ic))
2616 #if defined(__BORLANDC__) || defined(_MSC_VER)
2617 #define STRCASECMP stricmp
2619 #define STRCASECMP strcasecmp
2623 /*-----------------------------------------------------------------*/
2624 /* inExcludeList - return 1 if the string is in exclude Reg list */
2625 /*-----------------------------------------------------------------*/
2626 static bool inExcludeList(char *s)
2628 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2631 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2632 if (options.excludeRegs[i] &&
2633 STRCASECMP(options.excludeRegs[i],"none") == 0)
2636 for ( i = 0 ; options.excludeRegs[i]; i++) {
2637 if (options.excludeRegs[i] &&
2638 STRCASECMP(s,options.excludeRegs[i]) == 0)
2645 /*-----------------------------------------------------------------*/
2646 /* genFunction - generated code for function entry */
2647 /*-----------------------------------------------------------------*/
2648 static void genFunction (iCode *ic)
2653 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2655 labelOffset += (max_key+4);
2659 /* create the function header */
2660 pic14_emitcode(";","-----------------------------------------");
2661 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2662 pic14_emitcode(";","-----------------------------------------");
2664 pic14_emitcode("","%s:",sym->rname);
2665 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname));
2667 ftype = operandType(IC_LEFT(ic));
2669 /* if critical function then turn interrupts off */
2670 if (IFFUNC_ISCRITICAL(ftype))
2671 pic14_emitcode("clr","ea");
2673 /* here we need to generate the equates for the
2674 register bank if required */
2676 if (FUNC_REGBANK(ftype) != rbank) {
2679 rbank = FUNC_REGBANK(ftype);
2680 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2681 if (strcmp(regspic14[i].base,"0") == 0)
2682 pic14_emitcode("","%s = 0x%02x",
2684 8*rbank+regspic14[i].offset);
2686 pic14_emitcode ("","%s = %s + 0x%02x",
2689 8*rbank+regspic14[i].offset);
2694 /* if this is an interrupt service routine then
2695 save acc, b, dpl, dph */
2696 if (IFFUNC_ISISR(sym->type)) {
2697 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2698 emitpcodeNULLop(POC_NOP);
2699 emitpcodeNULLop(POC_NOP);
2700 emitpcodeNULLop(POC_NOP);
2701 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2702 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2703 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2704 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2706 pBlockConvert2ISR(pb);
2708 if (!inExcludeList("acc"))
2709 pic14_emitcode ("push","acc");
2710 if (!inExcludeList("b"))
2711 pic14_emitcode ("push","b");
2712 if (!inExcludeList("dpl"))
2713 pic14_emitcode ("push","dpl");
2714 if (!inExcludeList("dph"))
2715 pic14_emitcode ("push","dph");
2716 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2718 pic14_emitcode ("push", "dpx");
2719 /* Make sure we're using standard DPTR */
2720 pic14_emitcode ("push", "dps");
2721 pic14_emitcode ("mov", "dps, #0x00");
2722 if (options.stack10bit)
2724 /* This ISR could conceivably use DPTR2. Better save it. */
2725 pic14_emitcode ("push", "dpl1");
2726 pic14_emitcode ("push", "dph1");
2727 pic14_emitcode ("push", "dpx1");
2730 /* if this isr has no bank i.e. is going to
2731 run with bank 0 , then we need to save more
2733 if (!FUNC_REGBANK(sym->type)) {
2735 /* if this function does not call any other
2736 function then we can be economical and
2737 save only those registers that are used */
2738 if (! IFFUNC_HASFCALL(sym->type)) {
2741 /* if any registers used */
2742 if (sym->regsUsed) {
2743 /* save the registers used */
2744 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2745 if (bitVectBitValue(sym->regsUsed,i) ||
2746 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2747 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2752 /* this function has a function call cannot
2753 determines register usage so we will have the
2755 saverbank(0,ic,FALSE);
2760 /* if callee-save to be used for this function
2761 then save the registers being used in this function */
2762 if (IFFUNC_CALLEESAVES(sym->type)) {
2765 /* if any registers used */
2766 if (sym->regsUsed) {
2767 /* save the registers used */
2768 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2769 if (bitVectBitValue(sym->regsUsed,i) ||
2770 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2771 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2779 /* set the register bank to the desired value */
2780 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2781 pic14_emitcode("push","psw");
2782 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2785 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2787 if (options.useXstack) {
2788 pic14_emitcode("mov","r0,%s",spname);
2789 pic14_emitcode("mov","a,_bp");
2790 pic14_emitcode("movx","@r0,a");
2791 pic14_emitcode("inc","%s",spname);
2795 /* set up the stack */
2796 pic14_emitcode ("push","_bp"); /* save the callers stack */
2798 pic14_emitcode ("mov","_bp,%s",spname);
2801 /* adjust the stack for the function */
2806 werror(W_STACK_OVERFLOW,sym->name);
2808 if (i > 3 && sym->recvSize < 4) {
2810 pic14_emitcode ("mov","a,sp");
2811 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2812 pic14_emitcode ("mov","sp,a");
2817 pic14_emitcode("inc","sp");
2822 pic14_emitcode ("mov","a,_spx");
2823 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2824 pic14_emitcode ("mov","_spx,a");
2829 /*-----------------------------------------------------------------*/
2830 /* genEndFunction - generates epilogue for functions */
2831 /*-----------------------------------------------------------------*/
2832 static void genEndFunction (iCode *ic)
2834 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2836 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2838 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2840 pic14_emitcode ("mov","%s,_bp",spname);
2843 /* if use external stack but some variables were
2844 added to the local stack then decrement the
2846 if (options.useXstack && sym->stack) {
2847 pic14_emitcode("mov","a,sp");
2848 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2849 pic14_emitcode("mov","sp,a");
2853 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2854 if (options.useXstack) {
2855 pic14_emitcode("mov","r0,%s",spname);
2856 pic14_emitcode("movx","a,@r0");
2857 pic14_emitcode("mov","_bp,a");
2858 pic14_emitcode("dec","%s",spname);
2862 pic14_emitcode ("pop","_bp");
2866 /* restore the register bank */
2867 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2868 pic14_emitcode ("pop","psw");
2870 if (IFFUNC_ISISR(sym->type)) {
2872 /* now we need to restore the registers */
2873 /* if this isr has no bank i.e. is going to
2874 run with bank 0 , then we need to save more
2876 if (!FUNC_REGBANK(sym->type)) {
2878 /* if this function does not call any other
2879 function then we can be economical and
2880 save only those registers that are used */
2881 if (! IFFUNC_HASFCALL(sym->type)) {
2884 /* if any registers used */
2885 if (sym->regsUsed) {
2886 /* save the registers used */
2887 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2888 if (bitVectBitValue(sym->regsUsed,i) ||
2889 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2890 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2895 /* this function has a function call cannot
2896 determines register usage so we will have the
2898 unsaverbank(0,ic,FALSE);
2902 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2904 if (options.stack10bit)
2906 pic14_emitcode ("pop", "dpx1");
2907 pic14_emitcode ("pop", "dph1");
2908 pic14_emitcode ("pop", "dpl1");
2910 pic14_emitcode ("pop", "dps");
2911 pic14_emitcode ("pop", "dpx");
2913 if (!inExcludeList("dph"))
2914 pic14_emitcode ("pop","dph");
2915 if (!inExcludeList("dpl"))
2916 pic14_emitcode ("pop","dpl");
2917 if (!inExcludeList("b"))
2918 pic14_emitcode ("pop","b");
2919 if (!inExcludeList("acc"))
2920 pic14_emitcode ("pop","acc");
2922 if (IFFUNC_ISCRITICAL(sym->type))
2923 pic14_emitcode("setb","ea");
2926 /* if debug then send end of function */
2927 /* if (options.debug && currFunc) { */
2930 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2931 FileBaseName(ic->filename),currFunc->lastLine,
2932 ic->level,ic->block);
2933 if (IS_STATIC(currFunc->etype))
2934 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2936 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2940 pic14_emitcode ("reti","");
2942 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2943 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2944 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2945 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2946 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2947 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2949 emitpcodeNULLop(POC_RETFIE);
2953 if (IFFUNC_ISCRITICAL(sym->type))
2954 pic14_emitcode("setb","ea");
2956 if (IFFUNC_CALLEESAVES(sym->type)) {
2959 /* if any registers used */
2960 if (sym->regsUsed) {
2961 /* save the registers used */
2962 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2963 if (bitVectBitValue(sym->regsUsed,i) ||
2964 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2965 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2971 /* if debug then send end of function */
2974 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2975 FileBaseName(ic->filename),currFunc->lastLine,
2976 ic->level,ic->block);
2977 if (IS_STATIC(currFunc->etype))
2978 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2980 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2984 pic14_emitcode ("return","");
2985 emitpcodeNULLop(POC_RETURN);
2987 /* Mark the end of a function */
2988 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL));
2993 /*-----------------------------------------------------------------*/
2994 /* genRet - generate code for return statement */
2995 /*-----------------------------------------------------------------*/
2996 static void genRet (iCode *ic)
2998 int size,offset = 0 , pushed = 0;
3000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3001 /* if we have no return value then
3002 just generate the "ret" */
3006 /* we have something to return then
3007 move the return value into place */
3008 aopOp(IC_LEFT(ic),ic,FALSE);
3009 size = AOP_SIZE(IC_LEFT(ic));
3013 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
3015 l = aopGet(AOP(IC_LEFT(ic)),offset++,
3017 pic14_emitcode("push","%s",l);
3020 l = aopGet(AOP(IC_LEFT(ic)),offset,
3022 if (strcmp(fReturn[offset],l)) {
3023 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
3024 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
3025 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
3026 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
3027 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
3029 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
3032 emitpcode(POC_MOVWF,popRegFromIdx(offset + Gstack_base_addr));
3042 if (strcmp(fReturn[pushed],"a"))
3043 pic14_emitcode("pop",fReturn[pushed]);
3045 pic14_emitcode("pop","acc");
3048 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
3051 /* generate a jump to the return label
3052 if the next is not the return statement */
3053 if (!(ic->next && ic->next->op == LABEL &&
3054 IC_LABEL(ic->next) == returnLabel)) {
3056 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3057 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3062 /*-----------------------------------------------------------------*/
3063 /* genLabel - generates a label */
3064 /*-----------------------------------------------------------------*/
3065 static void genLabel (iCode *ic)
3067 /* special case never generate */
3068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3069 if (IC_LABEL(ic) == entryLabel)
3072 emitpLabel(IC_LABEL(ic)->key);
3073 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3076 /*-----------------------------------------------------------------*/
3077 /* genGoto - generates a goto */
3078 /*-----------------------------------------------------------------*/
3080 static void genGoto (iCode *ic)
3082 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3083 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3087 /*-----------------------------------------------------------------*/
3088 /* genMultbits :- multiplication of bits */
3089 /*-----------------------------------------------------------------*/
3090 static void genMultbits (operand *left,
3094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3096 if(!pic14_sameRegs(AOP(result),AOP(right)))
3097 emitpcode(POC_BSF, popGet(AOP(result),0));
3099 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3100 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3101 emitpcode(POC_BCF, popGet(AOP(result),0));
3106 /*-----------------------------------------------------------------*/
3107 /* genMultOneByte : 8 bit multiplication & division */
3108 /*-----------------------------------------------------------------*/
3109 static void genMultOneByte (operand *left,
3113 sym_link *opetype = operandType(result);
3118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3119 DEBUGpic14_AopType(__LINE__,left,right,result);
3120 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3122 /* (if two literals, the value is computed before) */
3123 /* if one literal, literal on the right */
3124 if (AOP_TYPE(left) == AOP_LIT){
3130 size = AOP_SIZE(result);
3133 if (AOP_TYPE(right) == AOP_LIT){
3134 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3135 aopGet(AOP(right),0,FALSE,FALSE),
3136 aopGet(AOP(left),0,FALSE,FALSE),
3137 aopGet(AOP(result),0,FALSE,FALSE));
3138 pic14_emitcode("call","genMultLit");
3140 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3141 aopGet(AOP(right),0,FALSE,FALSE),
3142 aopGet(AOP(left),0,FALSE,FALSE),
3143 aopGet(AOP(result),0,FALSE,FALSE));
3144 pic14_emitcode("call","genMult8X8_8");
3147 genMult8X8_8 (left, right,result);
3150 /* signed or unsigned */
3151 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3152 //l = aopGet(AOP(left),0,FALSE,FALSE);
3154 //pic14_emitcode("mul","ab");
3155 /* if result size = 1, mul signed = mul unsigned */
3156 //aopPut(AOP(result),"a",0);
3158 } else { // (size > 1)
3160 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3161 aopGet(AOP(right),0,FALSE,FALSE),
3162 aopGet(AOP(left),0,FALSE,FALSE),
3163 aopGet(AOP(result),0,FALSE,FALSE));
3165 if (SPEC_USIGN(opetype)){
3166 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3167 genUMult8X8_16 (left, right, result, NULL);
3170 /* for filling the MSBs */
3171 emitpcode(POC_CLRF, popGet(AOP(result),2));
3172 emitpcode(POC_CLRF, popGet(AOP(result),3));
3176 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3178 pic14_emitcode("mov","a,b");
3180 /* adjust the MSB if left or right neg */
3182 /* if one literal */
3183 if (AOP_TYPE(right) == AOP_LIT){
3184 pic14_emitcode("multiply ","right is a lit");
3185 /* AND literal negative */
3186 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3187 /* adjust MSB (c==0 after mul) */
3188 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3192 genSMult8X8_16 (left, right, result, NULL);
3196 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3198 pic14_emitcode("rlc","a");
3199 pic14_emitcode("subb","a,acc");
3207 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3208 //aopPut(AOP(result),"a",offset++);
3212 /*-----------------------------------------------------------------*/
3213 /* genMult - generates code for multiplication */
3214 /*-----------------------------------------------------------------*/
3215 static void genMult (iCode *ic)
3217 operand *left = IC_LEFT(ic);
3218 operand *right = IC_RIGHT(ic);
3219 operand *result= IC_RESULT(ic);
3221 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3222 /* assign the amsops */
3223 aopOp (left,ic,FALSE);
3224 aopOp (right,ic,FALSE);
3225 aopOp (result,ic,TRUE);
3227 DEBUGpic14_AopType(__LINE__,left,right,result);
3229 /* special cases first */
3231 if (AOP_TYPE(left) == AOP_CRY &&
3232 AOP_TYPE(right)== AOP_CRY) {
3233 genMultbits(left,right,result);
3237 /* if both are of size == 1 */
3238 if (AOP_SIZE(left) == 1 &&
3239 AOP_SIZE(right) == 1 ) {
3240 genMultOneByte(left,right,result);
3244 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3246 /* should have been converted to function call */
3250 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3251 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3252 freeAsmop(result,NULL,ic,TRUE);
3255 /*-----------------------------------------------------------------*/
3256 /* genDivbits :- division of bits */
3257 /*-----------------------------------------------------------------*/
3258 static void genDivbits (operand *left,
3265 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3266 /* the result must be bit */
3267 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3268 l = aopGet(AOP(left),0,FALSE,FALSE);
3272 pic14_emitcode("div","ab");
3273 pic14_emitcode("rrc","a");
3274 aopPut(AOP(result),"c",0);
3277 /*-----------------------------------------------------------------*/
3278 /* genDivOneByte : 8 bit division */
3279 /*-----------------------------------------------------------------*/
3280 static void genDivOneByte (operand *left,
3284 sym_link *opetype = operandType(result);
3289 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3290 size = AOP_SIZE(result) - 1;
3292 /* signed or unsigned */
3293 if (SPEC_USIGN(opetype)) {
3294 /* unsigned is easy */
3295 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3296 l = aopGet(AOP(left),0,FALSE,FALSE);
3298 pic14_emitcode("div","ab");
3299 aopPut(AOP(result),"a",0);
3301 aopPut(AOP(result),zero,offset++);
3305 /* signed is a little bit more difficult */
3307 /* save the signs of the operands */
3308 l = aopGet(AOP(left),0,FALSE,FALSE);
3310 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3311 pic14_emitcode("push","acc"); /* save it on the stack */
3313 /* now sign adjust for both left & right */
3314 l = aopGet(AOP(right),0,FALSE,FALSE);
3316 lbl = newiTempLabel(NULL);
3317 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3318 pic14_emitcode("cpl","a");
3319 pic14_emitcode("inc","a");
3320 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3321 pic14_emitcode("mov","b,a");
3323 /* sign adjust left side */
3324 l = aopGet(AOP(left),0,FALSE,FALSE);
3327 lbl = newiTempLabel(NULL);
3328 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3329 pic14_emitcode("cpl","a");
3330 pic14_emitcode("inc","a");
3331 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3333 /* now the division */
3334 pic14_emitcode("div","ab");
3335 /* we are interested in the lower order
3337 pic14_emitcode("mov","b,a");
3338 lbl = newiTempLabel(NULL);
3339 pic14_emitcode("pop","acc");
3340 /* if there was an over flow we don't
3341 adjust the sign of the result */
3342 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3343 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3345 pic14_emitcode("clr","a");
3346 pic14_emitcode("subb","a,b");
3347 pic14_emitcode("mov","b,a");
3348 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3350 /* now we are done */
3351 aopPut(AOP(result),"b",0);
3353 pic14_emitcode("mov","c,b.7");
3354 pic14_emitcode("subb","a,acc");
3357 aopPut(AOP(result),"a",offset++);
3361 /*-----------------------------------------------------------------*/
3362 /* genDiv - generates code for division */
3363 /*-----------------------------------------------------------------*/
3364 static void genDiv (iCode *ic)
3366 operand *left = IC_LEFT(ic);
3367 operand *right = IC_RIGHT(ic);
3368 operand *result= IC_RESULT(ic);
3370 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3371 /* assign the amsops */
3372 aopOp (left,ic,FALSE);
3373 aopOp (right,ic,FALSE);
3374 aopOp (result,ic,TRUE);
3376 /* special cases first */
3378 if (AOP_TYPE(left) == AOP_CRY &&
3379 AOP_TYPE(right)== AOP_CRY) {
3380 genDivbits(left,right,result);
3384 /* if both are of size == 1 */
3385 if (AOP_SIZE(left) == 1 &&
3386 AOP_SIZE(right) == 1 ) {
3387 genDivOneByte(left,right,result);
3391 /* should have been converted to function call */
3394 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3395 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3396 freeAsmop(result,NULL,ic,TRUE);
3399 /*-----------------------------------------------------------------*/
3400 /* genModbits :- modulus of bits */
3401 /*-----------------------------------------------------------------*/
3402 static void genModbits (operand *left,
3409 /* the result must be bit */
3410 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3411 l = aopGet(AOP(left),0,FALSE,FALSE);
3415 pic14_emitcode("div","ab");
3416 pic14_emitcode("mov","a,b");
3417 pic14_emitcode("rrc","a");
3418 aopPut(AOP(result),"c",0);
3421 /*-----------------------------------------------------------------*/
3422 /* genModOneByte : 8 bit modulus */
3423 /*-----------------------------------------------------------------*/
3424 static void genModOneByte (operand *left,
3428 sym_link *opetype = operandType(result);
3432 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3433 /* signed or unsigned */
3434 if (SPEC_USIGN(opetype)) {
3435 /* unsigned is easy */
3436 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3437 l = aopGet(AOP(left),0,FALSE,FALSE);
3439 pic14_emitcode("div","ab");
3440 aopPut(AOP(result),"b",0);
3444 /* signed is a little bit more difficult */
3446 /* save the signs of the operands */
3447 l = aopGet(AOP(left),0,FALSE,FALSE);
3450 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3451 pic14_emitcode("push","acc"); /* save it on the stack */
3453 /* now sign adjust for both left & right */
3454 l = aopGet(AOP(right),0,FALSE,FALSE);
3457 lbl = newiTempLabel(NULL);
3458 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3459 pic14_emitcode("cpl","a");
3460 pic14_emitcode("inc","a");
3461 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3462 pic14_emitcode("mov","b,a");
3464 /* sign adjust left side */
3465 l = aopGet(AOP(left),0,FALSE,FALSE);
3468 lbl = newiTempLabel(NULL);
3469 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3470 pic14_emitcode("cpl","a");
3471 pic14_emitcode("inc","a");
3472 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3474 /* now the multiplication */
3475 pic14_emitcode("div","ab");
3476 /* we are interested in the lower order
3478 lbl = newiTempLabel(NULL);
3479 pic14_emitcode("pop","acc");
3480 /* if there was an over flow we don't
3481 adjust the sign of the result */
3482 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3483 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3485 pic14_emitcode("clr","a");
3486 pic14_emitcode("subb","a,b");
3487 pic14_emitcode("mov","b,a");
3488 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3490 /* now we are done */
3491 aopPut(AOP(result),"b",0);
3495 /*-----------------------------------------------------------------*/
3496 /* genMod - generates code for division */
3497 /*-----------------------------------------------------------------*/
3498 static void genMod (iCode *ic)
3500 operand *left = IC_LEFT(ic);
3501 operand *right = IC_RIGHT(ic);
3502 operand *result= IC_RESULT(ic);
3504 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3505 /* assign the amsops */
3506 aopOp (left,ic,FALSE);
3507 aopOp (right,ic,FALSE);
3508 aopOp (result,ic,TRUE);
3510 /* special cases first */
3512 if (AOP_TYPE(left) == AOP_CRY &&
3513 AOP_TYPE(right)== AOP_CRY) {
3514 genModbits(left,right,result);
3518 /* if both are of size == 1 */
3519 if (AOP_SIZE(left) == 1 &&
3520 AOP_SIZE(right) == 1 ) {
3521 genModOneByte(left,right,result);
3525 /* should have been converted to function call */
3529 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3530 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3531 freeAsmop(result,NULL,ic,TRUE);
3534 /*-----------------------------------------------------------------*/
3535 /* genIfxJump :- will create a jump depending on the ifx */
3536 /*-----------------------------------------------------------------*/
3538 note: May need to add parameter to indicate when a variable is in bit space.
3540 static void genIfxJump (iCode *ic, char *jval)
3543 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3544 /* if true label then we jump if condition
3546 if ( IC_TRUE(ic) ) {
3548 if(strcmp(jval,"a") == 0)
3550 else if (strcmp(jval,"c") == 0)
3553 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3554 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3557 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3558 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3562 /* false label is present */
3563 if(strcmp(jval,"a") == 0)
3565 else if (strcmp(jval,"c") == 0)
3568 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3569 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3572 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3573 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3578 /* mark the icode as generated */
3582 /*-----------------------------------------------------------------*/
3584 /*-----------------------------------------------------------------*/
3585 static void genSkip(iCode *ifx,int status_bit)
3590 if ( IC_TRUE(ifx) ) {
3591 switch(status_bit) {
3606 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3607 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3611 switch(status_bit) {
3625 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3626 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3632 /*-----------------------------------------------------------------*/
3634 /*-----------------------------------------------------------------*/
3635 static void genSkipc(resolvedIfx *rifx)
3645 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3646 rifx->generated = 1;
3649 /*-----------------------------------------------------------------*/
3651 /*-----------------------------------------------------------------*/
3652 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3657 if( (rifx->condition ^ invert_condition) & 1)
3662 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3663 rifx->generated = 1;
3666 /*-----------------------------------------------------------------*/
3668 /*-----------------------------------------------------------------*/
3669 static void genSkipz(iCode *ifx, int condition)
3680 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3682 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3685 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3687 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3690 /*-----------------------------------------------------------------*/
3692 /*-----------------------------------------------------------------*/
3693 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3699 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3701 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3704 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3705 rifx->generated = 1;
3709 /*-----------------------------------------------------------------*/
3710 /* genChkZeroes :- greater or less than comparison */
3711 /* For each byte in a literal that is zero, inclusive or the */
3712 /* the corresponding byte in the operand with W */
3713 /* returns true if any of the bytes are zero */
3714 /*-----------------------------------------------------------------*/
3715 static int genChkZeroes(operand *op, int lit, int size)
3722 i = (lit >> (size*8)) & 0xff;
3726 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3728 emitpcode(POC_IORFW, popGet(AOP(op),size));
3737 /*-----------------------------------------------------------------*/
3738 /* genCmp :- greater or less than comparison */
3739 /*-----------------------------------------------------------------*/
3740 static void genCmp (operand *left,operand *right,
3741 operand *result, iCode *ifx, int sign)
3743 int size; //, offset = 0 ;
3744 unsigned long lit = 0L,i = 0;
3745 resolvedIfx rFalseIfx;
3746 // resolvedIfx rTrueIfx;
3748 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3751 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3752 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3756 resolveIfx(&rFalseIfx,ifx);
3757 truelbl = newiTempLabel(NULL);
3758 size = max(AOP_SIZE(left),AOP_SIZE(right));
3760 DEBUGpic14_AopType(__LINE__,left,right,result);
3764 /* if literal is on the right then swap with left */
3765 if ((AOP_TYPE(right) == AOP_LIT)) {
3766 operand *tmp = right ;
3767 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3768 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3771 lit = (lit - 1) & mask;
3774 rFalseIfx.condition ^= 1;
3777 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3778 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3782 //if(IC_TRUE(ifx) == NULL)
3783 /* if left & right are bit variables */
3784 if (AOP_TYPE(left) == AOP_CRY &&
3785 AOP_TYPE(right) == AOP_CRY ) {
3786 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3787 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3789 /* subtract right from left if at the
3790 end the carry flag is set then we know that
3791 left is greater than right */
3795 symbol *lbl = newiTempLabel(NULL);
3798 if(AOP_TYPE(right) == AOP_LIT) {
3800 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3802 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3809 genSkipCond(&rFalseIfx,left,size-1,7);
3811 /* no need to compare to 0...*/
3812 /* NOTE: this is a de-generate compare that most certainly
3813 * creates some dead code. */
3814 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3816 if(ifx) ifx->generated = 1;
3823 //i = (lit >> (size*8)) & 0xff;
3824 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3826 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3828 i = ((0-lit) & 0xff);
3831 /* lit is 0x7f, all signed chars are less than
3832 * this except for 0x7f itself */
3833 emitpcode(POC_XORLW, popGetLit(0x7f));
3834 genSkipz2(&rFalseIfx,0);
3836 emitpcode(POC_ADDLW, popGetLit(0x80));
3837 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3838 genSkipc(&rFalseIfx);
3843 genSkipz2(&rFalseIfx,1);
3845 emitpcode(POC_ADDLW, popGetLit(i));
3846 genSkipc(&rFalseIfx);
3850 if(ifx) ifx->generated = 1;
3854 /* chars are out of the way. now do ints and longs */
3857 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3864 genSkipCond(&rFalseIfx,left,size,7);
3865 if(ifx) ifx->generated = 1;
3870 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3872 //rFalseIfx.condition ^= 1;
3873 //genSkipCond(&rFalseIfx,left,size,7);
3874 //rFalseIfx.condition ^= 1;
3876 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3877 if(rFalseIfx.condition)
3878 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3880 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3882 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3883 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3884 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3887 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3889 if(rFalseIfx.condition) {
3891 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3897 genSkipc(&rFalseIfx);
3898 emitpLabel(truelbl->key);
3899 if(ifx) ifx->generated = 1;
3906 if( (lit & 0xff) == 0) {
3907 /* lower byte is zero */
3908 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3909 i = ((lit >> 8) & 0xff) ^0x80;
3910 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3911 emitpcode(POC_ADDLW, popGetLit( 0x80));
3912 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3913 genSkipc(&rFalseIfx);
3916 if(ifx) ifx->generated = 1;
3921 /* Special cases for signed longs */
3922 if( (lit & 0xffffff) == 0) {
3923 /* lower byte is zero */
3924 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3925 i = ((lit >> 8*3) & 0xff) ^0x80;
3926 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3927 emitpcode(POC_ADDLW, popGetLit( 0x80));
3928 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3929 genSkipc(&rFalseIfx);
3932 if(ifx) ifx->generated = 1;
3940 if(lit & (0x80 << (size*8))) {
3941 /* lit is negative */
3942 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3944 //genSkipCond(&rFalseIfx,left,size,7);
3946 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3948 if(rFalseIfx.condition)
3949 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3951 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3955 /* lit is positive */
3956 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3957 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3958 if(rFalseIfx.condition)
3959 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3961 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3966 This works, but is only good for ints.
3967 It also requires a "known zero" register.
3968 emitpcode(POC_MOVLW, popGetLit(mlit & 0xff));
3969 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3970 emitpcode(POC_RLFW, popCopyReg(&pc_kzero));
3971 emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff)));
3972 emitpcode(POC_ADDFW, popGet(AOP(left),1));
3973 genSkipc(&rFalseIfx);
3975 emitpLabel(truelbl->key);
3976 if(ifx) ifx->generated = 1;
3980 /* There are no more special cases, so perform a general compare */
3982 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3983 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3987 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3989 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3991 //rFalseIfx.condition ^= 1;
3992 genSkipc(&rFalseIfx);
3994 emitpLabel(truelbl->key);
3996 if(ifx) ifx->generated = 1;
4003 /* sign is out of the way. So now do an unsigned compare */
4004 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
4007 /* General case - compare to an unsigned literal on the right.*/
4009 i = (lit >> (size*8)) & 0xff;
4010 emitpcode(POC_MOVLW, popGetLit(i));
4011 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4013 i = (lit >> (size*8)) & 0xff;
4016 emitpcode(POC_MOVLW, popGetLit(i));
4018 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4020 /* this byte of the lit is zero,
4021 *if it's not the last then OR in the variable */
4023 emitpcode(POC_IORFW, popGet(AOP(left),size));
4028 emitpLabel(lbl->key);
4029 //if(emitFinalCheck)
4030 genSkipc(&rFalseIfx);
4032 emitpLabel(truelbl->key);
4034 if(ifx) ifx->generated = 1;
4041 if(AOP_TYPE(left) == AOP_LIT) {
4042 //symbol *lbl = newiTempLabel(NULL);
4044 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
4047 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
4050 if((lit == 0) && (sign == 0)){
4053 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4055 emitpcode(POC_IORFW, popGet(AOP(right),--size));
4057 genSkipz2(&rFalseIfx,0);
4058 if(ifx) ifx->generated = 1;
4065 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
4066 /* degenerate compare can never be true */
4067 if(rFalseIfx.condition == 0)
4068 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4070 if(ifx) ifx->generated = 1;
4075 /* signed comparisons to a literal byte */
4077 int lp1 = (lit+1) & 0xff;
4079 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4082 rFalseIfx.condition ^= 1;
4083 genSkipCond(&rFalseIfx,right,0,7);
4086 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4087 emitpcode(POC_XORLW, popGetLit(0x7f));
4088 genSkipz2(&rFalseIfx,1);
4091 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4092 emitpcode(POC_ADDLW, popGetLit(0x80));
4093 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4094 rFalseIfx.condition ^= 1;
4095 genSkipc(&rFalseIfx);
4098 if(ifx) ifx->generated = 1;
4100 /* unsigned comparisons to a literal byte */
4102 switch(lit & 0xff ) {
4104 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4105 genSkipz2(&rFalseIfx,0);
4106 if(ifx) ifx->generated = 1;
4109 rFalseIfx.condition ^= 1;
4110 genSkipCond(&rFalseIfx,right,0,7);
4111 if(ifx) ifx->generated = 1;
4115 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4116 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4117 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4118 rFalseIfx.condition ^= 1;
4119 if (AOP_TYPE(result) == AOP_CRY) {
4120 genSkipc(&rFalseIfx);
4121 if(ifx) ifx->generated = 1;
4123 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4124 emitpcode(POC_CLRF, popGet(AOP(result),0));
4125 emitpcode(POC_RLF, popGet(AOP(result),0));
4126 emitpcode(POC_MOVLW, popGetLit(0x01));
4127 emitpcode(POC_XORWF, popGet(AOP(result),0));
4138 /* Size is greater than 1 */
4146 /* this means lit = 0xffffffff, or -1 */
4149 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4150 rFalseIfx.condition ^= 1;
4151 genSkipCond(&rFalseIfx,right,size,7);
4152 if(ifx) ifx->generated = 1;
4159 if(rFalseIfx.condition) {
4160 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4161 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4164 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4166 emitpcode(POC_IORFW, popGet(AOP(right),size));
4170 if(rFalseIfx.condition) {
4171 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4172 emitpLabel(truelbl->key);
4174 rFalseIfx.condition ^= 1;
4175 genSkipCond(&rFalseIfx,right,s,7);
4178 if(ifx) ifx->generated = 1;
4182 if((size == 1) && (0 == (lp1&0xff))) {
4183 /* lower byte of signed word is zero */
4184 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4185 i = ((lp1 >> 8) & 0xff) ^0x80;
4186 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4187 emitpcode(POC_ADDLW, popGetLit( 0x80));
4188 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4189 rFalseIfx.condition ^= 1;
4190 genSkipc(&rFalseIfx);
4193 if(ifx) ifx->generated = 1;
4197 if(lit & (0x80 << (size*8))) {
4198 /* Lit is less than zero */
4199 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4200 //rFalseIfx.condition ^= 1;
4201 //genSkipCond(&rFalseIfx,left,size,7);
4202 //rFalseIfx.condition ^= 1;
4203 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4204 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4206 if(rFalseIfx.condition)
4207 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4209 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4213 /* Lit is greater than or equal to zero */
4214 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4215 //rFalseIfx.condition ^= 1;
4216 //genSkipCond(&rFalseIfx,right,size,7);
4217 //rFalseIfx.condition ^= 1;
4219 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4220 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4222 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4223 if(rFalseIfx.condition)
4224 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4226 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4231 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4232 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4236 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4238 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4240 rFalseIfx.condition ^= 1;
4241 //rFalseIfx.condition = 1;
4242 genSkipc(&rFalseIfx);
4244 emitpLabel(truelbl->key);
4246 if(ifx) ifx->generated = 1;
4251 /* compare word or long to an unsigned literal on the right.*/
4256 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4259 break; /* handled above */
4262 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4264 emitpcode(POC_IORFW, popGet(AOP(right),size));
4265 genSkipz2(&rFalseIfx,0);
4269 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4271 emitpcode(POC_IORFW, popGet(AOP(right),size));
4274 if(rFalseIfx.condition)
4275 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4277 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4280 emitpcode(POC_MOVLW, popGetLit(lit+1));
4281 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4283 rFalseIfx.condition ^= 1;
4284 genSkipc(&rFalseIfx);
4287 emitpLabel(truelbl->key);
4289 if(ifx) ifx->generated = 1;
4295 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4296 i = (lit >> (size*8)) & 0xff;
4298 emitpcode(POC_MOVLW, popGetLit(i));
4299 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4302 i = (lit >> (size*8)) & 0xff;
4305 emitpcode(POC_MOVLW, popGetLit(i));
4307 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4309 /* this byte of the lit is zero,
4310 *if it's not the last then OR in the variable */
4312 emitpcode(POC_IORFW, popGet(AOP(right),size));
4317 emitpLabel(lbl->key);
4319 rFalseIfx.condition ^= 1;
4320 genSkipc(&rFalseIfx);
4324 emitpLabel(truelbl->key);
4325 if(ifx) ifx->generated = 1;
4329 /* Compare two variables */
4331 DEBUGpic14_emitcode(";sign","%d",sign);
4335 /* Sigh. thus sucks... */
4337 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4338 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4339 emitpcode(POC_MOVLW, popGetLit(0x80));
4340 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4341 emitpcode(POC_XORFW, popGet(AOP(right),size));
4342 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4344 /* Signed char comparison */
4345 /* Special thanks to Nikolai Golovchenko for this snippet */
4346 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4347 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4348 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4349 emitpcode(POC_XORFW, popGet(AOP(left),0));
4350 emitpcode(POC_XORFW, popGet(AOP(right),0));
4351 emitpcode(POC_ADDLW, popGetLit(0x80));
4353 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4354 genSkipc(&rFalseIfx);
4356 if(ifx) ifx->generated = 1;
4362 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4363 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4367 /* The rest of the bytes of a multi-byte compare */
4371 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4374 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4375 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4380 emitpLabel(lbl->key);
4382 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4383 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4384 (AOP_TYPE(result) == AOP_REG)) {
4385 emitpcode(POC_CLRF, popGet(AOP(result),0));
4386 emitpcode(POC_RLF, popGet(AOP(result),0));
4388 genSkipc(&rFalseIfx);
4390 //genSkipc(&rFalseIfx);
4391 if(ifx) ifx->generated = 1;
4398 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4399 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4400 pic14_outBitC(result);
4402 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4403 /* if the result is used in the next
4404 ifx conditional branch then generate
4405 code a little differently */
4407 genIfxJump (ifx,"c");
4409 pic14_outBitC(result);
4410 /* leave the result in acc */
4415 /*-----------------------------------------------------------------*/
4416 /* genCmpGt :- greater than comparison */
4417 /*-----------------------------------------------------------------*/
4418 static void genCmpGt (iCode *ic, iCode *ifx)
4420 operand *left, *right, *result;
4421 sym_link *letype , *retype;
4424 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4426 right= IC_RIGHT(ic);
4427 result = IC_RESULT(ic);
4429 letype = getSpec(operandType(left));
4430 retype =getSpec(operandType(right));
4431 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4432 /* assign the amsops */
4433 aopOp (left,ic,FALSE);
4434 aopOp (right,ic,FALSE);
4435 aopOp (result,ic,TRUE);
4437 genCmp(right, left, result, ifx, sign);
4439 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4440 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4441 freeAsmop(result,NULL,ic,TRUE);
4444 /*-----------------------------------------------------------------*/
4445 /* genCmpLt - less than comparisons */
4446 /*-----------------------------------------------------------------*/
4447 static void genCmpLt (iCode *ic, iCode *ifx)
4449 operand *left, *right, *result;
4450 sym_link *letype , *retype;
4453 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4455 right= IC_RIGHT(ic);
4456 result = IC_RESULT(ic);
4458 letype = getSpec(operandType(left));
4459 retype =getSpec(operandType(right));
4460 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4462 /* assign the amsops */
4463 aopOp (left,ic,FALSE);
4464 aopOp (right,ic,FALSE);
4465 aopOp (result,ic,TRUE);
4467 genCmp(left, right, result, ifx, sign);
4469 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4470 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4471 freeAsmop(result,NULL,ic,TRUE);
4474 /*-----------------------------------------------------------------*/
4475 /* genc16bit2lit - compare a 16 bit value to a literal */
4476 /*-----------------------------------------------------------------*/
4477 static void genc16bit2lit(operand *op, int lit, int offset)
4481 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4482 if( (lit&0xff) == 0)
4487 switch( BYTEofLONG(lit,i)) {
4489 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4492 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4495 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4498 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4499 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4504 switch( BYTEofLONG(lit,i)) {
4506 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4510 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4514 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4517 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4519 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4525 /*-----------------------------------------------------------------*/
4526 /* gencjneshort - compare and jump if not equal */
4527 /*-----------------------------------------------------------------*/
4528 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4530 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4532 int res_offset = 0; /* the result may be a different size then left or right */
4533 int res_size = AOP_SIZE(result);
4537 unsigned long lit = 0L;
4538 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4539 DEBUGpic14_AopType(__LINE__,left,right,result);
4541 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4542 resolveIfx(&rIfx,ifx);
4543 lbl = newiTempLabel(NULL);
4546 /* if the left side is a literal or
4547 if the right is in a pointer register and left
4549 if ((AOP_TYPE(left) == AOP_LIT) ||
4550 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4555 if(AOP_TYPE(right) == AOP_LIT)
4556 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4558 /* if the right side is a literal then anything goes */
4559 if (AOP_TYPE(right) == AOP_LIT &&
4560 AOP_TYPE(left) != AOP_DIR ) {
4563 genc16bit2lit(left, lit, 0);
4565 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4570 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4571 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4573 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4577 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4579 if(res_offset < res_size-1)
4587 /* if the right side is in a register or in direct space or
4588 if the left is a pointer register & right is not */
4589 else if (AOP_TYPE(right) == AOP_REG ||
4590 AOP_TYPE(right) == AOP_DIR ||
4591 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4592 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4593 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4594 int lbl_key = lbl->key;
4597 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4598 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4600 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4601 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4602 __FUNCTION__,__LINE__);
4606 /* switch(size) { */
4608 /* genc16bit2lit(left, lit, 0); */
4610 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4615 if((AOP_TYPE(left) == AOP_DIR) &&
4616 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4618 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4619 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4621 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4623 switch (lit & 0xff) {
4625 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4628 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4629 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4630 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4634 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4635 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4636 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4637 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4641 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4642 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4647 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4650 if(AOP_TYPE(result) == AOP_CRY) {
4651 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4656 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4658 /* fix me. probably need to check result size too */
4659 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4664 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4665 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4672 if(res_offset < res_size-1)
4677 } else if(AOP_TYPE(right) == AOP_REG &&
4678 AOP_TYPE(left) != AOP_DIR){
4681 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4682 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4683 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4688 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4690 if(res_offset < res_size-1)
4695 /* right is a pointer reg need both a & b */
4697 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4699 pic14_emitcode("mov","b,%s",l);
4700 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4701 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4706 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4708 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4710 emitpLabel(lbl->key);
4712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4719 /*-----------------------------------------------------------------*/
4720 /* gencjne - compare and jump if not equal */
4721 /*-----------------------------------------------------------------*/
4722 static void gencjne(operand *left, operand *right, iCode *ifx)
4724 symbol *tlbl = newiTempLabel(NULL);
4726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4727 gencjneshort(left, right, lbl);
4729 pic14_emitcode("mov","a,%s",one);
4730 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4731 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4732 pic14_emitcode("clr","a");
4733 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4735 emitpLabel(lbl->key);
4736 emitpLabel(tlbl->key);
4741 /*-----------------------------------------------------------------*/
4742 /* genCmpEq - generates code for equal to */
4743 /*-----------------------------------------------------------------*/
4744 static void genCmpEq (iCode *ic, iCode *ifx)
4746 operand *left, *right, *result;
4747 unsigned long lit = 0L;
4750 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4753 DEBUGpic14_emitcode ("; ifx is non-null","");
4755 DEBUGpic14_emitcode ("; ifx is null","");
4757 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4758 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4759 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4761 size = max(AOP_SIZE(left),AOP_SIZE(right));
4763 DEBUGpic14_AopType(__LINE__,left,right,result);
4765 /* if literal, literal on the right or
4766 if the right is in a pointer register and left
4768 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4769 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4770 operand *tmp = right ;
4776 if(ifx && !AOP_SIZE(result)){
4778 /* if they are both bit variables */
4779 if (AOP_TYPE(left) == AOP_CRY &&
4780 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4781 if(AOP_TYPE(right) == AOP_LIT){
4782 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4784 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4785 pic14_emitcode("cpl","c");
4786 } else if(lit == 1L) {
4787 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4789 pic14_emitcode("clr","c");
4791 /* AOP_TYPE(right) == AOP_CRY */
4793 symbol *lbl = newiTempLabel(NULL);
4794 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4795 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4796 pic14_emitcode("cpl","c");
4797 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4799 /* if true label then we jump if condition
4801 tlbl = newiTempLabel(NULL);
4802 if ( IC_TRUE(ifx) ) {
4803 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4804 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4806 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4807 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4809 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4812 /* left and right are both bit variables, result is carry */
4815 resolveIfx(&rIfx,ifx);
4817 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4818 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4819 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4820 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4825 /* They're not both bit variables. Is the right a literal? */
4826 if(AOP_TYPE(right) == AOP_LIT) {
4827 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4832 switch(lit & 0xff) {
4834 if ( IC_TRUE(ifx) ) {
4835 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4837 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4839 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4840 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4844 if ( IC_TRUE(ifx) ) {
4845 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4847 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4849 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4850 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4854 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4856 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4861 /* end of size == 1 */
4865 genc16bit2lit(left,lit,offset);
4868 /* end of size == 2 */
4873 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4874 emitpcode(POC_IORFW,popGet(AOP(left),1));
4875 emitpcode(POC_IORFW,popGet(AOP(left),2));
4876 emitpcode(POC_IORFW,popGet(AOP(left),3));
4880 /* search for patterns that can be optimized */
4882 genc16bit2lit(left,lit,0);
4885 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4887 genc16bit2lit(left,lit,2);
4889 emitpcode(POC_IORFW,popGet(AOP(left),2));
4890 emitpcode(POC_IORFW,popGet(AOP(left),3));
4903 } else if(AOP_TYPE(right) == AOP_CRY ) {
4904 /* we know the left is not a bit, but that the right is */
4905 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4906 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4907 popGet(AOP(right),offset));
4908 emitpcode(POC_XORLW,popGetLit(1));
4910 /* if the two are equal, then W will be 0 and the Z bit is set
4911 * we could test Z now, or go ahead and check the high order bytes if
4912 * the variable we're comparing is larger than a byte. */
4915 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4917 if ( IC_TRUE(ifx) ) {
4919 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4920 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4923 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4924 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4928 /* They're both variables that are larger than bits */
4931 tlbl = newiTempLabel(NULL);
4934 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4935 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4937 if ( IC_TRUE(ifx) ) {
4940 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4941 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4944 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4945 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4949 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4950 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4954 if(s>1 && IC_TRUE(ifx)) {
4955 emitpLabel(tlbl->key);
4956 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4960 /* mark the icode as generated */
4965 /* if they are both bit variables */
4966 if (AOP_TYPE(left) == AOP_CRY &&
4967 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4968 if(AOP_TYPE(right) == AOP_LIT){
4969 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4971 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4972 pic14_emitcode("cpl","c");
4973 } else if(lit == 1L) {
4974 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4976 pic14_emitcode("clr","c");
4978 /* AOP_TYPE(right) == AOP_CRY */
4980 symbol *lbl = newiTempLabel(NULL);
4981 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4982 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4983 pic14_emitcode("cpl","c");
4984 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4987 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4988 pic14_outBitC(result);
4992 genIfxJump (ifx,"c");
4995 /* if the result is used in an arithmetic operation
4996 then put the result in place */
4997 pic14_outBitC(result);
5000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5001 gencjne(left,right,result,ifx);
5004 gencjne(left,right,newiTempLabel(NULL));
5006 if(IC_TRUE(ifx)->key)
5007 gencjne(left,right,IC_TRUE(ifx)->key);
5009 gencjne(left,right,IC_FALSE(ifx)->key);
5013 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
5014 aopPut(AOP(result),"a",0);
5019 genIfxJump (ifx,"a");
5023 /* if the result is used in an arithmetic operation
5024 then put the result in place */
5026 if (AOP_TYPE(result) != AOP_CRY)
5027 pic14_outAcc(result);
5029 /* leave the result in acc */
5033 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5034 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5035 freeAsmop(result,NULL,ic,TRUE);
5038 /*-----------------------------------------------------------------*/
5039 /* ifxForOp - returns the icode containing the ifx for operand */
5040 /*-----------------------------------------------------------------*/
5041 static iCode *ifxForOp ( operand *op, iCode *ic )
5043 /* if true symbol then needs to be assigned */
5044 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5045 if (IS_TRUE_SYMOP(op))
5048 /* if this has register type condition and
5049 the next instruction is ifx with the same operand
5050 and live to of the operand is upto the ifx only then */
5052 ic->next->op == IFX &&
5053 IC_COND(ic->next)->key == op->key &&
5054 OP_SYMBOL(op)->liveTo <= ic->next->seq )
5058 ic->next->op == IFX &&
5059 IC_COND(ic->next)->key == op->key) {
5060 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
5064 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
5066 ic->next->op == IFX)
5067 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5070 ic->next->op == IFX &&
5071 IC_COND(ic->next)->key == op->key) {
5072 DEBUGpic14_emitcode ("; "," key is okay");
5073 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5074 OP_SYMBOL(op)->liveTo,
5081 /*-----------------------------------------------------------------*/
5082 /* genAndOp - for && operation */
5083 /*-----------------------------------------------------------------*/
5084 static void genAndOp (iCode *ic)
5086 operand *left,*right, *result;
5089 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5090 /* note here that && operations that are in an
5091 if statement are taken away by backPatchLabels
5092 only those used in arthmetic operations remain */
5093 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5094 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5095 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5097 DEBUGpic14_AopType(__LINE__,left,right,result);
5099 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5100 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5101 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5103 /* if both are bit variables */
5104 /* if (AOP_TYPE(left) == AOP_CRY && */
5105 /* AOP_TYPE(right) == AOP_CRY ) { */
5106 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5107 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5108 /* pic14_outBitC(result); */
5110 /* tlbl = newiTempLabel(NULL); */
5111 /* pic14_toBoolean(left); */
5112 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5113 /* pic14_toBoolean(right); */
5114 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5115 /* pic14_outBitAcc(result); */
5118 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5119 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5120 freeAsmop(result,NULL,ic,TRUE);
5124 /*-----------------------------------------------------------------*/
5125 /* genOrOp - for || operation */
5126 /*-----------------------------------------------------------------*/
5129 modified this code, but it doesn't appear to ever get called
5132 static void genOrOp (iCode *ic)
5134 operand *left,*right, *result;
5137 /* note here that || operations that are in an
5138 if statement are taken away by backPatchLabels
5139 only those used in arthmetic operations remain */
5140 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5141 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5142 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5143 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5145 DEBUGpic14_AopType(__LINE__,left,right,result);
5147 /* if both are bit variables */
5148 if (AOP_TYPE(left) == AOP_CRY &&
5149 AOP_TYPE(right) == AOP_CRY ) {
5150 pic14_emitcode("clrc","");
5151 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5152 AOP(left)->aopu.aop_dir,
5153 AOP(left)->aopu.aop_dir);
5154 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5155 AOP(right)->aopu.aop_dir,
5156 AOP(right)->aopu.aop_dir);
5157 pic14_emitcode("setc","");
5160 tlbl = newiTempLabel(NULL);
5161 pic14_toBoolean(left);
5163 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5164 pic14_toBoolean(right);
5165 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5167 pic14_outBitAcc(result);
5170 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5171 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5172 freeAsmop(result,NULL,ic,TRUE);
5175 /*-----------------------------------------------------------------*/
5176 /* isLiteralBit - test if lit == 2^n */
5177 /*-----------------------------------------------------------------*/
5178 static int isLiteralBit(unsigned long lit)
5180 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5181 0x100L,0x200L,0x400L,0x800L,
5182 0x1000L,0x2000L,0x4000L,0x8000L,
5183 0x10000L,0x20000L,0x40000L,0x80000L,
5184 0x100000L,0x200000L,0x400000L,0x800000L,
5185 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5186 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5189 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5190 for(idx = 0; idx < 32; idx++)
5196 /*-----------------------------------------------------------------*/
5197 /* continueIfTrue - */
5198 /*-----------------------------------------------------------------*/
5199 static void continueIfTrue (iCode *ic)
5201 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5203 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5207 /*-----------------------------------------------------------------*/
5209 /*-----------------------------------------------------------------*/
5210 static void jumpIfTrue (iCode *ic)
5212 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5214 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5218 /*-----------------------------------------------------------------*/
5219 /* jmpTrueOrFalse - */
5220 /*-----------------------------------------------------------------*/
5221 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5223 // ugly but optimized by peephole
5224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5226 symbol *nlbl = newiTempLabel(NULL);
5227 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5228 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5229 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5230 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5233 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5234 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5239 /*-----------------------------------------------------------------*/
5240 /* genAnd - code for and */
5241 /*-----------------------------------------------------------------*/
5242 static void genAnd (iCode *ic, iCode *ifx)
5244 operand *left, *right, *result;
5246 unsigned long lit = 0L;
5251 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5252 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5253 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5254 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5256 resolveIfx(&rIfx,ifx);
5258 /* if left is a literal & right is not then exchange them */
5259 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5260 AOP_NEEDSACC(left)) {
5261 operand *tmp = right ;
5266 /* if result = right then exchange them */
5267 if(pic14_sameRegs(AOP(result),AOP(right))){
5268 operand *tmp = right ;
5273 /* if right is bit then exchange them */
5274 if (AOP_TYPE(right) == AOP_CRY &&
5275 AOP_TYPE(left) != AOP_CRY){
5276 operand *tmp = right ;
5280 if(AOP_TYPE(right) == AOP_LIT)
5281 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5283 size = AOP_SIZE(result);
5285 DEBUGpic14_AopType(__LINE__,left,right,result);
5288 // result = bit & yy;
5289 if (AOP_TYPE(left) == AOP_CRY){
5290 // c = bit & literal;
5291 if(AOP_TYPE(right) == AOP_LIT){
5293 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5296 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5299 if(size && (AOP_TYPE(result) == AOP_CRY)){
5300 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5303 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5307 pic14_emitcode("clr","c");
5310 if (AOP_TYPE(right) == AOP_CRY){
5312 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5313 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5316 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5318 pic14_emitcode("rrc","a");
5319 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5325 pic14_outBitC(result);
5327 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5328 genIfxJump(ifx, "c");
5332 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5333 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5334 if((AOP_TYPE(right) == AOP_LIT) &&
5335 (AOP_TYPE(result) == AOP_CRY) &&
5336 (AOP_TYPE(left) != AOP_CRY)){
5337 int posbit = isLiteralBit(lit);
5341 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5344 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5350 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5351 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
5353 emitpcode(POC_BTFSS,newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5354 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
5357 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5358 newpCodeOpBit(aopGet(AOP(left),0,FALSE,FALSE),posbit,0));
5359 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5366 symbol *tlbl = newiTempLabel(NULL);
5367 int sizel = AOP_SIZE(left);
5369 pic14_emitcode("setb","c");
5371 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5372 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5374 if((posbit = isLiteralBit(bytelit)) != 0)
5375 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5377 if(bytelit != 0x0FFL)
5378 pic14_emitcode("anl","a,%s",
5379 aopGet(AOP(right),offset,FALSE,TRUE));
5380 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5385 // bit = left & literal
5387 pic14_emitcode("clr","c");
5388 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5390 // if(left & literal)
5393 jmpTrueOrFalse(ifx, tlbl);
5397 pic14_outBitC(result);
5401 /* if left is same as result */
5402 if(pic14_sameRegs(AOP(result),AOP(left))){
5404 for(;size--; offset++,lit>>=8) {
5405 if(AOP_TYPE(right) == AOP_LIT){
5406 switch(lit & 0xff) {
5408 /* and'ing with 0 has clears the result */
5409 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5410 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5413 /* and'ing with 0xff is a nop when the result and left are the same */
5418 int p = my_powof2( (~lit) & 0xff );
5420 /* only one bit is set in the literal, so use a bcf instruction */
5421 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5422 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5425 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5426 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5427 if(know_W != (lit&0xff))
5428 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5430 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5435 if (AOP_TYPE(left) == AOP_ACC) {
5436 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5438 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5439 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5446 // left & result in different registers
5447 if(AOP_TYPE(result) == AOP_CRY){
5449 // if(size), result in bit
5450 // if(!size && ifx), conditional oper: if(left & right)
5451 symbol *tlbl = newiTempLabel(NULL);
5452 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5454 pic14_emitcode("setb","c");
5456 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5457 pic14_emitcode("anl","a,%s",
5458 aopGet(AOP(left),offset,FALSE,FALSE));
5459 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5464 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5465 pic14_outBitC(result);
5467 jmpTrueOrFalse(ifx, tlbl);
5469 for(;(size--);offset++) {
5471 // result = left & right
5472 if(AOP_TYPE(right) == AOP_LIT){
5473 int t = (lit >> (offset*8)) & 0x0FFL;
5476 pic14_emitcode("clrf","%s",
5477 aopGet(AOP(result),offset,FALSE,FALSE));
5478 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5481 if(AOP_TYPE(left) != AOP_ACC) {
5482 pic14_emitcode("movf","%s,w",
5483 aopGet(AOP(left),offset,FALSE,FALSE));
5484 pic14_emitcode("movwf","%s",
5485 aopGet(AOP(result),offset,FALSE,FALSE));
5486 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5488 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5491 if(AOP_TYPE(left) == AOP_ACC) {
5492 emitpcode(POC_ANDLW, popGetLit(t));
5494 pic14_emitcode("movlw","0x%x",t);
5495 pic14_emitcode("andwf","%s,w",
5496 aopGet(AOP(left),offset,FALSE,FALSE));
5497 pic14_emitcode("movwf","%s",
5498 aopGet(AOP(result),offset,FALSE,FALSE));
5500 emitpcode(POC_MOVLW, popGetLit(t));
5501 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5503 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5508 if (AOP_TYPE(left) == AOP_ACC) {
5509 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5510 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5512 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5513 pic14_emitcode("andwf","%s,w",
5514 aopGet(AOP(left),offset,FALSE,FALSE));
5515 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5516 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5518 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5519 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5525 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5526 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5527 freeAsmop(result,NULL,ic,TRUE);
5530 /*-----------------------------------------------------------------*/
5531 /* genOr - code for or */
5532 /*-----------------------------------------------------------------*/
5533 static void genOr (iCode *ic, iCode *ifx)
5535 operand *left, *right, *result;
5537 unsigned long lit = 0L;
5539 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5541 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5542 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5543 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5545 DEBUGpic14_AopType(__LINE__,left,right,result);
5547 /* if left is a literal & right is not then exchange them */
5548 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5549 AOP_NEEDSACC(left)) {
5550 operand *tmp = right ;
5555 /* if result = right then exchange them */
5556 if(pic14_sameRegs(AOP(result),AOP(right))){
5557 operand *tmp = right ;
5562 /* if right is bit then exchange them */
5563 if (AOP_TYPE(right) == AOP_CRY &&
5564 AOP_TYPE(left) != AOP_CRY){
5565 operand *tmp = right ;
5570 DEBUGpic14_AopType(__LINE__,left,right,result);
5572 if(AOP_TYPE(right) == AOP_LIT)
5573 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5575 size = AOP_SIZE(result);
5579 if (AOP_TYPE(left) == AOP_CRY){
5580 if(AOP_TYPE(right) == AOP_LIT){
5581 // c = bit & literal;
5583 // lit != 0 => result = 1
5584 if(AOP_TYPE(result) == AOP_CRY){
5586 emitpcode(POC_BSF, popGet(AOP(result),0));
5587 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5588 // AOP(result)->aopu.aop_dir,
5589 // AOP(result)->aopu.aop_dir);
5591 continueIfTrue(ifx);
5595 // lit == 0 => result = left
5596 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5598 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5601 if (AOP_TYPE(right) == AOP_CRY){
5602 if(pic14_sameRegs(AOP(result),AOP(left))){
5604 emitpcode(POC_BCF, popGet(AOP(result),0));
5605 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5606 emitpcode(POC_BSF, popGet(AOP(result),0));
5608 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5609 AOP(result)->aopu.aop_dir,
5610 AOP(result)->aopu.aop_dir);
5611 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5612 AOP(right)->aopu.aop_dir,
5613 AOP(right)->aopu.aop_dir);
5614 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5615 AOP(result)->aopu.aop_dir,
5616 AOP(result)->aopu.aop_dir);
5618 if( AOP_TYPE(result) == AOP_ACC) {
5619 emitpcode(POC_MOVLW, popGetLit(0));
5620 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5621 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5622 emitpcode(POC_MOVLW, popGetLit(1));
5626 emitpcode(POC_BCF, popGet(AOP(result),0));
5627 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5628 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5629 emitpcode(POC_BSF, popGet(AOP(result),0));
5631 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5632 AOP(result)->aopu.aop_dir,
5633 AOP(result)->aopu.aop_dir);
5634 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5635 AOP(right)->aopu.aop_dir,
5636 AOP(right)->aopu.aop_dir);
5637 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5638 AOP(left)->aopu.aop_dir,
5639 AOP(left)->aopu.aop_dir);
5640 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5641 AOP(result)->aopu.aop_dir,
5642 AOP(result)->aopu.aop_dir);
5647 symbol *tlbl = newiTempLabel(NULL);
5648 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5651 emitpcode(POC_BCF, popGet(AOP(result),0));
5652 if( AOP_TYPE(right) == AOP_ACC) {
5653 emitpcode(POC_IORLW, popGetLit(0));
5655 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5656 emitpcode(POC_BSF, popGet(AOP(result),0));
5661 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5662 pic14_emitcode(";XXX setb","c");
5663 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5664 AOP(left)->aopu.aop_dir,tlbl->key+100);
5665 pic14_toBoolean(right);
5666 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5667 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5668 jmpTrueOrFalse(ifx, tlbl);
5672 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5679 pic14_outBitC(result);
5681 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5682 genIfxJump(ifx, "c");
5686 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5687 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5688 if((AOP_TYPE(right) == AOP_LIT) &&
5689 (AOP_TYPE(result) == AOP_CRY) &&
5690 (AOP_TYPE(left) != AOP_CRY)){
5692 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5695 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5697 continueIfTrue(ifx);
5700 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5701 // lit = 0, result = boolean(left)
5703 pic14_emitcode(";XXX setb","c");
5704 pic14_toBoolean(right);
5706 symbol *tlbl = newiTempLabel(NULL);
5707 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5709 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5711 genIfxJump (ifx,"a");
5715 pic14_outBitC(result);
5719 /* if left is same as result */
5720 if(pic14_sameRegs(AOP(result),AOP(left))){
5722 for(;size--; offset++,lit>>=8) {
5723 if(AOP_TYPE(right) == AOP_LIT){
5724 if((lit & 0xff) == 0)
5725 /* or'ing with 0 has no effect */
5728 int p = my_powof2(lit & 0xff);
5730 /* only one bit is set in the literal, so use a bsf instruction */
5732 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5734 if(know_W != (lit & 0xff))
5735 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5736 know_W = lit & 0xff;
5737 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5742 if (AOP_TYPE(left) == AOP_ACC) {
5743 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5744 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5746 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5747 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5749 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5750 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5756 // left & result in different registers
5757 if(AOP_TYPE(result) == AOP_CRY){
5759 // if(size), result in bit
5760 // if(!size && ifx), conditional oper: if(left | right)
5761 symbol *tlbl = newiTempLabel(NULL);
5762 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5763 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5767 pic14_emitcode(";XXX setb","c");
5769 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5770 pic14_emitcode(";XXX orl","a,%s",
5771 aopGet(AOP(left),offset,FALSE,FALSE));
5772 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5777 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5778 pic14_outBitC(result);
5780 jmpTrueOrFalse(ifx, tlbl);
5781 } else for(;(size--);offset++){
5783 // result = left & right
5784 if(AOP_TYPE(right) == AOP_LIT){
5785 int t = (lit >> (offset*8)) & 0x0FFL;
5788 if (AOP_TYPE(left) != AOP_ACC) {
5789 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5791 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5795 if (AOP_TYPE(left) == AOP_ACC) {
5796 emitpcode(POC_IORLW, popGetLit(t));
5798 emitpcode(POC_MOVLW, popGetLit(t));
5799 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5801 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5806 // faster than result <- left, anl result,right
5807 // and better if result is SFR
5808 if (AOP_TYPE(left) == AOP_ACC) {
5809 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5810 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5812 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5813 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5815 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5816 pic14_emitcode("iorwf","%s,w",
5817 aopGet(AOP(left),offset,FALSE,FALSE));
5819 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5820 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5825 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5826 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5827 freeAsmop(result,NULL,ic,TRUE);
5830 /*-----------------------------------------------------------------*/
5831 /* genXor - code for xclusive or */
5832 /*-----------------------------------------------------------------*/
5833 static void genXor (iCode *ic, iCode *ifx)
5835 operand *left, *right, *result;
5837 unsigned long lit = 0L;
5839 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5841 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5842 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5843 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5845 /* if left is a literal & right is not ||
5846 if left needs acc & right does not */
5847 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5848 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5849 operand *tmp = right ;
5854 /* if result = right then exchange them */
5855 if(pic14_sameRegs(AOP(result),AOP(right))){
5856 operand *tmp = right ;
5861 /* if right is bit then exchange them */
5862 if (AOP_TYPE(right) == AOP_CRY &&
5863 AOP_TYPE(left) != AOP_CRY){
5864 operand *tmp = right ;
5868 if(AOP_TYPE(right) == AOP_LIT)
5869 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5871 size = AOP_SIZE(result);
5875 if (AOP_TYPE(left) == AOP_CRY){
5876 if(AOP_TYPE(right) == AOP_LIT){
5877 // c = bit & literal;
5879 // lit>>1 != 0 => result = 1
5880 if(AOP_TYPE(result) == AOP_CRY){
5882 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5883 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5885 continueIfTrue(ifx);
5888 pic14_emitcode("setb","c");
5892 // lit == 0, result = left
5893 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5895 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5897 // lit == 1, result = not(left)
5898 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5899 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5900 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5901 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5904 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5905 pic14_emitcode("cpl","c");
5912 symbol *tlbl = newiTempLabel(NULL);
5913 if (AOP_TYPE(right) == AOP_CRY){
5915 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5918 int sizer = AOP_SIZE(right);
5920 // if val>>1 != 0, result = 1
5921 pic14_emitcode("setb","c");
5923 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5925 // test the msb of the lsb
5926 pic14_emitcode("anl","a,#0xfe");
5927 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5931 pic14_emitcode("rrc","a");
5933 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5934 pic14_emitcode("cpl","c");
5935 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5940 pic14_outBitC(result);
5942 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5943 genIfxJump(ifx, "c");
5947 if(pic14_sameRegs(AOP(result),AOP(left))){
5948 /* if left is same as result */
5949 for(;size--; offset++) {
5950 if(AOP_TYPE(right) == AOP_LIT){
5951 int t = (lit >> (offset*8)) & 0x0FFL;
5955 if (IS_AOP_PREG(left)) {
5956 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5957 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5958 aopPut(AOP(result),"a",offset);
5960 emitpcode(POC_MOVLW, popGetLit(t));
5961 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5962 pic14_emitcode("xrl","%s,%s",
5963 aopGet(AOP(left),offset,FALSE,TRUE),
5964 aopGet(AOP(right),offset,FALSE,FALSE));
5967 if (AOP_TYPE(left) == AOP_ACC)
5968 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5970 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5971 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5973 if (IS_AOP_PREG(left)) {
5974 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5975 aopPut(AOP(result),"a",offset);
5977 pic14_emitcode("xrl","%s,a",
5978 aopGet(AOP(left),offset,FALSE,TRUE));
5984 // left & result in different registers
5985 if(AOP_TYPE(result) == AOP_CRY){
5987 // if(size), result in bit
5988 // if(!size && ifx), conditional oper: if(left ^ right)
5989 symbol *tlbl = newiTempLabel(NULL);
5990 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5992 pic14_emitcode("setb","c");
5994 if((AOP_TYPE(right) == AOP_LIT) &&
5995 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5996 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5998 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5999 pic14_emitcode("xrl","a,%s",
6000 aopGet(AOP(left),offset,FALSE,FALSE));
6002 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
6007 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6008 pic14_outBitC(result);
6010 jmpTrueOrFalse(ifx, tlbl);
6011 } else for(;(size--);offset++){
6013 // result = left & right
6014 if(AOP_TYPE(right) == AOP_LIT){
6015 int t = (lit >> (offset*8)) & 0x0FFL;
6018 if (AOP_TYPE(left) != AOP_ACC) {
6019 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
6021 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6022 pic14_emitcode("movf","%s,w",
6023 aopGet(AOP(left),offset,FALSE,FALSE));
6024 pic14_emitcode("movwf","%s",
6025 aopGet(AOP(result),offset,FALSE,FALSE));
6028 if (AOP_TYPE(left) == AOP_ACC) {
6029 emitpcode(POC_XORLW, popGetLit(t));
6031 emitpcode(POC_COMFW,popGet(AOP(left),offset));
6033 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6036 if (AOP_TYPE(left) == AOP_ACC) {
6037 emitpcode(POC_XORLW, popGetLit(t));
6039 emitpcode(POC_MOVLW, popGetLit(t));
6040 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6042 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6043 pic14_emitcode("movlw","0x%x",t);
6044 pic14_emitcode("xorwf","%s,w",
6045 aopGet(AOP(left),offset,FALSE,FALSE));
6046 pic14_emitcode("movwf","%s",
6047 aopGet(AOP(result),offset,FALSE,FALSE));
6053 // faster than result <- left, anl result,right
6054 // and better if result is SFR
6055 if (AOP_TYPE(left) == AOP_ACC) {
6056 emitpcode(POC_XORFW,popGet(AOP(right),offset));
6057 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6059 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
6060 emitpcode(POC_XORFW,popGet(AOP(left),offset));
6061 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
6062 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
6064 if ( AOP_TYPE(result) != AOP_ACC){
6065 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
6066 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
6072 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6073 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6074 freeAsmop(result,NULL,ic,TRUE);
6077 /*-----------------------------------------------------------------*/
6078 /* genInline - write the inline code out */
6079 /*-----------------------------------------------------------------*/
6080 static void genInline (iCode *ic)
6082 char *buffer, *bp, *bp1;
6084 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6086 _G.inLine += (!options.asmpeep);
6088 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6089 strcpy(buffer,IC_INLINE(ic));
6091 /* emit each line as a code */
6097 addpCode2pBlock(pb,AssembleLine(bp1));
6104 pic14_emitcode(bp1,"");
6110 if ((bp1 != bp) && *bp1)
6111 addpCode2pBlock(pb,AssembleLine(bp1));
6115 _G.inLine -= (!options.asmpeep);
6118 /*-----------------------------------------------------------------*/
6119 /* genRRC - rotate right with carry */
6120 /*-----------------------------------------------------------------*/
6121 static void genRRC (iCode *ic)
6123 operand *left , *result ;
6124 int size, offset = 0, same;
6126 /* rotate right with carry */
6128 result=IC_RESULT(ic);
6129 aopOp (left,ic,FALSE);
6130 aopOp (result,ic,FALSE);
6132 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6134 same = pic14_sameRegs(AOP(result),AOP(left));
6136 size = AOP_SIZE(result);
6138 /* get the lsb and put it into the carry */
6139 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6146 emitpcode(POC_RRF, popGet(AOP(left),offset));
6148 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6149 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6155 freeAsmop(left,NULL,ic,TRUE);
6156 freeAsmop(result,NULL,ic,TRUE);
6159 /*-----------------------------------------------------------------*/
6160 /* genRLC - generate code for rotate left with carry */
6161 /*-----------------------------------------------------------------*/
6162 static void genRLC (iCode *ic)
6164 operand *left , *result ;
6165 int size, offset = 0;
6168 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6169 /* rotate right with carry */
6171 result=IC_RESULT(ic);
6172 aopOp (left,ic,FALSE);
6173 aopOp (result,ic,FALSE);
6175 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6177 same = pic14_sameRegs(AOP(result),AOP(left));
6179 /* move it to the result */
6180 size = AOP_SIZE(result);
6182 /* get the msb and put it into the carry */
6183 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6190 emitpcode(POC_RLF, popGet(AOP(left),offset));
6192 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6193 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6200 freeAsmop(left,NULL,ic,TRUE);
6201 freeAsmop(result,NULL,ic,TRUE);
6204 /*-----------------------------------------------------------------*/
6205 /* genGetHbit - generates code get highest order bit */
6206 /*-----------------------------------------------------------------*/
6207 static void genGetHbit (iCode *ic)
6209 operand *left, *result;
6211 result=IC_RESULT(ic);
6212 aopOp (left,ic,FALSE);
6213 aopOp (result,ic,FALSE);
6215 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6216 /* get the highest order byte into a */
6217 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6218 if(AOP_TYPE(result) == AOP_CRY){
6219 pic14_emitcode("rlc","a");
6220 pic14_outBitC(result);
6223 pic14_emitcode("rl","a");
6224 pic14_emitcode("anl","a,#0x01");
6225 pic14_outAcc(result);
6229 freeAsmop(left,NULL,ic,TRUE);
6230 freeAsmop(result,NULL,ic,TRUE);
6233 /*-----------------------------------------------------------------*/
6234 /* AccRol - rotate left accumulator by known count */
6235 /*-----------------------------------------------------------------*/
6236 static void AccRol (int shCount)
6238 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6239 shCount &= 0x0007; // shCount : 0..7
6244 pic14_emitcode("rl","a");
6247 pic14_emitcode("rl","a");
6248 pic14_emitcode("rl","a");
6251 pic14_emitcode("swap","a");
6252 pic14_emitcode("rr","a");
6255 pic14_emitcode("swap","a");
6258 pic14_emitcode("swap","a");
6259 pic14_emitcode("rl","a");
6262 pic14_emitcode("rr","a");
6263 pic14_emitcode("rr","a");
6266 pic14_emitcode("rr","a");
6271 /*-----------------------------------------------------------------*/
6272 /* AccLsh - left shift accumulator by known count */
6273 /*-----------------------------------------------------------------*/
6274 static void AccLsh (int shCount)
6276 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6279 pic14_emitcode("add","a,acc");
6282 pic14_emitcode("add","a,acc");
6283 pic14_emitcode("add","a,acc");
6285 /* rotate left accumulator */
6287 /* and kill the lower order bits */
6288 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6293 /*-----------------------------------------------------------------*/
6294 /* AccRsh - right shift accumulator by known count */
6295 /*-----------------------------------------------------------------*/
6296 static void AccRsh (int shCount)
6298 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6302 pic14_emitcode("rrc","a");
6304 /* rotate right accumulator */
6305 AccRol(8 - shCount);
6306 /* and kill the higher order bits */
6307 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6313 /*-----------------------------------------------------------------*/
6314 /* AccSRsh - signed right shift accumulator by known count */
6315 /*-----------------------------------------------------------------*/
6316 static void AccSRsh (int shCount)
6319 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6322 pic14_emitcode("mov","c,acc.7");
6323 pic14_emitcode("rrc","a");
6324 } else if(shCount == 2){
6325 pic14_emitcode("mov","c,acc.7");
6326 pic14_emitcode("rrc","a");
6327 pic14_emitcode("mov","c,acc.7");
6328 pic14_emitcode("rrc","a");
6330 tlbl = newiTempLabel(NULL);
6331 /* rotate right accumulator */
6332 AccRol(8 - shCount);
6333 /* and kill the higher order bits */
6334 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6335 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6336 pic14_emitcode("orl","a,#0x%02x",
6337 (unsigned char)~SRMask[shCount]);
6338 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6343 /*-----------------------------------------------------------------*/
6344 /* shiftR1Left2Result - shift right one byte from left to result */
6345 /*-----------------------------------------------------------------*/
6346 static void shiftR1Left2ResultSigned (operand *left, int offl,
6347 operand *result, int offr,
6352 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6354 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6358 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6360 emitpcode(POC_RRF, popGet(AOP(result),offr));
6362 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6363 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6369 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6371 emitpcode(POC_RRF, popGet(AOP(result),offr));
6373 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6374 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6376 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6377 emitpcode(POC_RRF, popGet(AOP(result),offr));
6383 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6385 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6386 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6389 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6390 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6391 emitpcode(POC_ANDLW, popGetLit(0x1f));
6393 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6394 emitpcode(POC_IORLW, popGetLit(0xe0));
6396 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6400 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6401 emitpcode(POC_ANDLW, popGetLit(0x0f));
6402 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6403 emitpcode(POC_IORLW, popGetLit(0xf0));
6404 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6408 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6410 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6411 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6413 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6414 emitpcode(POC_ANDLW, popGetLit(0x07));
6415 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6416 emitpcode(POC_IORLW, popGetLit(0xf8));
6417 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6422 emitpcode(POC_MOVLW, popGetLit(0x00));
6423 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6424 emitpcode(POC_MOVLW, popGetLit(0xfe));
6425 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6426 emitpcode(POC_IORLW, popGetLit(0x01));
6427 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6429 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6430 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6431 emitpcode(POC_DECF, popGet(AOP(result),offr));
6432 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6433 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6439 emitpcode(POC_MOVLW, popGetLit(0x00));
6440 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6441 emitpcode(POC_MOVLW, popGetLit(0xff));
6442 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6444 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6445 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6446 emitpcode(POC_DECF, popGet(AOP(result),offr));
6454 /*-----------------------------------------------------------------*/
6455 /* shiftR1Left2Result - shift right one byte from left to result */
6456 /*-----------------------------------------------------------------*/
6457 static void shiftR1Left2Result (operand *left, int offl,
6458 operand *result, int offr,
6459 int shCount, int sign)
6463 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6465 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6467 /* Copy the msb into the carry if signed. */
6469 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6479 emitpcode(POC_RRF, popGet(AOP(result),offr));
6481 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6482 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6488 emitpcode(POC_RRF, popGet(AOP(result),offr));
6490 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6491 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6494 emitpcode(POC_RRF, popGet(AOP(result),offr));
6499 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6501 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6502 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6505 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6506 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6507 emitpcode(POC_ANDLW, popGetLit(0x1f));
6508 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6512 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6513 emitpcode(POC_ANDLW, popGetLit(0x0f));
6514 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6518 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6519 emitpcode(POC_ANDLW, popGetLit(0x0f));
6520 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6522 emitpcode(POC_RRF, popGet(AOP(result),offr));
6527 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6528 emitpcode(POC_ANDLW, popGetLit(0x80));
6529 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6530 emitpcode(POC_RLF, popGet(AOP(result),offr));
6531 emitpcode(POC_RLF, popGet(AOP(result),offr));
6536 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6537 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6538 emitpcode(POC_RLF, popGet(AOP(result),offr));
6547 /*-----------------------------------------------------------------*/
6548 /* shiftL1Left2Result - shift left one byte from left to result */
6549 /*-----------------------------------------------------------------*/
6550 static void shiftL1Left2Result (operand *left, int offl,
6551 operand *result, int offr, int shCount)
6556 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6558 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6559 DEBUGpic14_emitcode ("; ***","same = %d",same);
6560 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6562 /* shift left accumulator */
6563 //AccLsh(shCount); // don't comment out just yet...
6564 // aopPut(AOP(result),"a",offr);
6568 /* Shift left 1 bit position */
6569 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6571 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6573 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6574 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6578 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6579 emitpcode(POC_ANDLW,popGetLit(0x7e));
6580 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6581 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6584 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6585 emitpcode(POC_ANDLW,popGetLit(0x3e));
6586 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6587 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6588 emitpcode(POC_RLF, popGet(AOP(result),offr));
6591 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6592 emitpcode(POC_ANDLW, popGetLit(0xf0));
6593 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6596 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6597 emitpcode(POC_ANDLW, popGetLit(0xf0));
6598 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6599 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6602 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6603 emitpcode(POC_ANDLW, popGetLit(0x30));
6604 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6605 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6606 emitpcode(POC_RLF, popGet(AOP(result),offr));
6609 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6610 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6611 emitpcode(POC_RRF, popGet(AOP(result),offr));
6615 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6620 /*-----------------------------------------------------------------*/
6621 /* movLeft2Result - move byte from left to result */
6622 /*-----------------------------------------------------------------*/
6623 static void movLeft2Result (operand *left, int offl,
6624 operand *result, int offr)
6627 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6628 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6629 l = aopGet(AOP(left),offl,FALSE,FALSE);
6631 if (*l == '@' && (IS_AOP_PREG(result))) {
6632 pic14_emitcode("mov","a,%s",l);
6633 aopPut(AOP(result),"a",offr);
6635 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6636 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6641 /*-----------------------------------------------------------------*/
6642 /* shiftL2Left2Result - shift left two bytes from left to result */
6643 /*-----------------------------------------------------------------*/
6644 static void shiftL2Left2Result (operand *left, int offl,
6645 operand *result, int offr, int shCount)
6649 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6651 if(pic14_sameRegs(AOP(result), AOP(left))) {
6659 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6660 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6661 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6665 emitpcode(POC_RLF, popGet(AOP(result),offr));
6666 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6672 emitpcode(POC_MOVLW, popGetLit(0x0f));
6673 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6674 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6675 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6676 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6677 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6678 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6680 emitpcode(POC_RLF, popGet(AOP(result),offr));
6681 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6685 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6686 emitpcode(POC_RRF, popGet(AOP(result),offr));
6687 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6688 emitpcode(POC_RRF, popGet(AOP(result),offr));
6689 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6690 emitpcode(POC_ANDLW,popGetLit(0xc0));
6691 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6692 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6693 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6694 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6697 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6698 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6699 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6700 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6701 emitpcode(POC_RRF, popGet(AOP(result),offr));
6711 /* note, use a mov/add for the shift since the mov has a
6712 chance of getting optimized out */
6713 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6714 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6715 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6716 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6717 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6721 emitpcode(POC_RLF, popGet(AOP(result),offr));
6722 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6728 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6729 emitpcode(POC_ANDLW, popGetLit(0xF0));
6730 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6731 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6732 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6733 emitpcode(POC_ANDLW, popGetLit(0xF0));
6734 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6735 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6739 emitpcode(POC_RLF, popGet(AOP(result),offr));
6740 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6744 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6745 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6746 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6747 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6749 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_RRF, popGet(AOP(result),offr));
6751 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6752 emitpcode(POC_ANDLW,popGetLit(0xc0));
6753 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6754 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6755 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6756 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6759 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6760 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6761 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6762 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6763 emitpcode(POC_RRF, popGet(AOP(result),offr));
6768 /*-----------------------------------------------------------------*/
6769 /* shiftR2Left2Result - shift right two bytes from left to result */
6770 /*-----------------------------------------------------------------*/
6771 static void shiftR2Left2Result (operand *left, int offl,
6772 operand *result, int offr,
6773 int shCount, int sign)
6777 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6778 same = pic14_sameRegs(AOP(result), AOP(left));
6780 if(same && ((offl + MSB16) == offr)){
6782 /* don't crash result[offr] */
6783 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6784 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6787 movLeft2Result(left,offl, result, offr);
6788 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6791 /* a:x >> shCount (x = lsb(result))*/
6794 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6796 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6805 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6810 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6811 emitpcode(POC_RRF,popGet(AOP(result),offr));
6813 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6814 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6815 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6816 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6821 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6824 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6825 emitpcode(POC_RRF,popGet(AOP(result),offr));
6832 emitpcode(POC_MOVLW, popGetLit(0xf0));
6833 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6834 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6836 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6837 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6838 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6839 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6841 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6842 emitpcode(POC_ANDLW, popGetLit(0x0f));
6843 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6845 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6846 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6847 emitpcode(POC_ANDLW, popGetLit(0xf0));
6848 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6849 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6853 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6854 emitpcode(POC_RRF, popGet(AOP(result),offr));
6858 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6859 emitpcode(POC_BTFSC,
6860 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6861 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6869 emitpcode(POC_RLF, popGet(AOP(result),offr));
6870 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6872 emitpcode(POC_RLF, popGet(AOP(result),offr));
6873 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6874 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6875 emitpcode(POC_ANDLW,popGetLit(0x03));
6877 emitpcode(POC_BTFSC,
6878 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6879 emitpcode(POC_IORLW,popGetLit(0xfc));
6881 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6882 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6883 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6884 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6886 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6887 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6888 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6889 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6890 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6891 emitpcode(POC_RLF, popGet(AOP(result),offr));
6892 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6893 emitpcode(POC_ANDLW,popGetLit(0x03));
6895 emitpcode(POC_BTFSC,
6896 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6897 emitpcode(POC_IORLW,popGetLit(0xfc));
6899 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6900 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6907 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6908 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6909 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6910 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6913 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6915 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6920 /*-----------------------------------------------------------------*/
6921 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6922 /*-----------------------------------------------------------------*/
6923 static void shiftLLeftOrResult (operand *left, int offl,
6924 operand *result, int offr, int shCount)
6926 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6927 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6928 /* shift left accumulator */
6930 /* or with result */
6931 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6932 /* back to result */
6933 aopPut(AOP(result),"a",offr);
6936 /*-----------------------------------------------------------------*/
6937 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6938 /*-----------------------------------------------------------------*/
6939 static void shiftRLeftOrResult (operand *left, int offl,
6940 operand *result, int offr, int shCount)
6942 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6943 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6944 /* shift right accumulator */
6946 /* or with result */
6947 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6948 /* back to result */
6949 aopPut(AOP(result),"a",offr);
6952 /*-----------------------------------------------------------------*/
6953 /* genlshOne - left shift a one byte quantity by known count */
6954 /*-----------------------------------------------------------------*/
6955 static void genlshOne (operand *result, operand *left, int shCount)
6957 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6958 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6961 /*-----------------------------------------------------------------*/
6962 /* genlshTwo - left shift two bytes by known amount != 0 */
6963 /*-----------------------------------------------------------------*/
6964 static void genlshTwo (operand *result,operand *left, int shCount)
6968 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6969 size = pic14_getDataSize(result);
6971 /* if shCount >= 8 */
6977 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6979 movLeft2Result(left, LSB, result, MSB16);
6981 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6984 /* 1 <= shCount <= 7 */
6987 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6989 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6993 /*-----------------------------------------------------------------*/
6994 /* shiftLLong - shift left one long from left to result */
6995 /* offl = LSB or MSB16 */
6996 /*-----------------------------------------------------------------*/
6997 static void shiftLLong (operand *left, operand *result, int offr )
7000 int size = AOP_SIZE(result);
7002 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7003 if(size >= LSB+offr){
7004 l = aopGet(AOP(left),LSB,FALSE,FALSE);
7006 pic14_emitcode("add","a,acc");
7007 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7008 size >= MSB16+offr && offr != LSB )
7009 pic14_emitcode("xch","a,%s",
7010 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
7012 aopPut(AOP(result),"a",LSB+offr);
7015 if(size >= MSB16+offr){
7016 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
7017 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
7020 pic14_emitcode("rlc","a");
7021 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7022 size >= MSB24+offr && offr != LSB)
7023 pic14_emitcode("xch","a,%s",
7024 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
7026 aopPut(AOP(result),"a",MSB16+offr);
7029 if(size >= MSB24+offr){
7030 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
7031 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
7034 pic14_emitcode("rlc","a");
7035 if (pic14_sameRegs(AOP(left),AOP(result)) &&
7036 size >= MSB32+offr && offr != LSB )
7037 pic14_emitcode("xch","a,%s",
7038 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
7040 aopPut(AOP(result),"a",MSB24+offr);
7043 if(size > MSB32+offr){
7044 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
7045 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
7048 pic14_emitcode("rlc","a");
7049 aopPut(AOP(result),"a",MSB32+offr);
7052 aopPut(AOP(result),zero,LSB);
7055 /*-----------------------------------------------------------------*/
7056 /* genlshFour - shift four byte by a known amount != 0 */
7057 /*-----------------------------------------------------------------*/
7058 static void genlshFour (operand *result, operand *left, int shCount)
7062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7063 size = AOP_SIZE(result);
7065 /* if shifting more that 3 bytes */
7066 if (shCount >= 24 ) {
7069 /* lowest order of left goes to the highest
7070 order of the destination */
7071 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
7073 movLeft2Result(left, LSB, result, MSB32);
7074 aopPut(AOP(result),zero,LSB);
7075 aopPut(AOP(result),zero,MSB16);
7076 aopPut(AOP(result),zero,MSB32);
7080 /* more than two bytes */
7081 else if ( shCount >= 16 ) {
7082 /* lower order two bytes goes to higher order two bytes */
7084 /* if some more remaining */
7086 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7088 movLeft2Result(left, MSB16, result, MSB32);
7089 movLeft2Result(left, LSB, result, MSB24);
7091 aopPut(AOP(result),zero,MSB16);
7092 aopPut(AOP(result),zero,LSB);
7096 /* if more than 1 byte */
7097 else if ( shCount >= 8 ) {
7098 /* lower order three bytes goes to higher order three bytes */
7102 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7104 movLeft2Result(left, LSB, result, MSB16);
7106 else{ /* size = 4 */
7108 movLeft2Result(left, MSB24, result, MSB32);
7109 movLeft2Result(left, MSB16, result, MSB24);
7110 movLeft2Result(left, LSB, result, MSB16);
7111 aopPut(AOP(result),zero,LSB);
7113 else if(shCount == 1)
7114 shiftLLong(left, result, MSB16);
7116 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7117 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7118 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7119 aopPut(AOP(result),zero,LSB);
7124 /* 1 <= shCount <= 7 */
7125 else if(shCount <= 2){
7126 shiftLLong(left, result, LSB);
7128 shiftLLong(result, result, LSB);
7130 /* 3 <= shCount <= 7, optimize */
7132 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7133 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7134 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7138 /*-----------------------------------------------------------------*/
7139 /* genLeftShiftLiteral - left shifting by known count */
7140 /*-----------------------------------------------------------------*/
7141 static void genLeftShiftLiteral (operand *left,
7146 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7149 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7150 freeAsmop(right,NULL,ic,TRUE);
7152 aopOp(left,ic,FALSE);
7153 aopOp(result,ic,FALSE);
7155 size = getSize(operandType(result));
7158 pic14_emitcode("; shift left ","result %d, left %d",size,
7162 /* I suppose that the left size >= result size */
7165 movLeft2Result(left, size, result, size);
7169 else if(shCount >= (size * 8))
7171 aopPut(AOP(result),zero,size);
7175 genlshOne (result,left,shCount);
7180 genlshTwo (result,left,shCount);
7184 genlshFour (result,left,shCount);
7188 freeAsmop(left,NULL,ic,TRUE);
7189 freeAsmop(result,NULL,ic,TRUE);
7192 /*-----------------------------------------------------------------*
7193 * genMultiAsm - repeat assembly instruction for size of register.
7194 * if endian == 1, then the high byte (i.e base address + size of
7195 * register) is used first else the low byte is used first;
7196 *-----------------------------------------------------------------*/
7197 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7202 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7215 emitpcode(poc, popGet(AOP(reg),offset));
7220 /*-----------------------------------------------------------------*/
7221 /* genLeftShift - generates code for left shifting */
7222 /*-----------------------------------------------------------------*/
7223 static void genLeftShift (iCode *ic)
7225 operand *left,*right, *result;
7228 symbol *tlbl , *tlbl1;
7231 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7233 right = IC_RIGHT(ic);
7235 result = IC_RESULT(ic);
7237 aopOp(right,ic,FALSE);
7239 /* if the shift count is known then do it
7240 as efficiently as possible */
7241 if (AOP_TYPE(right) == AOP_LIT) {
7242 genLeftShiftLiteral (left,right,result,ic);
7246 /* shift count is unknown then we have to form
7247 a loop get the loop count in B : Note: we take
7248 only the lower order byte since shifting
7249 more that 32 bits make no sense anyway, ( the
7250 largest size of an object can be only 32 bits ) */
7253 aopOp(left,ic,FALSE);
7254 aopOp(result,ic,FALSE);
7256 /* now move the left to the result if they are not the
7258 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7259 AOP_SIZE(result) > 1) {
7261 size = AOP_SIZE(result);
7264 l = aopGet(AOP(left),offset,FALSE,TRUE);
7265 if (*l == '@' && (IS_AOP_PREG(result))) {
7267 pic14_emitcode("mov","a,%s",l);
7268 aopPut(AOP(result),"a",offset);
7270 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7271 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7272 //aopPut(AOP(result),l,offset);
7278 size = AOP_SIZE(result);
7280 /* if it is only one byte then */
7282 if(optimized_for_speed) {
7283 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7284 emitpcode(POC_ANDLW, popGetLit(0xf0));
7285 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7286 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7287 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7288 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7289 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7290 emitpcode(POC_RLFW, popGet(AOP(result),0));
7291 emitpcode(POC_ANDLW, popGetLit(0xfe));
7292 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7293 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7294 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7297 tlbl = newiTempLabel(NULL);
7298 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7299 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7300 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7303 emitpcode(POC_COMFW, popGet(AOP(right),0));
7304 emitpcode(POC_RRF, popGet(AOP(result),0));
7305 emitpLabel(tlbl->key);
7306 emitpcode(POC_RLF, popGet(AOP(result),0));
7307 emitpcode(POC_ADDLW, popGetLit(1));
7309 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7314 if (pic14_sameRegs(AOP(left),AOP(result))) {
7316 tlbl = newiTempLabel(NULL);
7317 emitpcode(POC_COMFW, popGet(AOP(right),0));
7318 genMultiAsm(POC_RRF, result, size,1);
7319 emitpLabel(tlbl->key);
7320 genMultiAsm(POC_RLF, result, size,0);
7321 emitpcode(POC_ADDLW, popGetLit(1));
7323 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7327 //tlbl = newiTempLabel(NULL);
7329 //tlbl1 = newiTempLabel(NULL);
7331 //reAdjustPreg(AOP(result));
7333 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7334 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7335 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7337 //pic14_emitcode("add","a,acc");
7338 //aopPut(AOP(result),"a",offset++);
7340 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7342 // pic14_emitcode("rlc","a");
7343 // aopPut(AOP(result),"a",offset++);
7345 //reAdjustPreg(AOP(result));
7347 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7348 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7351 tlbl = newiTempLabel(NULL);
7352 tlbl1= newiTempLabel(NULL);
7354 size = AOP_SIZE(result);
7357 pctemp = popGetTempReg(); /* grab a temporary working register. */
7359 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7361 /* offset should be 0, 1 or 3 */
7362 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7364 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7366 emitpcode(POC_MOVWF, pctemp);
7369 emitpLabel(tlbl->key);
7372 emitpcode(POC_RLF, popGet(AOP(result),0));
7374 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7376 emitpcode(POC_DECFSZ, pctemp);
7377 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7378 emitpLabel(tlbl1->key);
7380 popReleaseTempReg(pctemp);
7384 freeAsmop (right,NULL,ic,TRUE);
7385 freeAsmop(left,NULL,ic,TRUE);
7386 freeAsmop(result,NULL,ic,TRUE);
7389 /*-----------------------------------------------------------------*/
7390 /* genrshOne - right shift a one byte quantity by known count */
7391 /*-----------------------------------------------------------------*/
7392 static void genrshOne (operand *result, operand *left,
7393 int shCount, int sign)
7395 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7396 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7399 /*-----------------------------------------------------------------*/
7400 /* genrshTwo - right shift two bytes by known amount != 0 */
7401 /*-----------------------------------------------------------------*/
7402 static void genrshTwo (operand *result,operand *left,
7403 int shCount, int sign)
7405 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7406 /* if shCount >= 8 */
7410 shiftR1Left2Result(left, MSB16, result, LSB,
7413 movLeft2Result(left, MSB16, result, LSB);
7415 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7418 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7419 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7423 /* 1 <= shCount <= 7 */
7425 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7428 /*-----------------------------------------------------------------*/
7429 /* shiftRLong - shift right one long from left to result */
7430 /* offl = LSB or MSB16 */
7431 /*-----------------------------------------------------------------*/
7432 static void shiftRLong (operand *left, int offl,
7433 operand *result, int sign)
7435 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7437 pic14_emitcode("clr","c");
7438 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7440 pic14_emitcode("mov","c,acc.7");
7441 pic14_emitcode("rrc","a");
7442 aopPut(AOP(result),"a",MSB32-offl);
7444 /* add sign of "a" */
7445 addSign(result, MSB32, sign);
7447 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7448 pic14_emitcode("rrc","a");
7449 aopPut(AOP(result),"a",MSB24-offl);
7451 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7452 pic14_emitcode("rrc","a");
7453 aopPut(AOP(result),"a",MSB16-offl);
7456 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7457 pic14_emitcode("rrc","a");
7458 aopPut(AOP(result),"a",LSB);
7462 /*-----------------------------------------------------------------*/
7463 /* genrshFour - shift four byte by a known amount != 0 */
7464 /*-----------------------------------------------------------------*/
7465 static void genrshFour (operand *result, operand *left,
7466 int shCount, int sign)
7468 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7469 /* if shifting more that 3 bytes */
7470 if(shCount >= 24 ) {
7473 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7475 movLeft2Result(left, MSB32, result, LSB);
7477 addSign(result, MSB16, sign);
7479 else if(shCount >= 16){
7482 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7484 movLeft2Result(left, MSB24, result, LSB);
7485 movLeft2Result(left, MSB32, result, MSB16);
7487 addSign(result, MSB24, sign);
7489 else if(shCount >= 8){
7492 shiftRLong(left, MSB16, result, sign);
7493 else if(shCount == 0){
7494 movLeft2Result(left, MSB16, result, LSB);
7495 movLeft2Result(left, MSB24, result, MSB16);
7496 movLeft2Result(left, MSB32, result, MSB24);
7497 addSign(result, MSB32, sign);
7500 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7501 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7502 /* the last shift is signed */
7503 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7504 addSign(result, MSB32, sign);
7507 else{ /* 1 <= shCount <= 7 */
7509 shiftRLong(left, LSB, result, sign);
7511 shiftRLong(result, LSB, result, sign);
7514 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7515 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7516 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7521 /*-----------------------------------------------------------------*/
7522 /* genRightShiftLiteral - right shifting by known count */
7523 /*-----------------------------------------------------------------*/
7524 static void genRightShiftLiteral (operand *left,
7530 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7533 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7534 freeAsmop(right,NULL,ic,TRUE);
7536 aopOp(left,ic,FALSE);
7537 aopOp(result,ic,FALSE);
7540 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7544 lsize = pic14_getDataSize(left);
7545 res_size = pic14_getDataSize(result);
7546 /* test the LEFT size !!! */
7548 /* I suppose that the left size >= result size */
7551 movLeft2Result(left, lsize, result, res_size);
7554 else if(shCount >= (lsize * 8)){
7557 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7559 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7560 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7565 emitpcode(POC_MOVLW, popGetLit(0));
7566 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7567 emitpcode(POC_MOVLW, popGetLit(0xff));
7569 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7574 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7581 genrshOne (result,left,shCount,sign);
7585 genrshTwo (result,left,shCount,sign);
7589 genrshFour (result,left,shCount,sign);
7597 freeAsmop(left,NULL,ic,TRUE);
7598 freeAsmop(result,NULL,ic,TRUE);
7601 /*-----------------------------------------------------------------*/
7602 /* genSignedRightShift - right shift of signed number */
7603 /*-----------------------------------------------------------------*/
7604 static void genSignedRightShift (iCode *ic)
7606 operand *right, *left, *result;
7609 symbol *tlbl, *tlbl1 ;
7612 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7614 /* we do it the hard way put the shift count in b
7615 and loop thru preserving the sign */
7616 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7618 right = IC_RIGHT(ic);
7620 result = IC_RESULT(ic);
7622 aopOp(right,ic,FALSE);
7623 aopOp(left,ic,FALSE);
7624 aopOp(result,ic,FALSE);
7627 if ( AOP_TYPE(right) == AOP_LIT) {
7628 genRightShiftLiteral (left,right,result,ic,1);
7631 /* shift count is unknown then we have to form
7632 a loop get the loop count in B : Note: we take
7633 only the lower order byte since shifting
7634 more that 32 bits make no sense anyway, ( the
7635 largest size of an object can be only 32 bits ) */
7637 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7638 //pic14_emitcode("inc","b");
7639 //freeAsmop (right,NULL,ic,TRUE);
7640 //aopOp(left,ic,FALSE);
7641 //aopOp(result,ic,FALSE);
7643 /* now move the left to the result if they are not the
7645 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7646 AOP_SIZE(result) > 1) {
7648 size = AOP_SIZE(result);
7652 l = aopGet(AOP(left),offset,FALSE,TRUE);
7653 if (*l == '@' && IS_AOP_PREG(result)) {
7655 pic14_emitcode("mov","a,%s",l);
7656 aopPut(AOP(result),"a",offset);
7658 aopPut(AOP(result),l,offset);
7660 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7661 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7667 /* mov the highest order bit to OVR */
7668 tlbl = newiTempLabel(NULL);
7669 tlbl1= newiTempLabel(NULL);
7671 size = AOP_SIZE(result);
7674 pctemp = popGetTempReg(); /* grab a temporary working register. */
7676 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7678 /* offset should be 0, 1 or 3 */
7679 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7681 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7683 emitpcode(POC_MOVWF, pctemp);
7686 emitpLabel(tlbl->key);
7688 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7689 emitpcode(POC_RRF, popGet(AOP(result),offset));
7692 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7695 emitpcode(POC_DECFSZ, pctemp);
7696 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7697 emitpLabel(tlbl1->key);
7699 popReleaseTempReg(pctemp);
7701 size = AOP_SIZE(result);
7703 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7704 pic14_emitcode("rlc","a");
7705 pic14_emitcode("mov","ov,c");
7706 /* if it is only one byte then */
7708 l = aopGet(AOP(left),0,FALSE,FALSE);
7710 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7711 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7712 pic14_emitcode("mov","c,ov");
7713 pic14_emitcode("rrc","a");
7714 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7715 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7716 aopPut(AOP(result),"a",0);
7720 reAdjustPreg(AOP(result));
7721 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7722 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7723 pic14_emitcode("mov","c,ov");
7725 l = aopGet(AOP(result),offset,FALSE,FALSE);
7727 pic14_emitcode("rrc","a");
7728 aopPut(AOP(result),"a",offset--);
7730 reAdjustPreg(AOP(result));
7731 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7732 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7737 freeAsmop(left,NULL,ic,TRUE);
7738 freeAsmop(result,NULL,ic,TRUE);
7739 freeAsmop(right,NULL,ic,TRUE);
7742 /*-----------------------------------------------------------------*/
7743 /* genRightShift - generate code for right shifting */
7744 /*-----------------------------------------------------------------*/
7745 static void genRightShift (iCode *ic)
7747 operand *right, *left, *result;
7751 symbol *tlbl, *tlbl1 ;
7753 /* if signed then we do it the hard way preserve the
7754 sign bit moving it inwards */
7755 retype = getSpec(operandType(IC_RESULT(ic)));
7756 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7758 if (!SPEC_USIGN(retype)) {
7759 genSignedRightShift (ic);
7763 /* signed & unsigned types are treated the same : i.e. the
7764 signed is NOT propagated inwards : quoting from the
7765 ANSI - standard : "for E1 >> E2, is equivalent to division
7766 by 2**E2 if unsigned or if it has a non-negative value,
7767 otherwise the result is implementation defined ", MY definition
7768 is that the sign does not get propagated */
7770 right = IC_RIGHT(ic);
7772 result = IC_RESULT(ic);
7774 aopOp(right,ic,FALSE);
7776 /* if the shift count is known then do it
7777 as efficiently as possible */
7778 if (AOP_TYPE(right) == AOP_LIT) {
7779 genRightShiftLiteral (left,right,result,ic, 0);
7783 /* shift count is unknown then we have to form
7784 a loop get the loop count in B : Note: we take
7785 only the lower order byte since shifting
7786 more that 32 bits make no sense anyway, ( the
7787 largest size of an object can be only 32 bits ) */
7789 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7790 pic14_emitcode("inc","b");
7791 aopOp(left,ic,FALSE);
7792 aopOp(result,ic,FALSE);
7794 /* now move the left to the result if they are not the
7796 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7797 AOP_SIZE(result) > 1) {
7799 size = AOP_SIZE(result);
7802 l = aopGet(AOP(left),offset,FALSE,TRUE);
7803 if (*l == '@' && IS_AOP_PREG(result)) {
7805 pic14_emitcode("mov","a,%s",l);
7806 aopPut(AOP(result),"a",offset);
7808 aopPut(AOP(result),l,offset);
7813 tlbl = newiTempLabel(NULL);
7814 tlbl1= newiTempLabel(NULL);
7815 size = AOP_SIZE(result);
7818 /* if it is only one byte then */
7821 tlbl = newiTempLabel(NULL);
7822 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7823 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7824 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7827 emitpcode(POC_COMFW, popGet(AOP(right),0));
7828 emitpcode(POC_RLF, popGet(AOP(result),0));
7829 emitpLabel(tlbl->key);
7830 emitpcode(POC_RRF, popGet(AOP(result),0));
7831 emitpcode(POC_ADDLW, popGetLit(1));
7833 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7838 reAdjustPreg(AOP(result));
7839 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7840 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7843 l = aopGet(AOP(result),offset,FALSE,FALSE);
7845 pic14_emitcode("rrc","a");
7846 aopPut(AOP(result),"a",offset--);
7848 reAdjustPreg(AOP(result));
7850 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7851 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7854 freeAsmop(left,NULL,ic,TRUE);
7855 freeAsmop (right,NULL,ic,TRUE);
7856 freeAsmop(result,NULL,ic,TRUE);
7859 /*-----------------------------------------------------------------*/
7860 /* genUnpackBits - generates code for unpacking bits */
7861 /*-----------------------------------------------------------------*/
7862 static void genUnpackBits (operand *result, char *rname, int ptype)
7869 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7870 etype = getSpec(operandType(result));
7872 /* read the first byte */
7877 pic14_emitcode("mov","a,@%s",rname);
7881 pic14_emitcode("movx","a,@%s",rname);
7885 pic14_emitcode("movx","a,@dptr");
7889 pic14_emitcode("clr","a");
7890 pic14_emitcode("movc","a","@a+dptr");
7894 pic14_emitcode("lcall","__gptrget");
7898 /* if we have bitdisplacement then it fits */
7899 /* into this byte completely or if length is */
7900 /* less than a byte */
7901 if ((shCnt = SPEC_BSTR(etype)) ||
7902 (SPEC_BLEN(etype) <= 8)) {
7904 /* shift right acc */
7907 pic14_emitcode("anl","a,#0x%02x",
7908 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7909 aopPut(AOP(result),"a",offset);
7913 /* bit field did not fit in a byte */
7914 rlen = SPEC_BLEN(etype) - 8;
7915 aopPut(AOP(result),"a",offset++);
7922 pic14_emitcode("inc","%s",rname);
7923 pic14_emitcode("mov","a,@%s",rname);
7927 pic14_emitcode("inc","%s",rname);
7928 pic14_emitcode("movx","a,@%s",rname);
7932 pic14_emitcode("inc","dptr");
7933 pic14_emitcode("movx","a,@dptr");
7937 pic14_emitcode("clr","a");
7938 pic14_emitcode("inc","dptr");
7939 pic14_emitcode("movc","a","@a+dptr");
7943 pic14_emitcode("inc","dptr");
7944 pic14_emitcode("lcall","__gptrget");
7949 /* if we are done */
7953 aopPut(AOP(result),"a",offset++);
7958 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7959 aopPut(AOP(result),"a",offset);
7966 /*-----------------------------------------------------------------*/
7967 /* genDataPointerGet - generates code when ptr offset is known */
7968 /*-----------------------------------------------------------------*/
7969 static void genDataPointerGet (operand *left,
7973 int size , offset = 0;
7976 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7979 /* optimization - most of the time, left and result are the same
7980 * address, but different types. for the pic code, we could omit
7984 aopOp(result,ic,TRUE);
7986 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7988 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7990 size = AOP_SIZE(result);
7993 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7997 freeAsmop(left,NULL,ic,TRUE);
7998 freeAsmop(result,NULL,ic,TRUE);
8001 /*-----------------------------------------------------------------*/
8002 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
8003 /*-----------------------------------------------------------------*/
8004 static void genNearPointerGet (operand *left,
8009 //regs *preg = NULL ;
8011 sym_link *rtype, *retype;
8012 sym_link *ltype = operandType(left);
8015 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8017 rtype = operandType(result);
8018 retype= getSpec(rtype);
8020 aopOp(left,ic,FALSE);
8022 /* if left is rematerialisable and
8023 result is not bit variable type and
8024 the left is pointer to data space i.e
8025 lower 128 bytes of space */
8026 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
8027 !IS_BITVAR(retype) &&
8028 DCL_TYPE(ltype) == POINTER) {
8029 //genDataPointerGet (left,result,ic);
8033 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8035 /* if the value is already in a pointer register
8036 then don't need anything more */
8037 if (!AOP_INPREG(AOP(left))) {
8038 /* otherwise get a free pointer register */
8039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8042 preg = getFreePtr(ic,&aop,FALSE);
8043 pic14_emitcode("mov","%s,%s",
8045 aopGet(AOP(left),0,FALSE,TRUE));
8046 rname = preg->name ;
8050 rname = aopGet(AOP(left),0,FALSE,FALSE);
8052 aopOp (result,ic,FALSE);
8054 /* if bitfield then unpack the bits */
8055 if (IS_BITVAR(retype))
8056 genUnpackBits (result,rname,POINTER);
8058 /* we have can just get the values */
8059 int size = AOP_SIZE(result);
8062 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8064 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8065 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8067 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8068 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8070 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8074 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8076 pic14_emitcode("mov","a,@%s",rname);
8077 aopPut(AOP(result),"a",offset);
8079 sprintf(buffer,"@%s",rname);
8080 aopPut(AOP(result),buffer,offset);
8084 pic14_emitcode("inc","%s",rname);
8089 /* now some housekeeping stuff */
8091 /* we had to allocate for this iCode */
8092 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8093 freeAsmop(NULL,aop,ic,TRUE);
8095 /* we did not allocate which means left
8096 already in a pointer register, then
8097 if size > 0 && this could be used again
8098 we have to point it back to where it
8100 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8101 if (AOP_SIZE(result) > 1 &&
8102 !OP_SYMBOL(left)->remat &&
8103 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8105 int size = AOP_SIZE(result) - 1;
8107 pic14_emitcode("dec","%s",rname);
8112 freeAsmop(left,NULL,ic,TRUE);
8113 freeAsmop(result,NULL,ic,TRUE);
8117 /*-----------------------------------------------------------------*/
8118 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8119 /*-----------------------------------------------------------------*/
8120 static void genPagedPointerGet (operand *left,
8127 sym_link *rtype, *retype;
8129 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8131 rtype = operandType(result);
8132 retype= getSpec(rtype);
8134 aopOp(left,ic,FALSE);
8136 /* if the value is already in a pointer register
8137 then don't need anything more */
8138 if (!AOP_INPREG(AOP(left))) {
8139 /* otherwise get a free pointer register */
8141 preg = getFreePtr(ic,&aop,FALSE);
8142 pic14_emitcode("mov","%s,%s",
8144 aopGet(AOP(left),0,FALSE,TRUE));
8145 rname = preg->name ;
8147 rname = aopGet(AOP(left),0,FALSE,FALSE);
8149 freeAsmop(left,NULL,ic,TRUE);
8150 aopOp (result,ic,FALSE);
8152 /* if bitfield then unpack the bits */
8153 if (IS_BITVAR(retype))
8154 genUnpackBits (result,rname,PPOINTER);
8156 /* we have can just get the values */
8157 int size = AOP_SIZE(result);
8162 pic14_emitcode("movx","a,@%s",rname);
8163 aopPut(AOP(result),"a",offset);
8168 pic14_emitcode("inc","%s",rname);
8172 /* now some housekeeping stuff */
8174 /* we had to allocate for this iCode */
8175 freeAsmop(NULL,aop,ic,TRUE);
8177 /* we did not allocate which means left
8178 already in a pointer register, then
8179 if size > 0 && this could be used again
8180 we have to point it back to where it
8182 if (AOP_SIZE(result) > 1 &&
8183 !OP_SYMBOL(left)->remat &&
8184 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8186 int size = AOP_SIZE(result) - 1;
8188 pic14_emitcode("dec","%s",rname);
8193 freeAsmop(result,NULL,ic,TRUE);
8198 /*-----------------------------------------------------------------*/
8199 /* genFarPointerGet - gget value from far space */
8200 /*-----------------------------------------------------------------*/
8201 static void genFarPointerGet (operand *left,
8202 operand *result, iCode *ic)
8205 sym_link *retype = getSpec(operandType(result));
8207 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8209 aopOp(left,ic,FALSE);
8211 /* if the operand is already in dptr
8212 then we do nothing else we move the value to dptr */
8213 if (AOP_TYPE(left) != AOP_STR) {
8214 /* if this is remateriazable */
8215 if (AOP_TYPE(left) == AOP_IMMD)
8216 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8217 else { /* we need to get it byte by byte */
8218 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8219 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8220 if (options.model == MODEL_FLAT24)
8222 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8226 /* so dptr know contains the address */
8227 freeAsmop(left,NULL,ic,TRUE);
8228 aopOp(result,ic,FALSE);
8230 /* if bit then unpack */
8231 if (IS_BITVAR(retype))
8232 genUnpackBits(result,"dptr",FPOINTER);
8234 size = AOP_SIZE(result);
8238 pic14_emitcode("movx","a,@dptr");
8239 aopPut(AOP(result),"a",offset++);
8241 pic14_emitcode("inc","dptr");
8245 freeAsmop(result,NULL,ic,TRUE);
8248 /*-----------------------------------------------------------------*/
8249 /* genCodePointerGet - get value from code space */
8250 /*-----------------------------------------------------------------*/
8251 static void genCodePointerGet (operand *left,
8252 operand *result, iCode *ic)
8255 sym_link *retype = getSpec(operandType(result));
8257 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8259 aopOp(left,ic,FALSE);
8261 /* if the operand is already in dptr
8262 then we do nothing else we move the value to dptr */
8263 if (AOP_TYPE(left) != AOP_STR) {
8264 /* if this is remateriazable */
8265 if (AOP_TYPE(left) == AOP_IMMD)
8266 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8267 else { /* we need to get it byte by byte */
8268 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8269 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8270 if (options.model == MODEL_FLAT24)
8272 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8276 /* so dptr know contains the address */
8277 freeAsmop(left,NULL,ic,TRUE);
8278 aopOp(result,ic,FALSE);
8280 /* if bit then unpack */
8281 if (IS_BITVAR(retype))
8282 genUnpackBits(result,"dptr",CPOINTER);
8284 size = AOP_SIZE(result);
8288 pic14_emitcode("clr","a");
8289 pic14_emitcode("movc","a,@a+dptr");
8290 aopPut(AOP(result),"a",offset++);
8292 pic14_emitcode("inc","dptr");
8296 freeAsmop(result,NULL,ic,TRUE);
8299 /*-----------------------------------------------------------------*/
8300 /* genGenPointerGet - gget value from generic pointer space */
8301 /*-----------------------------------------------------------------*/
8302 static void genGenPointerGet (operand *left,
8303 operand *result, iCode *ic)
8306 sym_link *retype = getSpec(operandType(result));
8308 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8309 aopOp(left,ic,FALSE);
8310 aopOp(result,ic,FALSE);
8313 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8315 /* if the operand is already in dptr
8316 then we do nothing else we move the value to dptr */
8317 // if (AOP_TYPE(left) != AOP_STR) {
8318 /* if this is remateriazable */
8319 if (AOP_TYPE(left) == AOP_IMMD) {
8320 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8321 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8323 else { /* we need to get it byte by byte */
8325 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8326 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8328 size = AOP_SIZE(result);
8332 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8333 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8335 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8340 /* so dptr know contains the address */
8342 /* if bit then unpack */
8343 //if (IS_BITVAR(retype))
8344 // genUnpackBits(result,"dptr",GPOINTER);
8347 freeAsmop(left,NULL,ic,TRUE);
8348 freeAsmop(result,NULL,ic,TRUE);
8352 /*-----------------------------------------------------------------*/
8353 /* genConstPointerGet - get value from const generic pointer space */
8354 /*-----------------------------------------------------------------*/
8355 static void genConstPointerGet (operand *left,
8356 operand *result, iCode *ic)
8358 //sym_link *retype = getSpec(operandType(result));
8359 symbol *albl = newiTempLabel(NULL);
8360 symbol *blbl = newiTempLabel(NULL);
8363 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8364 aopOp(left,ic,FALSE);
8365 aopOp(result,ic,FALSE);
8368 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8370 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8372 emitpcode(POC_CALL,popGetLabel(albl->key));
8373 emitpcode(POC_GOTO,popGetLabel(blbl->key));
8374 emitpLabel(albl->key);
8376 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8378 emitpcode(poc,popGet(AOP(left),1));
8379 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8380 emitpcode(poc,popGet(AOP(left),0));
8381 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8383 emitpLabel(blbl->key);
8385 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8388 freeAsmop(left,NULL,ic,TRUE);
8389 freeAsmop(result,NULL,ic,TRUE);
8392 /*-----------------------------------------------------------------*/
8393 /* genPointerGet - generate code for pointer get */
8394 /*-----------------------------------------------------------------*/
8395 static void genPointerGet (iCode *ic)
8397 operand *left, *result ;
8398 sym_link *type, *etype;
8401 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8404 result = IC_RESULT(ic) ;
8406 /* depending on the type of pointer we need to
8407 move it to the correct pointer register */
8408 type = operandType(left);
8409 etype = getSpec(type);
8411 if (IS_PTR_CONST(type))
8412 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8414 /* if left is of type of pointer then it is simple */
8415 if (IS_PTR(type) && !IS_FUNC(type->next))
8416 p_type = DCL_TYPE(type);
8418 /* we have to go by the storage class */
8419 p_type = PTR_TYPE(SPEC_OCLS(etype));
8421 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8423 if (SPEC_OCLS(etype)->codesp ) {
8424 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8425 //p_type = CPOINTER ;
8428 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8429 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8430 /*p_type = FPOINTER ;*/
8432 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8433 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8434 /* p_type = PPOINTER; */
8436 if (SPEC_OCLS(etype) == idata )
8437 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8438 /* p_type = IPOINTER; */
8440 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8441 /* p_type = POINTER ; */
8444 /* now that we have the pointer type we assign
8445 the pointer values */
8450 genNearPointerGet (left,result,ic);
8454 genPagedPointerGet(left,result,ic);
8458 genFarPointerGet (left,result,ic);
8462 genConstPointerGet (left,result,ic);
8463 //pic14_emitcodePointerGet (left,result,ic);
8467 if (IS_PTR_CONST(type))
8468 genConstPointerGet (left,result,ic);
8470 genGenPointerGet (left,result,ic);
8476 /*-----------------------------------------------------------------*/
8477 /* genPackBits - generates code for packed bit storage */
8478 /*-----------------------------------------------------------------*/
8479 static void genPackBits (sym_link *etype ,
8481 char *rname, int p_type)
8489 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8490 blen = SPEC_BLEN(etype);
8491 bstr = SPEC_BSTR(etype);
8493 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8496 /* if the bit lenth is less than or */
8497 /* it exactly fits a byte then */
8498 if (SPEC_BLEN(etype) <= 8 ) {
8499 shCount = SPEC_BSTR(etype) ;
8501 /* shift left acc */
8504 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8509 pic14_emitcode ("mov","b,a");
8510 pic14_emitcode("mov","a,@%s",rname);
8514 pic14_emitcode ("mov","b,a");
8515 pic14_emitcode("movx","a,@dptr");
8519 pic14_emitcode ("push","b");
8520 pic14_emitcode ("push","acc");
8521 pic14_emitcode ("lcall","__gptrget");
8522 pic14_emitcode ("pop","b");
8526 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8527 ((unsigned char)(0xFF << (blen+bstr)) |
8528 (unsigned char)(0xFF >> (8-bstr)) ) );
8529 pic14_emitcode ("orl","a,b");
8530 if (p_type == GPOINTER)
8531 pic14_emitcode("pop","b");
8537 pic14_emitcode("mov","@%s,a",rname);
8541 pic14_emitcode("movx","@dptr,a");
8545 DEBUGpic14_emitcode(";lcall","__gptrput");
8550 if ( SPEC_BLEN(etype) <= 8 )
8553 pic14_emitcode("inc","%s",rname);
8554 rLen = SPEC_BLEN(etype) ;
8556 /* now generate for lengths greater than one byte */
8559 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8569 pic14_emitcode("mov","@%s,a",rname);
8571 pic14_emitcode("mov","@%s,%s",rname,l);
8576 pic14_emitcode("movx","@dptr,a");
8581 DEBUGpic14_emitcode(";lcall","__gptrput");
8584 pic14_emitcode ("inc","%s",rname);
8589 /* last last was not complete */
8591 /* save the byte & read byte */
8594 pic14_emitcode ("mov","b,a");
8595 pic14_emitcode("mov","a,@%s",rname);
8599 pic14_emitcode ("mov","b,a");
8600 pic14_emitcode("movx","a,@dptr");
8604 pic14_emitcode ("push","b");
8605 pic14_emitcode ("push","acc");
8606 pic14_emitcode ("lcall","__gptrget");
8607 pic14_emitcode ("pop","b");
8611 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8612 pic14_emitcode ("orl","a,b");
8615 if (p_type == GPOINTER)
8616 pic14_emitcode("pop","b");
8621 pic14_emitcode("mov","@%s,a",rname);
8625 pic14_emitcode("movx","@dptr,a");
8629 DEBUGpic14_emitcode(";lcall","__gptrput");
8633 /*-----------------------------------------------------------------*/
8634 /* genDataPointerSet - remat pointer to data space */
8635 /*-----------------------------------------------------------------*/
8636 static void genDataPointerSet(operand *right,
8640 int size, offset = 0 ;
8641 char *l, buffer[256];
8643 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8644 aopOp(right,ic,FALSE);
8646 l = aopGet(AOP(result),0,FALSE,TRUE);
8647 size = AOP_SIZE(right);
8649 if ( AOP_TYPE(result) == AOP_PCODE) {
8650 fprintf(stderr,"genDataPointerSet %s, %d\n",
8651 AOP(result)->aopu.pcop->name,
8652 PCOI(AOP(result)->aopu.pcop)->offset);
8656 // tsd, was l+1 - the underline `_' prefix was being stripped
8659 sprintf(buffer,"(%s + %d)",l,offset);
8660 fprintf(stderr,"oops %s\n",buffer);
8662 sprintf(buffer,"%s",l);
8664 if (AOP_TYPE(right) == AOP_LIT) {
8665 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8666 lit = lit >> (8*offset);
8668 pic14_emitcode("movlw","%d",lit);
8669 pic14_emitcode("movwf","%s",buffer);
8671 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8672 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8673 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8676 pic14_emitcode("clrf","%s",buffer);
8677 //emitpcode(POC_CLRF, popRegFromString(buffer));
8678 emitpcode(POC_CLRF, popGet(AOP(result),0));
8681 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8682 pic14_emitcode("movwf","%s",buffer);
8684 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8685 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8686 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8693 freeAsmop(right,NULL,ic,TRUE);
8694 freeAsmop(result,NULL,ic,TRUE);
8697 /*-----------------------------------------------------------------*/
8698 /* genNearPointerSet - pic14_emitcode for near pointer put */
8699 /*-----------------------------------------------------------------*/
8700 static void genNearPointerSet (operand *right,
8707 sym_link *ptype = operandType(result);
8710 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8711 retype= getSpec(operandType(right));
8713 aopOp(result,ic,FALSE);
8716 /* if the result is rematerializable &
8717 in data space & not a bit variable */
8718 //if (AOP_TYPE(result) == AOP_IMMD &&
8719 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8720 DCL_TYPE(ptype) == POINTER &&
8721 !IS_BITVAR(retype)) {
8722 genDataPointerSet (right,result,ic);
8723 freeAsmop(result,NULL,ic,TRUE);
8727 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8728 aopOp(right,ic,FALSE);
8729 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8731 /* if the value is already in a pointer register
8732 then don't need anything more */
8733 if (!AOP_INPREG(AOP(result))) {
8734 /* otherwise get a free pointer register */
8735 //aop = newAsmop(0);
8736 //preg = getFreePtr(ic,&aop,FALSE);
8737 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8738 //pic14_emitcode("mov","%s,%s",
8740 // aopGet(AOP(result),0,FALSE,TRUE));
8741 //rname = preg->name ;
8742 //pic14_emitcode("movwf","fsr");
8743 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8744 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8745 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8746 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8750 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8753 /* if bitfield then unpack the bits */
8754 if (IS_BITVAR(retype)) {
8755 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8756 "The programmer is obviously confused");
8757 //genPackBits (retype,right,rname,POINTER);
8761 /* we have can just get the values */
8762 int size = AOP_SIZE(right);
8765 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8767 l = aopGet(AOP(right),offset,FALSE,TRUE);
8770 //pic14_emitcode("mov","@%s,a",rname);
8771 pic14_emitcode("movf","indf,w ;1");
8774 if (AOP_TYPE(right) == AOP_LIT) {
8775 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8777 pic14_emitcode("movlw","%s",l);
8778 pic14_emitcode("movwf","indf ;2");
8780 pic14_emitcode("clrf","indf");
8782 pic14_emitcode("movf","%s,w",l);
8783 pic14_emitcode("movwf","indf ;2");
8785 //pic14_emitcode("mov","@%s,%s",rname,l);
8788 pic14_emitcode("incf","fsr,f ;3");
8789 //pic14_emitcode("inc","%s",rname);
8794 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8795 /* now some housekeeping stuff */
8797 /* we had to allocate for this iCode */
8798 freeAsmop(NULL,aop,ic,TRUE);
8800 /* we did not allocate which means left
8801 already in a pointer register, then
8802 if size > 0 && this could be used again
8803 we have to point it back to where it
8805 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8806 if (AOP_SIZE(right) > 1 &&
8807 !OP_SYMBOL(result)->remat &&
8808 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8810 int size = AOP_SIZE(right) - 1;
8812 pic14_emitcode("decf","fsr,f");
8813 //pic14_emitcode("dec","%s",rname);
8817 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8820 freeAsmop(right,NULL,ic,TRUE);
8821 freeAsmop(result,NULL,ic,TRUE);
8824 /*-----------------------------------------------------------------*/
8825 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8826 /*-----------------------------------------------------------------*/
8827 static void genPagedPointerSet (operand *right,
8836 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8838 retype= getSpec(operandType(right));
8840 aopOp(result,ic,FALSE);
8842 /* if the value is already in a pointer register
8843 then don't need anything more */
8844 if (!AOP_INPREG(AOP(result))) {
8845 /* otherwise get a free pointer register */
8847 preg = getFreePtr(ic,&aop,FALSE);
8848 pic14_emitcode("mov","%s,%s",
8850 aopGet(AOP(result),0,FALSE,TRUE));
8851 rname = preg->name ;
8853 rname = aopGet(AOP(result),0,FALSE,FALSE);
8855 freeAsmop(result,NULL,ic,TRUE);
8856 aopOp (right,ic,FALSE);
8858 /* if bitfield then unpack the bits */
8859 if (IS_BITVAR(retype))
8860 genPackBits (retype,right,rname,PPOINTER);
8862 /* we have can just get the values */
8863 int size = AOP_SIZE(right);
8867 l = aopGet(AOP(right),offset,FALSE,TRUE);
8870 pic14_emitcode("movx","@%s,a",rname);
8873 pic14_emitcode("inc","%s",rname);
8879 /* now some housekeeping stuff */
8881 /* we had to allocate for this iCode */
8882 freeAsmop(NULL,aop,ic,TRUE);
8884 /* we did not allocate which means left
8885 already in a pointer register, then
8886 if size > 0 && this could be used again
8887 we have to point it back to where it
8889 if (AOP_SIZE(right) > 1 &&
8890 !OP_SYMBOL(result)->remat &&
8891 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8893 int size = AOP_SIZE(right) - 1;
8895 pic14_emitcode("dec","%s",rname);
8900 freeAsmop(right,NULL,ic,TRUE);
8905 /*-----------------------------------------------------------------*/
8906 /* genFarPointerSet - set value from far space */
8907 /*-----------------------------------------------------------------*/
8908 static void genFarPointerSet (operand *right,
8909 operand *result, iCode *ic)
8912 sym_link *retype = getSpec(operandType(right));
8914 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8915 aopOp(result,ic,FALSE);
8917 /* if the operand is already in dptr
8918 then we do nothing else we move the value to dptr */
8919 if (AOP_TYPE(result) != AOP_STR) {
8920 /* if this is remateriazable */
8921 if (AOP_TYPE(result) == AOP_IMMD)
8922 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8923 else { /* we need to get it byte by byte */
8924 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8925 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8926 if (options.model == MODEL_FLAT24)
8928 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8932 /* so dptr know contains the address */
8933 freeAsmop(result,NULL,ic,TRUE);
8934 aopOp(right,ic,FALSE);
8936 /* if bit then unpack */
8937 if (IS_BITVAR(retype))
8938 genPackBits(retype,right,"dptr",FPOINTER);
8940 size = AOP_SIZE(right);
8944 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8946 pic14_emitcode("movx","@dptr,a");
8948 pic14_emitcode("inc","dptr");
8952 freeAsmop(right,NULL,ic,TRUE);
8955 /*-----------------------------------------------------------------*/
8956 /* genGenPointerSet - set value from generic pointer space */
8957 /*-----------------------------------------------------------------*/
8958 static void genGenPointerSet (operand *right,
8959 operand *result, iCode *ic)
8962 sym_link *retype = getSpec(operandType(right));
8964 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8966 aopOp(result,ic,FALSE);
8967 aopOp(right,ic,FALSE);
8968 size = AOP_SIZE(right);
8970 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8972 /* if the operand is already in dptr
8973 then we do nothing else we move the value to dptr */
8974 if (AOP_TYPE(result) != AOP_STR) {
8975 /* if this is remateriazable */
8976 if (AOP_TYPE(result) == AOP_IMMD) {
8977 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8978 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8980 else { /* we need to get it byte by byte */
8981 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8982 size = AOP_SIZE(right);
8985 /* hack hack! see if this the FSR. If so don't load W */
8986 if(AOP_TYPE(right) != AOP_ACC) {
8989 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8990 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8992 if(AOP_SIZE(result) > 1) {
8993 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8994 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8995 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
9000 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
9002 // emitpcode(POC_MOVLW,popGetLit(0xfd));
9003 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
9007 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
9008 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9011 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
9018 if(aopIdx(AOP(result),0) != 4) {
9020 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9024 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9029 /* so dptr know contains the address */
9032 /* if bit then unpack */
9033 if (IS_BITVAR(retype))
9034 genPackBits(retype,right,"dptr",GPOINTER);
9036 size = AOP_SIZE(right);
9039 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
9043 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
9044 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
9046 if (AOP_TYPE(right) == AOP_LIT)
9047 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9049 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9051 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
9058 freeAsmop(right,NULL,ic,TRUE);
9059 freeAsmop(result,NULL,ic,TRUE);
9062 /*-----------------------------------------------------------------*/
9063 /* genPointerSet - stores the value into a pointer location */
9064 /*-----------------------------------------------------------------*/
9065 static void genPointerSet (iCode *ic)
9067 operand *right, *result ;
9068 sym_link *type, *etype;
9071 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9073 right = IC_RIGHT(ic);
9074 result = IC_RESULT(ic) ;
9076 /* depending on the type of pointer we need to
9077 move it to the correct pointer register */
9078 type = operandType(result);
9079 etype = getSpec(type);
9080 /* if left is of type of pointer then it is simple */
9081 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9082 p_type = DCL_TYPE(type);
9085 /* we have to go by the storage class */
9086 p_type = PTR_TYPE(SPEC_OCLS(etype));
9088 /* if (SPEC_OCLS(etype)->codesp ) { */
9089 /* p_type = CPOINTER ; */
9092 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9093 /* p_type = FPOINTER ; */
9095 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9096 /* p_type = PPOINTER ; */
9098 /* if (SPEC_OCLS(etype) == idata ) */
9099 /* p_type = IPOINTER ; */
9101 /* p_type = POINTER ; */
9104 /* now that we have the pointer type we assign
9105 the pointer values */
9110 genNearPointerSet (right,result,ic);
9114 genPagedPointerSet (right,result,ic);
9118 genFarPointerSet (right,result,ic);
9122 genGenPointerSet (right,result,ic);
9126 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9127 "genPointerSet: illegal pointer type");
9131 /*-----------------------------------------------------------------*/
9132 /* genIfx - generate code for Ifx statement */
9133 /*-----------------------------------------------------------------*/
9134 static void genIfx (iCode *ic, iCode *popIc)
9136 operand *cond = IC_COND(ic);
9139 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9141 aopOp(cond,ic,FALSE);
9143 /* get the value into acc */
9144 if (AOP_TYPE(cond) != AOP_CRY)
9145 pic14_toBoolean(cond);
9148 /* the result is now in the accumulator */
9149 freeAsmop(cond,NULL,ic,TRUE);
9151 /* if there was something to be popped then do it */
9155 /* if the condition is a bit variable */
9156 if (isbit && IS_ITEMP(cond) &&
9158 genIfxJump(ic,SPIL_LOC(cond)->rname);
9159 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9162 if (isbit && !IS_ITEMP(cond))
9163 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9171 /*-----------------------------------------------------------------*/
9172 /* genAddrOf - generates code for address of */
9173 /*-----------------------------------------------------------------*/
9174 static void genAddrOf (iCode *ic)
9176 operand *right, *result, *left;
9179 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9182 //aopOp(IC_RESULT(ic),ic,FALSE);
9184 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9185 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9186 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9188 DEBUGpic14_AopType(__LINE__,left,right,result);
9190 size = AOP_SIZE(IC_RESULT(ic));
9194 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9195 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9199 freeAsmop(left,NULL,ic,FALSE);
9200 freeAsmop(result,NULL,ic,TRUE);
9205 /*-----------------------------------------------------------------*/
9206 /* genFarFarAssign - assignment when both are in far space */
9207 /*-----------------------------------------------------------------*/
9208 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9210 int size = AOP_SIZE(right);
9213 /* first push the right side on to the stack */
9215 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9217 pic14_emitcode ("push","acc");
9220 freeAsmop(right,NULL,ic,FALSE);
9221 /* now assign DPTR to result */
9222 aopOp(result,ic,FALSE);
9223 size = AOP_SIZE(result);
9225 pic14_emitcode ("pop","acc");
9226 aopPut(AOP(result),"a",--offset);
9228 freeAsmop(result,NULL,ic,FALSE);
9233 /*-----------------------------------------------------------------*/
9234 /* genAssign - generate code for assignment */
9235 /*-----------------------------------------------------------------*/
9236 static void genAssign (iCode *ic)
9238 operand *result, *right;
9239 int size, offset,know_W;
9240 unsigned long lit = 0L;
9242 result = IC_RESULT(ic);
9243 right = IC_RIGHT(ic) ;
9245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9247 /* if they are the same */
9248 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9251 aopOp(right,ic,FALSE);
9252 aopOp(result,ic,TRUE);
9254 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9256 /* if they are the same registers */
9257 if (pic14_sameRegs(AOP(right),AOP(result)))
9260 /* if the result is a bit */
9261 if (AOP_TYPE(result) == AOP_CRY) {
9263 /* if the right size is a literal then
9264 we know what the value is */
9265 if (AOP_TYPE(right) == AOP_LIT) {
9267 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9268 popGet(AOP(result),0));
9270 if (((int) operandLitValue(right)))
9271 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9272 AOP(result)->aopu.aop_dir,
9273 AOP(result)->aopu.aop_dir);
9275 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9276 AOP(result)->aopu.aop_dir,
9277 AOP(result)->aopu.aop_dir);
9281 /* the right is also a bit variable */
9282 if (AOP_TYPE(right) == AOP_CRY) {
9283 emitpcode(POC_BCF, popGet(AOP(result),0));
9284 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9285 emitpcode(POC_BSF, popGet(AOP(result),0));
9287 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9288 AOP(result)->aopu.aop_dir,
9289 AOP(result)->aopu.aop_dir);
9290 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9291 AOP(right)->aopu.aop_dir,
9292 AOP(right)->aopu.aop_dir);
9293 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9294 AOP(result)->aopu.aop_dir,
9295 AOP(result)->aopu.aop_dir);
9300 emitpcode(POC_BCF, popGet(AOP(result),0));
9301 pic14_toBoolean(right);
9303 emitpcode(POC_BSF, popGet(AOP(result),0));
9304 //aopPut(AOP(result),"a",0);
9308 /* bit variables done */
9310 size = AOP_SIZE(result);
9312 if(AOP_TYPE(right) == AOP_LIT)
9313 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9315 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9316 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9317 if(aopIdx(AOP(result),0) == 4) {
9318 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9319 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9320 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9323 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9328 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9329 if(AOP_TYPE(right) == AOP_LIT) {
9331 if(know_W != (lit&0xff))
9332 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9334 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9336 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9340 } else if (AOP_TYPE(right) == AOP_CRY) {
9341 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9343 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9344 emitpcode(POC_INCF, popGet(AOP(result),0));
9347 mov2w (AOP(right), offset);
9348 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9356 freeAsmop (right,NULL,ic,FALSE);
9357 freeAsmop (result,NULL,ic,TRUE);
9360 /*-----------------------------------------------------------------*/
9361 /* genJumpTab - genrates code for jump table */
9362 /*-----------------------------------------------------------------*/
9363 static void genJumpTab (iCode *ic)
9368 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9370 aopOp(IC_JTCOND(ic),ic,FALSE);
9371 /* get the condition into accumulator */
9372 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9374 /* multiply by three */
9375 pic14_emitcode("add","a,acc");
9376 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9378 jtab = newiTempLabel(NULL);
9379 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9380 pic14_emitcode("jmp","@a+dptr");
9381 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9383 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9384 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9386 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9387 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9388 emitpLabel(jtab->key);
9390 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9392 /* now generate the jump labels */
9393 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9394 jtab = setNextItem(IC_JTLABELS(ic))) {
9395 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9396 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9402 /*-----------------------------------------------------------------*/
9403 /* genMixedOperation - gen code for operators between mixed types */
9404 /*-----------------------------------------------------------------*/
9406 TSD - Written for the PIC port - but this unfortunately is buggy.
9407 This routine is good in that it is able to efficiently promote
9408 types to different (larger) sizes. Unfortunately, the temporary
9409 variables that are optimized out by this routine are sometimes
9410 used in other places. So until I know how to really parse the
9411 iCode tree, I'm going to not be using this routine :(.
9413 static int genMixedOperation (iCode *ic)
9416 operand *result = IC_RESULT(ic);
9417 sym_link *ctype = operandType(IC_LEFT(ic));
9418 operand *right = IC_RIGHT(ic);
9424 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9426 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9432 nextright = IC_RIGHT(nextic);
9433 nextleft = IC_LEFT(nextic);
9434 nextresult = IC_RESULT(nextic);
9436 aopOp(right,ic,FALSE);
9437 aopOp(result,ic,FALSE);
9438 aopOp(nextright, nextic, FALSE);
9439 aopOp(nextleft, nextic, FALSE);
9440 aopOp(nextresult, nextic, FALSE);
9442 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9448 pic14_emitcode(";remove right +","");
9450 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9456 pic14_emitcode(";remove left +","");
9460 big = AOP_SIZE(nextleft);
9461 small = AOP_SIZE(nextright);
9463 switch(nextic->op) {
9466 pic14_emitcode(";optimize a +","");
9467 /* if unsigned or not an integral type */
9468 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9469 pic14_emitcode(";add a bit to something","");
9472 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9474 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9475 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9476 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9478 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9486 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9487 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9488 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9491 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9493 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9494 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9495 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9496 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9497 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9500 pic14_emitcode("rlf","known_zero,w");
9507 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9508 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9509 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9511 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9521 freeAsmop(right,NULL,ic,TRUE);
9522 freeAsmop(result,NULL,ic,TRUE);
9523 freeAsmop(nextright,NULL,ic,TRUE);
9524 freeAsmop(nextleft,NULL,ic,TRUE);
9526 nextic->generated = 1;
9533 /*-----------------------------------------------------------------*/
9534 /* genCast - gen code for casting */
9535 /*-----------------------------------------------------------------*/
9536 static void genCast (iCode *ic)
9538 operand *result = IC_RESULT(ic);
9539 sym_link *ctype = operandType(IC_LEFT(ic));
9540 sym_link *rtype = operandType(IC_RIGHT(ic));
9541 operand *right = IC_RIGHT(ic);
9544 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9545 /* if they are equivalent then do nothing */
9546 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9549 aopOp(right,ic,FALSE) ;
9550 aopOp(result,ic,FALSE);
9552 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9554 /* if the result is a bit */
9555 if (AOP_TYPE(result) == AOP_CRY) {
9556 /* if the right size is a literal then
9557 we know what the value is */
9558 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9559 if (AOP_TYPE(right) == AOP_LIT) {
9561 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9562 popGet(AOP(result),0));
9564 if (((int) operandLitValue(right)))
9565 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9566 AOP(result)->aopu.aop_dir,
9567 AOP(result)->aopu.aop_dir);
9569 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9570 AOP(result)->aopu.aop_dir,
9571 AOP(result)->aopu.aop_dir);
9576 /* the right is also a bit variable */
9577 if (AOP_TYPE(right) == AOP_CRY) {
9580 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9582 pic14_emitcode("clrc","");
9583 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9584 AOP(right)->aopu.aop_dir,
9585 AOP(right)->aopu.aop_dir);
9586 aopPut(AOP(result),"c",0);
9591 if (AOP_TYPE(right) == AOP_REG) {
9592 emitpcode(POC_BCF, popGet(AOP(result),0));
9593 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9594 emitpcode(POC_BSF, popGet(AOP(result),0));
9596 pic14_toBoolean(right);
9597 aopPut(AOP(result),"a",0);
9601 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9603 size = AOP_SIZE(result);
9605 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9607 emitpcode(POC_CLRF, popGet(AOP(result),0));
9608 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9609 emitpcode(POC_INCF, popGet(AOP(result),0));
9612 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9617 /* if they are the same size : or less */
9618 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9620 /* if they are in the same place */
9621 if (pic14_sameRegs(AOP(right),AOP(result)))
9624 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9625 if (IS_PTR_CONST(rtype))
9626 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9627 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9628 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9630 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9631 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9632 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9633 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9634 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9635 if(AOP_SIZE(result) <2)
9636 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9640 /* if they in different places then copy */
9641 size = AOP_SIZE(result);
9644 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9645 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9647 //aopPut(AOP(result),
9648 // aopGet(AOP(right),offset,FALSE,FALSE),
9658 /* if the result is of type pointer */
9659 if (IS_PTR(ctype)) {
9662 sym_link *type = operandType(right);
9663 sym_link *etype = getSpec(type);
9664 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9666 /* pointer to generic pointer */
9667 if (IS_GENPTR(ctype)) {
9671 p_type = DCL_TYPE(type);
9673 /* we have to go by the storage class */
9674 p_type = PTR_TYPE(SPEC_OCLS(etype));
9676 /* if (SPEC_OCLS(etype)->codesp ) */
9677 /* p_type = CPOINTER ; */
9679 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9680 /* p_type = FPOINTER ; */
9682 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9683 /* p_type = PPOINTER; */
9685 /* if (SPEC_OCLS(etype) == idata ) */
9686 /* p_type = IPOINTER ; */
9688 /* p_type = POINTER ; */
9691 /* the first two bytes are known */
9692 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9693 size = GPTRSIZE - 1;
9696 if(offset < AOP_SIZE(right)) {
9697 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9698 if ((AOP_TYPE(right) == AOP_PCODE) &&
9699 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9700 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9701 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9704 aopGet(AOP(right),offset,FALSE,FALSE),
9708 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9711 /* the last byte depending on type */
9715 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9718 pic14_emitcode(";BUG!? ","%d",__LINE__);
9722 pic14_emitcode(";BUG!? ","%d",__LINE__);
9726 pic14_emitcode(";BUG!? ","%d",__LINE__);
9731 /* this should never happen */
9732 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9733 "got unknown pointer type");
9736 //aopPut(AOP(result),l, GPTRSIZE - 1);
9740 /* just copy the pointers */
9741 size = AOP_SIZE(result);
9745 aopGet(AOP(right),offset,FALSE,FALSE),
9754 /* so we now know that the size of destination is greater
9755 than the size of the source.
9756 Now, if the next iCode is an operator then we might be
9757 able to optimize the operation without performing a cast.
9759 if(genMixedOperation(ic))
9762 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9764 /* we move to result for the size of source */
9765 size = AOP_SIZE(right);
9768 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9769 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9773 /* now depending on the sign of the destination */
9774 size = AOP_SIZE(result) - AOP_SIZE(right);
9775 /* if unsigned or not an integral type */
9776 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9778 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9780 /* we need to extend the sign :{ */
9783 /* Save one instruction of casting char to int */
9784 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9785 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9786 emitpcode(POC_DECF, popGet(AOP(result),offset));
9788 emitpcodeNULLop(POC_CLRW);
9791 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9793 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9795 emitpcode(POC_MOVLW, popGetLit(0xff));
9798 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9803 freeAsmop(right,NULL,ic,TRUE);
9804 freeAsmop(result,NULL,ic,TRUE);
9808 /*-----------------------------------------------------------------*/
9809 /* genDjnz - generate decrement & jump if not zero instrucion */
9810 /*-----------------------------------------------------------------*/
9811 static int genDjnz (iCode *ic, iCode *ifx)
9814 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9819 /* if the if condition has a false label
9820 then we cannot save */
9824 /* if the minus is not of the form
9826 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9827 !IS_OP_LITERAL(IC_RIGHT(ic)))
9830 if (operandLitValue(IC_RIGHT(ic)) != 1)
9833 /* if the size of this greater than one then no
9835 if (getSize(operandType(IC_RESULT(ic))) > 1)
9838 /* otherwise we can save BIG */
9839 lbl = newiTempLabel(NULL);
9840 lbl1= newiTempLabel(NULL);
9842 aopOp(IC_RESULT(ic),ic,FALSE);
9844 if (IS_AOP_PREG(IC_RESULT(ic))) {
9845 pic14_emitcode("dec","%s",
9846 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9847 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9848 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9852 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9853 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9855 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9856 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9859 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9860 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9861 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9862 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9865 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9870 /*-----------------------------------------------------------------*/
9871 /* genReceive - generate code for a receive iCode */
9872 /*-----------------------------------------------------------------*/
9873 static void genReceive (iCode *ic)
9875 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9877 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9878 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9879 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9881 int size = getSize(operandType(IC_RESULT(ic)));
9882 int offset = fReturnSizePic - size;
9884 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9885 fReturn[fReturnSizePic - offset - 1] : "acc"));
9888 aopOp(IC_RESULT(ic),ic,FALSE);
9889 size = AOP_SIZE(IC_RESULT(ic));
9892 pic14_emitcode ("pop","acc");
9893 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9898 aopOp(IC_RESULT(ic),ic,FALSE);
9900 assignResultValue(IC_RESULT(ic));
9903 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9906 /*-----------------------------------------------------------------*/
9907 /* genpic14Code - generate code for pic14 based controllers */
9908 /*-----------------------------------------------------------------*/
9910 * At this point, ralloc.c has gone through the iCode and attempted
9911 * to optimize in a way suitable for a PIC. Now we've got to generate
9912 * PIC instructions that correspond to the iCode.
9914 * Once the instructions are generated, we'll pass through both the
9915 * peep hole optimizer and the pCode optimizer.
9916 *-----------------------------------------------------------------*/
9918 void genpic14Code (iCode *lic)
9923 lineHead = lineCurr = NULL;
9925 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9928 /* if debug information required */
9929 if (options.debug && currFunc) {
9931 debugFile->writeFunction(currFunc);
9933 if (IS_STATIC(currFunc->etype)) {
9934 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9935 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9937 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9938 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9945 for (ic = lic ; ic ; ic = ic->next ) {
9947 DEBUGpic14_emitcode(";ic","");
9948 if ( cln != ic->lineno ) {
9949 if ( options.debug ) {
9951 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9952 FileBaseName(ic->filename),ic->lineno,
9953 ic->level,ic->block);
9957 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9958 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9959 printCLine(ic->filename, ic->lineno));
9961 if (!options.noCcodeInAsm) {
9963 newpCodeCSource(ic->lineno,
9965 printCLine(ic->filename, ic->lineno)));
9971 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9973 /* if the result is marked as
9974 spilt and rematerializable or code for
9975 this has already been generated then
9977 if (resultRemat(ic) || ic->generated )
9980 /* depending on the operation */
9999 /* IPOP happens only when trying to restore a
10000 spilt live range, if there is an ifx statement
10001 following this pop then the if statement might
10002 be using some of the registers being popped which
10003 would destory the contents of the register so
10004 we need to check for this condition and handle it */
10006 ic->next->op == IFX &&
10007 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
10008 genIfx (ic->next,ic);
10026 genEndFunction (ic);
10046 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10063 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10067 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10074 /* note these two are xlated by algebraic equivalence
10075 during parsing SDCC.y */
10076 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10077 "got '>=' or '<=' shouldn't have come here");
10081 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10093 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10097 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10101 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10125 genRightShift (ic);
10128 case GET_VALUE_AT_ADDRESS:
10133 if (POINTER_SET(ic))
10160 addSet(&_G.sendSet,ic);
10169 /* now we are ready to call the
10170 peep hole optimizer */
10171 if (!options.nopeep) {
10172 peepHole (&lineHead);
10174 /* now do the actual printing */
10175 printLine (lineHead,codeOutFile);
10178 DFPRINTF((stderr,"printing pBlock\n\n"));
10179 printpBlock(stdout,pb);