1 /*-------------------------------------------------------------------------
2 gen.c - source file for code generation for pic
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 and - Jean-Louis VERN.jlvern@writeme.com (1999)
6 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
7 PIC port - Scott Dattalo scott@dattalo.com (2000)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
28 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
29 Made everything static
30 -------------------------------------------------------------------------*/
36 #include "SDCCglobl.h"
40 #include "SDCCpeeph.h"
46 extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
47 extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
48 void genMult8X8_8 (operand *, operand *,operand *);
49 pCode *AssembleLine(char *line);
50 extern void printpBlock(FILE *of, pBlock *pb);
52 static int labelOffset=0;
53 extern int debug_verbose;
54 static int optimized_for_speed = 0;
56 /* max_key keeps track of the largest label number used in
57 a function. This is then used to adjust the label offset
58 for the next function.
61 static int GpsuedoStkPtr=0;
63 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
64 unsigned int pic14aopLiteral (value *val, int offset);
65 const char *AopType(short type);
66 static iCode *ifxForOp ( operand *op, iCode *ic );
68 #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff)
70 /* this is the down and dirty file with all kinds of
71 kludgy & hacky stuff. This is what it is all about
72 CODE GENERATION for a specific MCU . some of the
73 routines may be reusable, will have to see */
75 static char *zero = "#0x00";
76 static char *one = "#0x01";
77 static char *spname = "sp";
79 char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" };
80 //char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
81 unsigned fReturnSizePic = 4; /* shared with ralloc.c */
82 static char **fReturn = fReturnpic14;
84 static char *accUse[] = {"a","b"};
86 //static short rbank = -1;
98 /* Resolved ifx structure. This structure stores information
99 about an iCode ifx that makes it easier to generate code.
101 typedef struct resolvedIfx {
102 symbol *lbl; /* pointer to a label */
103 int condition; /* true or false ifx */
104 int generated; /* set true when the code associated with the ifx
108 extern int pic14_ptrRegReq ;
109 extern int pic14_nRegs;
110 extern FILE *codeOutFile;
111 static void saverbank (int, iCode *,bool);
113 static lineNode *lineHead = NULL;
114 static lineNode *lineCurr = NULL;
116 static unsigned char SLMask[] = {0xFF ,0xFE, 0xFC, 0xF8, 0xF0,
117 0xE0, 0xC0, 0x80, 0x00};
118 static unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F,
119 0x07, 0x03, 0x01, 0x00};
123 /*-----------------------------------------------------------------*/
124 /* my_powof2(n) - If `n' is an integaer power of 2, then the */
125 /* exponent of 2 is returned, otherwise -1 is */
127 /* note that this is similar to the function `powof2' in SDCCsymt */
131 /*-----------------------------------------------------------------*/
132 static int my_powof2 (unsigned long num)
135 if( (num & (num-1)) == 0) {
148 void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result)
151 DEBUGpic14_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d",
153 ((result) ? AopType(AOP_TYPE(result)) : "-"),
154 ((result) ? aopGet(AOP(result),0,TRUE,FALSE) : "-"),
155 ((left) ? AopType(AOP_TYPE(left)) : "-"),
156 ((left) ? aopGet(AOP(left),0,TRUE,FALSE) : "-"),
157 ((right) ? AopType(AOP_TYPE(right)) : "-"),
158 ((right) ? aopGet(AOP(right),0,FALSE,FALSE) : "-"),
159 ((result) ? AOP_SIZE(result) : 0));
163 void DEBUGpic14_AopTypeSign(int line_no, operand *left, operand *right, operand *result)
166 DEBUGpic14_emitcode ("; ","line = %d, signs: result %s=%c, left %s=%c, right %s=%c",
168 ((result) ? AopType(AOP_TYPE(result)) : "-"),
169 ((result) ? (SPEC_USIGN(operandType(result)) ? 'u' : 's') : '-'),
170 ((left) ? AopType(AOP_TYPE(left)) : "-"),
171 ((left) ? (SPEC_USIGN(operandType(left)) ? 'u' : 's') : '-'),
172 ((right) ? AopType(AOP_TYPE(right)) : "-"),
173 ((right) ? (SPEC_USIGN(operandType(right)) ? 'u' : 's') : '-'));
177 void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
180 char lb[INITIAL_INLINEASM];
190 sprintf(lb,"%s\t",inst);
192 sprintf(lb,"%s",inst);
193 vsprintf(lb+(strlen(lb)),fmt,ap);
197 while (isspace(*lbp)) lbp++;
200 lineCurr = (lineCurr ?
201 connectLine(lineCurr,newLineNode(lb)) :
202 (lineHead = newLineNode(lb)));
203 lineCurr->isInline = _G.inLine;
204 lineCurr->isDebug = _G.debugLine;
206 addpCode2pBlock(pb,newpCodeCharP(lb));
212 void emitpLabel(int key)
214 addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
217 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
220 addpCode2pBlock(pb,newpCode(poc,pcop));
222 DEBUGpic14_emitcode(";","%s ignoring NULL pcop",__FUNCTION__);
225 void emitpcodeNULLop(PIC_OPCODE poc)
228 addpCode2pBlock(pb,newpCode(poc,NULL));
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);
1185 if(key>(unsigned int)max_key)
1188 return newpCodeOpLabel(NULL,key+100+labelOffset);
1191 /*-------------------------------------------------------------------*/
1192 /* popGetHighLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
1193 /*-------------------------------------------------------------------*/
1194 pCodeOp *popGetHighLabel(unsigned int key)
1197 pcop = popGetLabel(key);
1198 PCOLAB(pcop)->offset = 1;
1202 /*-----------------------------------------------------------------*/
1203 /* popGet - asm operator to pcode operator conversion */
1204 /*-----------------------------------------------------------------*/
1205 pCodeOp *popGetLit(unsigned int lit)
1208 return newpCodeOpLit(lit);
1212 /*-----------------------------------------------------------------*/
1213 /* popGetImmd - asm operator to pcode immediate conversion */
1214 /*-----------------------------------------------------------------*/
1215 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
1218 return newpCodeOpImmd(name, offset,index, 0, is_func);
1222 /*-----------------------------------------------------------------*/
1223 /* popGet - asm operator to pcode operator conversion */
1224 /*-----------------------------------------------------------------*/
1225 pCodeOp *popGetWithString(char *str, int isExtern)
1231 fprintf(stderr,"NULL string %s %d\n",__FILE__,__LINE__);
1235 pcop = newpCodeOp(str,PO_STR);
1236 PCOS(pcop)->isPublic = isExtern ? 1 : 0;
1241 /*-----------------------------------------------------------------*/
1242 /* popRegFromString - */
1243 /*-----------------------------------------------------------------*/
1244 pCodeOp *popRegFromString(char *str, int size, int offset)
1247 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1248 pcop->type = PO_DIR;
1250 DEBUGpic14_emitcode(";","%d",__LINE__);
1255 pcop->name = Safe_calloc(1,strlen(str)+1);
1256 strcpy(pcop->name,str);
1258 //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING"));
1260 PCOR(pcop)->r = dirregWithName(pcop->name);
1261 if(PCOR(pcop)->r == NULL) {
1262 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1263 PCOR(pcop)->r = allocRegByName (pcop->name,size);
1264 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1266 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1268 PCOR(pcop)->instance = offset;
1273 /*-----------------------------------------------------------------*/
1274 /*-----------------------------------------------------------------*/
1275 pCodeOp *popRegFromIdx(int rIdx)
1279 DEBUGpic14_emitcode ("; ***","%s,%d , rIdx=0x%x",
1280 __FUNCTION__,__LINE__,rIdx);
1282 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1284 PCOR(pcop)->rIdx = rIdx;
1285 PCOR(pcop)->r = typeRegWithIdx(rIdx,REG_STK,1);
1286 PCOR(pcop)->r->isFree = 0;
1287 PCOR(pcop)->r->wasUsed = 1;
1289 pcop->type = PCOR(pcop)->r->pc_type;
1295 /*-----------------------------------------------------------------*/
1296 /* popGet - asm operator to pcode operator conversion */
1297 /*-----------------------------------------------------------------*/
1298 pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
1300 //char *s = buffer ;
1305 //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1306 /* offset is greater than
1309 if (offset > (aop->size - 1) &&
1310 aop->type != AOP_LIT)
1311 return NULL; //zero;
1313 /* depending on type */
1314 switch (aop->type) {
1321 DEBUGpic14_emitcode(";8051 legacy","%d type = %s",__LINE__,AopType(aop->type));
1325 DEBUGpic14_emitcode(";","%d",__LINE__);
1326 return popGetImmd(aop->aopu.aop_immd,offset,0,0);
1329 return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
1331 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1332 pcop->type = PO_DIR;
1336 sprintf(s,"(%s + %d)",
1340 sprintf(s,"%s",aop->aopu.aop_dir);
1341 pcop->name = Safe_calloc(1,strlen(s)+1);
1342 strcpy(pcop->name,s);
1344 pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1);
1345 strcpy(pcop->name,aop->aopu.aop_dir);
1346 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1347 if(PCOR(pcop)->r == NULL) {
1348 //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size);
1349 PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size);
1350 DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset);
1352 DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset);
1354 PCOR(pcop)->instance = offset;
1361 int rIdx = aop->aopu.aop_reg[offset]->rIdx;
1363 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1364 PCOR(pcop)->rIdx = rIdx;
1365 PCOR(pcop)->r = pic14_regWithIdx(rIdx);
1366 PCOR(pcop)->r->wasUsed=1;
1367 PCOR(pcop)->r->isFree=0;
1369 PCOR(pcop)->instance = offset;
1370 pcop->type = PCOR(pcop)->r->pc_type;
1371 //rs = aop->aopu.aop_reg[offset]->name;
1372 DEBUGpic14_emitcode(";","%d regiser idx = %d ",__LINE__,rIdx);
1377 pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
1378 PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir);
1379 //if(PCOR(pcop)->r == NULL)
1380 //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir);
1384 return newpCodeOpLit(pic14aopLiteral (aop->aopu.aop_lit,offset));
1387 DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]);
1388 return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]);
1390 pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1391 PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]);
1392 PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
1393 pcop->type = PCOR(pcop)->r->pc_type;
1394 pcop->name = PCOR(pcop)->r->name;
1400 DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s) %d %s",pCodeOpType(aop->aopu.pcop),
1402 ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
1403 pcop = pCodeOpCopy(aop->aopu.pcop);
1404 PCOI(pcop)->offset = offset;
1408 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1409 "popGet got unsupported aop->type");
1412 /*-----------------------------------------------------------------*/
1413 /* aopPut - puts a string for a aop */
1414 /*-----------------------------------------------------------------*/
1415 void aopPut (asmop *aop, char *s, int offset)
1420 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1422 if (aop->size && offset > ( aop->size - 1)) {
1423 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1424 "aopPut got offset > aop->size");
1428 /* will assign value to value */
1429 /* depending on where it is ofcourse */
1430 switch (aop->type) {
1433 sprintf(d,"(%s + %d)",
1434 aop->aopu.aop_dir,offset);
1435 fprintf(stderr,"oops aopPut:AOP_DIR did this %s\n",s);
1438 sprintf(d,"%s",aop->aopu.aop_dir);
1441 DEBUGpic14_emitcode(";","%d",__LINE__);
1443 pic14_emitcode("movf","%s,w",s);
1444 pic14_emitcode("movwf","%s",d);
1447 pic14_emitcode(";BUG!? should have this:movf","%s,w %d",s,__LINE__);
1448 if(offset >= aop->size) {
1449 emitpcode(POC_CLRF,popGet(aop,offset));
1452 emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
1455 emitpcode(POC_MOVWF,popGet(aop,offset));
1462 if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { // &&
1463 //strcmp(aop->aopu.aop_reg[offset]->dname,s)!= 0){
1466 strcmp(s,"r0") == 0 ||
1467 strcmp(s,"r1") == 0 ||
1468 strcmp(s,"r2") == 0 ||
1469 strcmp(s,"r3") == 0 ||
1470 strcmp(s,"r4") == 0 ||
1471 strcmp(s,"r5") == 0 ||
1472 strcmp(s,"r6") == 0 ||
1473 strcmp(s,"r7") == 0 )
1474 pic14_emitcode("mov","%s,%s ; %d",
1475 aop->aopu.aop_reg[offset]->dname,s,__LINE__);
1479 if(strcmp(s,"W")==0 )
1480 pic14_emitcode("movf","%s,w ; %d",s,__LINE__);
1482 pic14_emitcode("movwf","%s",
1483 aop->aopu.aop_reg[offset]->name);
1485 if(strcmp(s,zero)==0) {
1486 emitpcode(POC_CLRF,popGet(aop,offset));
1488 } else if(strcmp(s,"W")==0) {
1489 pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
1490 pcop->type = PO_GPR_REGISTER;
1492 PCOR(pcop)->rIdx = -1;
1493 PCOR(pcop)->r = NULL;
1495 DEBUGpic14_emitcode(";","%d",__LINE__);
1496 pcop->name = Safe_strdup(s);
1497 emitpcode(POC_MOVFW,pcop);
1498 emitpcode(POC_MOVWF,popGet(aop,offset));
1499 } else if(strcmp(s,one)==0) {
1500 emitpcode(POC_CLRF,popGet(aop,offset));
1501 emitpcode(POC_INCF,popGet(aop,offset));
1503 emitpcode(POC_MOVWF,popGet(aop,offset));
1511 if (aop->type == AOP_DPTR2)
1517 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1518 "aopPut writting to code space");
1522 while (offset > aop->coff) {
1524 pic14_emitcode ("inc","dptr");
1527 while (offset < aop->coff) {
1529 pic14_emitcode("lcall","__decdptr");
1534 /* if not in accumulater */
1537 pic14_emitcode ("movx","@dptr,a");
1539 if (aop->type == AOP_DPTR2)
1547 while (offset > aop->coff) {
1549 pic14_emitcode("inc","%s",aop->aopu.aop_ptr->name);
1551 while (offset < aop->coff) {
1553 pic14_emitcode ("dec","%s",aop->aopu.aop_ptr->name);
1559 pic14_emitcode("movx","@%s,a",aop->aopu.aop_ptr->name);
1564 pic14_emitcode("mov","@%s,a ; %d",aop->aopu.aop_ptr->name,__LINE__);
1566 if (strcmp(s,"r0") == 0 ||
1567 strcmp(s,"r1") == 0 ||
1568 strcmp(s,"r2") == 0 ||
1569 strcmp(s,"r3") == 0 ||
1570 strcmp(s,"r4") == 0 ||
1571 strcmp(s,"r5") == 0 ||
1572 strcmp(s,"r6") == 0 ||
1573 strcmp(s,"r7") == 0 ) {
1575 sprintf(buffer,"a%s",s);
1576 pic14_emitcode("mov","@%s,%s",
1577 aop->aopu.aop_ptr->name,buffer);
1579 pic14_emitcode("mov","@%s,%s",aop->aopu.aop_ptr->name,s);
1584 if (strcmp(s,"a") == 0)
1585 pic14_emitcode("push","acc");
1587 pic14_emitcode("push","%s",s);
1592 /* if bit variable */
1593 if (!aop->aopu.aop_dir) {
1594 pic14_emitcode("clr","a");
1595 pic14_emitcode("rlc","a");
1598 pic14_emitcode("clr","%s",aop->aopu.aop_dir);
1601 pic14_emitcode("setb","%s",aop->aopu.aop_dir);
1604 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1606 lbl = newiTempLabel(NULL);
1608 if (strcmp(s,"a")) {
1611 pic14_emitcode("clr","c");
1612 pic14_emitcode("jz","%05d_DS_",lbl->key+100);
1613 pic14_emitcode("cpl","c");
1614 pic14_emitcode("","%05d_DS_:",lbl->key+100);
1615 pic14_emitcode("mov","%s,c",aop->aopu.aop_dir);
1622 if (strcmp(aop->aopu.aop_str[offset],s))
1623 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s,__LINE__);
1628 if (!offset && (strcmp(s,"acc") == 0))
1631 if (strcmp(aop->aopu.aop_str[offset],s))
1632 pic14_emitcode ("mov","%s,%s ; %d",aop->aopu.aop_str[offset],s, __LINE__);
1636 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
1637 "aopPut got unsupported aop->type");
1643 /*-----------------------------------------------------------------*/
1644 /* mov2w - generate either a MOVLW or MOVFW based operand type */
1645 /*-----------------------------------------------------------------*/
1646 void mov2w (asmop *aop, int offset)
1652 DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
1654 if ( aop->type == AOP_PCODE ||
1655 aop->type == AOP_LIT ||
1656 aop->type == AOP_IMMD )
1657 emitpcode(POC_MOVLW,popGet(aop,offset));
1659 emitpcode(POC_MOVFW,popGet(aop,offset));
1663 /*-----------------------------------------------------------------*/
1664 /* reAdjustPreg - points a register back to where it should */
1665 /*-----------------------------------------------------------------*/
1666 static void reAdjustPreg (asmop *aop)
1670 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1672 if ((size = aop->size) <= 1)
1675 switch (aop->type) {
1679 pic14_emitcode("dec","%s",aop->aopu.aop_ptr->name);
1683 if (aop->type == AOP_DPTR2)
1689 pic14_emitcode("lcall","__decdptr");
1692 if (aop->type == AOP_DPTR2)
1704 /*-----------------------------------------------------------------*/
1705 /* opIsGptr: returns non-zero if the passed operand is */
1706 /* a generic pointer type. */
1707 /*-----------------------------------------------------------------*/
1708 static int opIsGptr(operand *op)
1710 sym_link *type = operandType(op);
1712 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1713 if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
1721 /*-----------------------------------------------------------------*/
1722 /* pic14_getDataSize - get the operand data size */
1723 /*-----------------------------------------------------------------*/
1724 int pic14_getDataSize(operand *op)
1726 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1729 return AOP_SIZE(op);
1731 // tsd- in the pic port, the genptr size is 1, so this code here
1732 // fails. ( in the 8051 port, the size was 4).
1735 size = AOP_SIZE(op);
1736 if (size == GPTRSIZE)
1738 sym_link *type = operandType(op);
1739 if (IS_GENPTR(type))
1741 /* generic pointer; arithmetic operations
1742 * should ignore the high byte (pointer type).
1745 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1752 /*-----------------------------------------------------------------*/
1753 /* pic14_outAcc - output Acc */
1754 /*-----------------------------------------------------------------*/
1755 void pic14_outAcc(operand *result)
1758 DEBUGpic14_emitcode ("; ***","%s %d - ",__FUNCTION__,__LINE__);
1759 DEBUGpic14_AopType(__LINE__,NULL,NULL,result);
1762 size = pic14_getDataSize(result);
1764 emitpcode(POC_MOVWF,popGet(AOP(result),0));
1767 /* unsigned or positive */
1769 emitpcode(POC_CLRF,popGet(AOP(result),offset++));
1774 /*-----------------------------------------------------------------*/
1775 /* pic14_outBitC - output a bit C */
1776 /*-----------------------------------------------------------------*/
1777 void pic14_outBitC(operand *result)
1780 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1781 /* if the result is bit */
1782 if (AOP_TYPE(result) == AOP_CRY)
1783 aopPut(AOP(result),"c",0);
1785 pic14_emitcode("clr","a ; %d", __LINE__);
1786 pic14_emitcode("rlc","a");
1787 pic14_outAcc(result);
1791 /*-----------------------------------------------------------------*/
1792 /* pic14_toBoolean - emit code for orl a,operator(sizeop) */
1793 /*-----------------------------------------------------------------*/
1794 void pic14_toBoolean(operand *oper)
1796 int size = AOP_SIZE(oper) - 1;
1799 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1801 if ( AOP_TYPE(oper) != AOP_ACC) {
1802 emitpcode(POC_MOVFW,popGet(AOP(oper),0));
1805 emitpcode(POC_IORFW, popGet(AOP(oper),offset++));
1810 /*-----------------------------------------------------------------*/
1811 /* genNot - generate code for ! operation */
1812 /*-----------------------------------------------------------------*/
1813 static void genNot (iCode *ic)
1818 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1819 /* assign asmOps to operand & result */
1820 aopOp (IC_LEFT(ic),ic,FALSE);
1821 aopOp (IC_RESULT(ic),ic,TRUE);
1823 DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
1824 /* if in bit space then a special case */
1825 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
1826 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
1827 emitpcode(POC_MOVLW,popGet(AOP(IC_LEFT(ic)),0));
1828 emitpcode(POC_XORWF,popGet(AOP(IC_RESULT(ic)),0));
1830 emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
1831 emitpcode(POC_BTFSS,popGet(AOP(IC_LEFT(ic)),0));
1832 emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
1837 size = AOP_SIZE(IC_LEFT(ic));
1839 emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
1840 emitpcode(POC_ANDLW,popGetLit(1));
1841 emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
1844 pic14_toBoolean(IC_LEFT(ic));
1846 tlbl = newiTempLabel(NULL);
1847 pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
1848 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
1849 pic14_outBitC(IC_RESULT(ic));
1852 /* release the aops */
1853 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1854 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1858 /*-----------------------------------------------------------------*/
1859 /* genCpl - generate code for complement */
1860 /*-----------------------------------------------------------------*/
1861 static void genCpl (iCode *ic)
1863 operand *left, *result;
1867 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1868 aopOp((left = IC_LEFT(ic)),ic,FALSE);
1869 aopOp((result=IC_RESULT(ic)),ic,TRUE);
1871 /* if both are in bit space then
1873 if (AOP_TYPE(result) == AOP_CRY &&
1874 AOP_TYPE(left) == AOP_CRY ) {
1876 pic14_emitcode("mov","c,%s",left->aop->aopu.aop_dir);
1877 pic14_emitcode("cpl","c");
1878 pic14_emitcode("mov","%s,c",result->aop->aopu.aop_dir);
1882 size = AOP_SIZE(result);
1885 if(AOP_TYPE(left) == AOP_ACC)
1886 emitpcode(POC_XORLW, popGetLit(0xff));
1888 emitpcode(POC_COMFW,popGet(AOP(left),offset));
1890 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
1896 /* release the aops */
1897 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1898 freeAsmop(result,NULL,ic,TRUE);
1901 /*-----------------------------------------------------------------*/
1902 /* genUminusFloat - unary minus for floating points */
1903 /*-----------------------------------------------------------------*/
1904 static void genUminusFloat(operand *op,operand *result)
1906 int size ,offset =0 ;
1909 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1910 /* for this we just need to flip the
1911 first it then copy the rest in place */
1912 size = AOP_SIZE(op) - 1;
1913 l = aopGet(AOP(op),3,FALSE,FALSE);
1917 pic14_emitcode("cpl","acc.7");
1918 aopPut(AOP(result),"a",3);
1922 aopGet(AOP(op),offset,FALSE,FALSE),
1928 /*-----------------------------------------------------------------*/
1929 /* genUminus - unary minus code generation */
1930 /*-----------------------------------------------------------------*/
1931 static void genUminus (iCode *ic)
1934 sym_link *optype, *rtype;
1937 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1939 aopOp(IC_LEFT(ic),ic,FALSE);
1940 aopOp(IC_RESULT(ic),ic,TRUE);
1942 /* if both in bit space then special
1944 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
1945 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
1947 emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0));
1948 emitpcode(POC_BTFSS, popGet(AOP(IC_LEFT(ic)),0));
1949 emitpcode(POC_BSF, popGet(AOP(IC_RESULT(ic)),0));
1954 optype = operandType(IC_LEFT(ic));
1955 rtype = operandType(IC_RESULT(ic));
1957 /* if float then do float stuff */
1958 if (IS_FLOAT(optype)) {
1959 genUminusFloat(IC_LEFT(ic),IC_RESULT(ic));
1963 /* otherwise subtract from zero by taking the 2's complement */
1964 size = AOP_SIZE(IC_LEFT(ic));
1966 for(i=0; i<size; i++) {
1967 if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) )
1968 emitpcode(POC_COMF, popGet(AOP(IC_LEFT(ic)),i));
1970 emitpcode(POC_COMFW, popGet(AOP(IC_LEFT(ic)),i));
1971 emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),i));
1975 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),0));
1976 for(i=1; i<size; i++) {
1978 emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),i));
1982 /* release the aops */
1983 freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
1984 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
1987 /*-----------------------------------------------------------------*/
1988 /* saveRegisters - will look for a call and save the registers */
1989 /*-----------------------------------------------------------------*/
1990 static void saveRegisters(iCode *lic)
1997 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
1999 for (ic = lic ; ic ; ic = ic->next)
2000 if (ic->op == CALL || ic->op == PCALL)
2004 fprintf(stderr,"found parameter push with no function call\n");
2008 /* if the registers have been saved already then
2010 if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type))
2013 /* find the registers in use at this time
2014 and push them away to safety */
2015 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2019 if (options.useXstack) {
2020 if (bitVectBitValue(rsave,R0_IDX))
2021 pic14_emitcode("mov","b,r0");
2022 pic14_emitcode("mov","r0,%s",spname);
2023 for (i = 0 ; i < pic14_nRegs ; i++) {
2024 if (bitVectBitValue(rsave,i)) {
2026 pic14_emitcode("mov","a,b");
2028 pic14_emitcode("mov","a,%s",pic14_regWithIdx(i)->name);
2029 pic14_emitcode("movx","@r0,a");
2030 pic14_emitcode("inc","r0");
2033 pic14_emitcode("mov","%s,r0",spname);
2034 if (bitVectBitValue(rsave,R0_IDX))
2035 pic14_emitcode("mov","r0,b");
2037 //for (i = 0 ; i < pic14_nRegs ; i++) {
2038 // if (bitVectBitValue(rsave,i))
2039 // pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2042 dtype = operandType(IC_LEFT(ic));
2043 if (currFunc && dtype &&
2044 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2045 IFFUNC_ISISR(currFunc->type) &&
2048 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2051 /*-----------------------------------------------------------------*/
2052 /* unsaveRegisters - pop the pushed registers */
2053 /*-----------------------------------------------------------------*/
2054 static void unsaveRegisters (iCode *ic)
2059 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2060 /* find the registers in use at this time
2061 and push them away to safety */
2062 rsave = bitVectCplAnd(bitVectCopy(ic->rMask),
2065 if (options.useXstack) {
2066 pic14_emitcode("mov","r0,%s",spname);
2067 for (i = pic14_nRegs ; i >= 0 ; i--) {
2068 if (bitVectBitValue(rsave,i)) {
2069 pic14_emitcode("dec","r0");
2070 pic14_emitcode("movx","a,@r0");
2072 pic14_emitcode("mov","b,a");
2074 pic14_emitcode("mov","%s,a",pic14_regWithIdx(i)->name);
2078 pic14_emitcode("mov","%s,r0",spname);
2079 if (bitVectBitValue(rsave,R0_IDX))
2080 pic14_emitcode("mov","r0,b");
2082 //for (i = pic14_nRegs ; i >= 0 ; i--) {
2083 // if (bitVectBitValue(rsave,i))
2084 // pic14_emitcode("pop","%s",pic14_regWithIdx(i)->dname);
2090 /*-----------------------------------------------------------------*/
2092 /*-----------------------------------------------------------------*/
2093 static void pushSide(operand * oper, int size)
2097 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2099 char *l = aopGet(AOP(oper),offset++,FALSE,TRUE);
2100 if (AOP_TYPE(oper) != AOP_REG &&
2101 AOP_TYPE(oper) != AOP_DIR &&
2103 pic14_emitcode("mov","a,%s",l);
2104 pic14_emitcode("push","acc");
2106 pic14_emitcode("push","%s",l);
2111 /*-----------------------------------------------------------------*/
2112 /* assignResultValue - */
2113 /*-----------------------------------------------------------------*/
2114 static void assignResultValue(operand * oper)
2116 int size = AOP_SIZE(oper);
2118 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2120 DEBUGpic14_AopType(__LINE__,oper,NULL,NULL);
2123 if (GpsuedoStkPtr++)
2124 emitpcode(POC_MOVFW,popRegFromIdx(Gstack_base_addr+2-GpsuedoStkPtr));
2125 emitpcode(POC_MOVWF, popGet(AOP(oper),size));
2130 /*-----------------------------------------------------------------*/
2131 /* genIpush - genrate code for pushing this gets a little complex */
2132 /*-----------------------------------------------------------------*/
2133 static void genIpush (iCode *ic)
2136 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2138 int size, offset = 0 ;
2142 /* if this is not a parm push : ie. it is spill push
2143 and spill push is always done on the local stack */
2144 if (!ic->parmPush) {
2146 /* and the item is spilt then do nothing */
2147 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2150 aopOp(IC_LEFT(ic),ic,FALSE);
2151 size = AOP_SIZE(IC_LEFT(ic));
2152 /* push it on the stack */
2154 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2159 pic14_emitcode("push","%s",l);
2164 /* this is a paramter push: in this case we call
2165 the routine to find the call and save those
2166 registers that need to be saved */
2169 /* then do the push */
2170 aopOp(IC_LEFT(ic),ic,FALSE);
2173 // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
2174 size = AOP_SIZE(IC_LEFT(ic));
2177 l = aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE);
2178 if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG &&
2179 AOP_TYPE(IC_LEFT(ic)) != AOP_DIR &&
2181 pic14_emitcode("mov","a,%s",l);
2182 pic14_emitcode("push","acc");
2184 pic14_emitcode("push","%s",l);
2187 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2191 /*-----------------------------------------------------------------*/
2192 /* genIpop - recover the registers: can happen only for spilling */
2193 /*-----------------------------------------------------------------*/
2194 static void genIpop (iCode *ic)
2196 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2201 /* if the temp was not pushed then */
2202 if (OP_SYMBOL(IC_LEFT(ic))->isspilt)
2205 aopOp(IC_LEFT(ic),ic,FALSE);
2206 size = AOP_SIZE(IC_LEFT(ic));
2209 pic14_emitcode("pop","%s",aopGet(AOP(IC_LEFT(ic)),offset--,
2212 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2216 /*-----------------------------------------------------------------*/
2217 /* unsaverbank - restores the resgister bank from stack */
2218 /*-----------------------------------------------------------------*/
2219 static void unsaverbank (int bank,iCode *ic,bool popPsw)
2221 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2227 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2229 if (options.useXstack) {
2231 r = getFreePtr(ic,&aop,FALSE);
2234 pic14_emitcode("mov","%s,_spx",r->name);
2235 pic14_emitcode("movx","a,@%s",r->name);
2236 pic14_emitcode("mov","psw,a");
2237 pic14_emitcode("dec","%s",r->name);
2240 pic14_emitcode ("pop","psw");
2243 for (i = (pic14_nRegs - 1) ; i >= 0 ;i--) {
2244 if (options.useXstack) {
2245 pic14_emitcode("movx","a,@%s",r->name);
2246 //pic14_emitcode("mov","(%s+%d),a",
2247 // regspic14[i].base,8*bank+regspic14[i].offset);
2248 pic14_emitcode("dec","%s",r->name);
2251 pic14_emitcode("pop",""); //"(%s+%d)",
2252 //regspic14[i].base,8*bank); //+regspic14[i].offset);
2255 if (options.useXstack) {
2257 pic14_emitcode("mov","_spx,%s",r->name);
2258 freeAsmop(NULL,aop,ic,TRUE);
2264 /*-----------------------------------------------------------------*/
2265 /* saverbank - saves an entire register bank on the stack */
2266 /*-----------------------------------------------------------------*/
2267 static void saverbank (int bank, iCode *ic, bool pushPsw)
2269 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2275 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2276 if (options.useXstack) {
2279 r = getFreePtr(ic,&aop,FALSE);
2280 pic14_emitcode("mov","%s,_spx",r->name);
2284 for (i = 0 ; i < pic14_nRegs ;i++) {
2285 if (options.useXstack) {
2286 pic14_emitcode("inc","%s",r->name);
2287 //pic14_emitcode("mov","a,(%s+%d)",
2288 // regspic14[i].base,8*bank+regspic14[i].offset);
2289 pic14_emitcode("movx","@%s,a",r->name);
2291 pic14_emitcode("push","");// "(%s+%d)",
2292 //regspic14[i].base,8*bank+regspic14[i].offset);
2296 if (options.useXstack) {
2297 pic14_emitcode("mov","a,psw");
2298 pic14_emitcode("movx","@%s,a",r->name);
2299 pic14_emitcode("inc","%s",r->name);
2300 pic14_emitcode("mov","_spx,%s",r->name);
2301 freeAsmop (NULL,aop,ic,TRUE);
2304 pic14_emitcode("push","psw");
2306 pic14_emitcode("mov","psw,#0x%02x",(bank << 3)&0x00ff);
2312 /*-----------------------------------------------------------------*/
2313 /* genCall - generates a call statement */
2314 /*-----------------------------------------------------------------*/
2315 static void genCall (iCode *ic)
2319 unsigned char *name;
2322 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2324 /* if caller saves & we have not saved then */
2328 /* if we are calling a function that is not using
2329 the same register bank then we need to save the
2330 destination registers on the stack */
2331 dtype = operandType(IC_LEFT(ic));
2332 if (currFunc && dtype &&
2333 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) &&
2334 IFFUNC_ISISR(currFunc->type) &&
2337 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2339 /* if send set is not empty the assign */
2342 /* For the Pic port, there is no data stack.
2343 * So parameters passed to functions are stored
2344 * in registers. (The pCode optimizer will get
2345 * rid of most of these :).
2347 int psuedoStkPtr=-1;
2348 int firstTimeThruLoop = 1;
2350 _G.sendSet = reverseSet(_G.sendSet);
2352 /* First figure how many parameters are getting passed */
2353 for (sic = setFirstItem(_G.sendSet) ; sic ;
2354 sic = setNextItem(_G.sendSet)) {
2356 aopOp(IC_LEFT(sic),sic,FALSE);
2357 psuedoStkPtr += AOP_SIZE(IC_LEFT(sic));
2358 freeAsmop (IC_LEFT(sic),NULL,sic,FALSE);
2361 for (sic = setFirstItem(_G.sendSet) ; sic ;
2362 sic = setNextItem(_G.sendSet)) {
2363 int size, offset = 0;
2365 aopOp(IC_LEFT(sic),sic,FALSE);
2366 size = AOP_SIZE(IC_LEFT(sic));
2369 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2370 AopType(AOP_TYPE(IC_LEFT(sic))));
2372 if(!firstTimeThruLoop) {
2373 /* If this is not the first time we've been through the loop
2374 * then we need to save the parameter in a temporary
2375 * register. The last byte of the last parameter is
2377 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr - --psuedoStkPtr));
2380 firstTimeThruLoop=0;
2382 mov2w (AOP(IC_LEFT(sic)), offset);
2385 freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
2390 sym = OP_SYMBOL(IC_LEFT(ic));
2391 name = sym->rname[0] ? sym->rname : sym->name;
2392 isExtern = IS_EXTERN(sym->etype);
2394 emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
2396 emitpcode(POC_CALL,popGetWithString(name,isExtern));
2398 emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel */
2401 /* if we need assign a result value */
2402 if ((IS_ITEMP(IC_RESULT(ic)) &&
2403 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2404 OP_SYMBOL(IC_RESULT(ic))->spildir )) ||
2405 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2408 aopOp(IC_RESULT(ic),ic,FALSE);
2411 assignResultValue(IC_RESULT(ic));
2413 DEBUGpic14_emitcode ("; ","%d left %s",__LINE__,
2414 AopType(AOP_TYPE(IC_RESULT(ic))));
2416 freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
2419 /* adjust the stack for parameters if
2421 if (ic->parmBytes) {
2423 if (ic->parmBytes > 3) {
2424 pic14_emitcode("mov","a,%s",spname);
2425 pic14_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff);
2426 pic14_emitcode("mov","%s,a",spname);
2428 for ( i = 0 ; i < ic->parmBytes ;i++)
2429 pic14_emitcode("dec","%s",spname);
2433 /* if register bank was saved then pop them */
2435 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2437 /* if we hade saved some registers then unsave them */
2438 if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
2439 unsaveRegisters (ic);
2444 /*-----------------------------------------------------------------*/
2445 /* genPcall - generates a call by pointer statement */
2446 /*-----------------------------------------------------------------*/
2447 static void genPcall (iCode *ic)
2450 symbol *albl = newiTempLabel(NULL);
2451 symbol *blbl = newiTempLabel(NULL);
2456 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2457 /* if caller saves & we have not saved then */
2461 /* if we are calling a function that is not using
2462 the same register bank then we need to save the
2463 destination registers on the stack */
2464 dtype = operandType(IC_LEFT(ic));
2465 if (currFunc && dtype &&
2466 IFFUNC_ISISR(currFunc->type) &&
2467 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2468 saverbank(FUNC_REGBANK(dtype),ic,TRUE);
2471 aopOp(left,ic,FALSE);
2472 DEBUGpic14_AopType(__LINE__,left,NULL,NULL);
2474 pushSide(IC_LEFT(ic), FPTRSIZE);
2476 /* if send set is not empty, assign parameters */
2479 DEBUGpic14_emitcode ("; ***","%s %d - WARNING arg-passing to indirect call not supported",__FUNCTION__,__LINE__);
2480 /* no way to pass args - W always gets used to make the call */
2482 /* first idea - factor out a common helper function and call it.
2483 But don't know how to get it generated only once in its own block
2485 if(AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) {
2488 rname = IC_LEFT(ic)->aop->aopu.aop_dir;
2489 DEBUGpic14_emitcode ("; ***","%s %d AOP_DIR %s",__FUNCTION__,__LINE__,rname);
2490 buffer = Safe_calloc(1,strlen(rname)+16);
2491 sprintf(buffer, "%s_goto_helper", rname);
2492 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp(buffer,PO_STR)));
2496 emitpcode(POC_CALL,popGetLabel(albl->key));
2497 pcop = popGetLabel(blbl->key);
2498 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
2499 emitpcode(POC_GOTO,pcop);
2500 emitpLabel(albl->key);
2502 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
2504 emitpcode(poc,popGet(AOP(left),1));
2505 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
2506 emitpcode(poc,popGet(AOP(left),0));
2507 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
2509 emitpLabel(blbl->key);
2511 freeAsmop(IC_LEFT(ic),NULL,ic,TRUE);
2513 /* if we need to assign a result value */
2514 if ((IS_ITEMP(IC_RESULT(ic)) &&
2515 (OP_SYMBOL(IC_RESULT(ic))->nRegs ||
2516 OP_SYMBOL(IC_RESULT(ic))->spildir)) ||
2517 IS_TRUE_SYMOP(IC_RESULT(ic)) ) {
2520 aopOp(IC_RESULT(ic),ic,FALSE);
2523 assignResultValue(IC_RESULT(ic));
2525 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
2528 /* if register bank was saved then unsave them */
2529 if (currFunc && dtype &&
2530 (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)))
2531 unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
2533 /* if we hade saved some registers then
2536 unsaveRegisters (ic);
2540 /*-----------------------------------------------------------------*/
2541 /* resultRemat - result is rematerializable */
2542 /*-----------------------------------------------------------------*/
2543 static int resultRemat (iCode *ic)
2545 // DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2546 if (SKIP_IC(ic) || ic->op == IFX)
2549 if (IC_RESULT(ic) && IS_ITEMP(IC_RESULT(ic))) {
2550 symbol *sym = OP_SYMBOL(IC_RESULT(ic));
2551 if (sym->remat && !POINTER_SET(ic))
2558 #if defined(__BORLANDC__) || defined(_MSC_VER)
2559 #define STRCASECMP stricmp
2561 #define STRCASECMP strcasecmp
2565 /*-----------------------------------------------------------------*/
2566 /* inExcludeList - return 1 if the string is in exclude Reg list */
2567 /*-----------------------------------------------------------------*/
2568 static bool inExcludeList(char *s)
2570 DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__);
2573 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2574 if (options.excludeRegs[i] &&
2575 STRCASECMP(options.excludeRegs[i],"none") == 0)
2578 for ( i = 0 ; options.excludeRegs[i]; i++) {
2579 if (options.excludeRegs[i] &&
2580 STRCASECMP(s,options.excludeRegs[i]) == 0)
2587 /*-----------------------------------------------------------------*/
2588 /* genFunction - generated code for function entry */
2589 /*-----------------------------------------------------------------*/
2590 static void genFunction (iCode *ic)
2595 DEBUGpic14_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
2597 labelOffset += (max_key+4);
2601 /* create the function header */
2602 pic14_emitcode(";","-----------------------------------------");
2603 pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
2604 pic14_emitcode(";","-----------------------------------------");
2606 pic14_emitcode("","%s:",sym->rname);
2607 addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
2609 ftype = operandType(IC_LEFT(ic));
2611 /* if critical function then turn interrupts off */
2612 if (IFFUNC_ISCRITICAL(ftype))
2613 pic14_emitcode("clr","ea");
2615 /* here we need to generate the equates for the
2616 register bank if required */
2618 if (FUNC_REGBANK(ftype) != rbank) {
2621 rbank = FUNC_REGBANK(ftype);
2622 for ( i = 0 ; i < pic14_nRegs ; i++ ) {
2623 if (strcmp(regspic14[i].base,"0") == 0)
2624 pic14_emitcode("","%s = 0x%02x",
2626 8*rbank+regspic14[i].offset);
2628 pic14_emitcode ("","%s = %s + 0x%02x",
2631 8*rbank+regspic14[i].offset);
2636 /* if this is an interrupt service routine */
2637 if (IFFUNC_ISISR(sym->type)) {
2638 /* already done in pic14createInterruptVect() - delete me
2639 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
2640 emitpcodeNULLop(POC_NOP);
2641 emitpcodeNULLop(POC_NOP);
2642 emitpcodeNULLop(POC_NOP);
2644 emitpcode(POC_MOVWF, popCopyReg(&pc_wsave));
2645 emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
2646 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2647 emitpcode(POC_MOVWF, popCopyReg(&pc_ssave));
2648 emitpcode(POC_MOVFW, popCopyReg(&pc_pclath));
2649 emitpcode(POC_MOVWF, popCopyReg(&pc_psave));
2650 emitpcode(POC_CLRF, popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
2652 pBlockConvert2ISR(pb);
2654 if (!inExcludeList("acc"))
2655 pic14_emitcode ("push","acc");
2656 if (!inExcludeList("b"))
2657 pic14_emitcode ("push","b");
2658 if (!inExcludeList("dpl"))
2659 pic14_emitcode ("push","dpl");
2660 if (!inExcludeList("dph"))
2661 pic14_emitcode ("push","dph");
2662 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2664 pic14_emitcode ("push", "dpx");
2665 /* Make sure we're using standard DPTR */
2666 pic14_emitcode ("push", "dps");
2667 pic14_emitcode ("mov", "dps, #0x00");
2668 if (options.stack10bit)
2670 /* This ISR could conceivably use DPTR2. Better save it. */
2671 pic14_emitcode ("push", "dpl1");
2672 pic14_emitcode ("push", "dph1");
2673 pic14_emitcode ("push", "dpx1");
2676 /* if this isr has no bank i.e. is going to
2677 run with bank 0 , then we need to save more
2679 if (!FUNC_REGBANK(sym->type)) {
2681 /* if this function does not call any other
2682 function then we can be economical and
2683 save only those registers that are used */
2684 if (! IFFUNC_HASFCALL(sym->type)) {
2687 /* if any registers used */
2688 if (sym->regsUsed) {
2689 /* save the registers used */
2690 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2691 if (bitVectBitValue(sym->regsUsed,i) ||
2692 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2693 pic14_emitcode("push","junk");//"%s",pic14_regWithIdx(i)->dname);
2698 /* this function has a function call cannot
2699 determines register usage so we will have the
2701 saverbank(0,ic,FALSE);
2706 /* if callee-save to be used for this function
2707 then save the registers being used in this function */
2708 if (IFFUNC_CALLEESAVES(sym->type)) {
2711 /* if any registers used */
2712 if (sym->regsUsed) {
2713 /* save the registers used */
2714 for ( i = 0 ; i < sym->regsUsed->size ; i++) {
2715 if (bitVectBitValue(sym->regsUsed,i) ||
2716 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
2717 //pic14_emitcode("push","%s",pic14_regWithIdx(i)->dname);
2725 /* set the register bank to the desired value */
2726 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
2727 pic14_emitcode("push","psw");
2728 pic14_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);
2731 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
2733 if (options.useXstack) {
2734 pic14_emitcode("mov","r0,%s",spname);
2735 pic14_emitcode("mov","a,_bp");
2736 pic14_emitcode("movx","@r0,a");
2737 pic14_emitcode("inc","%s",spname);
2741 /* set up the stack */
2742 pic14_emitcode ("push","_bp"); /* save the callers stack */
2744 pic14_emitcode ("mov","_bp,%s",spname);
2747 /* adjust the stack for the function */
2752 werror(W_STACK_OVERFLOW,sym->name);
2754 if (i > 3 && sym->recvSize < 4) {
2756 pic14_emitcode ("mov","a,sp");
2757 pic14_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
2758 pic14_emitcode ("mov","sp,a");
2763 pic14_emitcode("inc","sp");
2768 pic14_emitcode ("mov","a,_spx");
2769 pic14_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
2770 pic14_emitcode ("mov","_spx,a");
2775 /*-----------------------------------------------------------------*/
2776 /* genEndFunction - generates epilogue for functions */
2777 /*-----------------------------------------------------------------*/
2778 static void genEndFunction (iCode *ic)
2780 symbol *sym = OP_SYMBOL(IC_LEFT(ic));
2782 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2784 if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
2786 pic14_emitcode ("mov","%s,_bp",spname);
2789 /* if use external stack but some variables were
2790 added to the local stack then decrement the
2792 if (options.useXstack && sym->stack) {
2793 pic14_emitcode("mov","a,sp");
2794 pic14_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
2795 pic14_emitcode("mov","sp,a");
2799 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
2800 if (options.useXstack) {
2801 pic14_emitcode("mov","r0,%s",spname);
2802 pic14_emitcode("movx","a,@r0");
2803 pic14_emitcode("mov","_bp,a");
2804 pic14_emitcode("dec","%s",spname);
2808 pic14_emitcode ("pop","_bp");
2812 /* restore the register bank */
2813 if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
2814 pic14_emitcode ("pop","psw");
2816 if (IFFUNC_ISISR(sym->type)) {
2818 /* now we need to restore the registers */
2819 /* if this isr has no bank i.e. is going to
2820 run with bank 0 , then we need to save more
2822 if (!FUNC_REGBANK(sym->type)) {
2824 /* if this function does not call any other
2825 function then we can be economical and
2826 save only those registers that are used */
2827 if (! IFFUNC_HASFCALL(sym->type)) {
2830 /* if any registers used */
2831 if (sym->regsUsed) {
2832 /* save the registers used */
2833 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2834 if (bitVectBitValue(sym->regsUsed,i) ||
2835 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2836 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2841 /* this function has a function call cannot
2842 determines register usage so we will have the
2844 unsaverbank(0,ic,FALSE);
2848 if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
2850 if (options.stack10bit)
2852 pic14_emitcode ("pop", "dpx1");
2853 pic14_emitcode ("pop", "dph1");
2854 pic14_emitcode ("pop", "dpl1");
2856 pic14_emitcode ("pop", "dps");
2857 pic14_emitcode ("pop", "dpx");
2859 if (!inExcludeList("dph"))
2860 pic14_emitcode ("pop","dph");
2861 if (!inExcludeList("dpl"))
2862 pic14_emitcode ("pop","dpl");
2863 if (!inExcludeList("b"))
2864 pic14_emitcode ("pop","b");
2865 if (!inExcludeList("acc"))
2866 pic14_emitcode ("pop","acc");
2868 if (IFFUNC_ISCRITICAL(sym->type))
2869 pic14_emitcode("setb","ea");
2872 /* if debug then send end of function */
2873 /* if (options.debug && currFunc) { */
2876 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2877 FileBaseName(ic->filename),currFunc->lastLine,
2878 ic->level,ic->block);
2879 if (IS_STATIC(currFunc->etype))
2880 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2882 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2886 pic14_emitcode ("reti","");
2887 emitpcode(POC_MOVFW, popCopyReg(&pc_psave));
2888 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
2889 emitpcode(POC_CLRF, popCopyReg(&pc_status));
2890 emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
2891 emitpcode(POC_MOVWF, popCopyReg(&pc_status));
2892 emitpcode(POC_SWAPF, popCopyReg(&pc_wsave));
2893 emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
2894 addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
2895 emitpcodeNULLop(POC_RETFIE);
2898 if (IFFUNC_ISCRITICAL(sym->type))
2899 pic14_emitcode("setb","ea");
2901 if (IFFUNC_CALLEESAVES(sym->type)) {
2904 /* if any registers used */
2905 if (sym->regsUsed) {
2906 /* save the registers used */
2907 for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
2908 if (bitVectBitValue(sym->regsUsed,i) ||
2909 (pic14_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
2910 pic14_emitcode("pop","junk");//"%s",pic14_regWithIdx(i)->dname);
2916 /* if debug then send end of function */
2919 pic14_emitcode(";","C$%s$%d$%d$%d ==.",
2920 FileBaseName(ic->filename),currFunc->lastLine,
2921 ic->level,ic->block);
2922 if (IS_STATIC(currFunc->etype))
2923 pic14_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name);
2925 pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
2929 pic14_emitcode ("return","");
2930 emitpcodeNULLop(POC_RETURN);
2932 /* Mark the end of a function */
2933 addpCode2pBlock(pb,newpCodeFunction(NULL,NULL,0));
2938 /*-----------------------------------------------------------------*/
2939 /* genRet - generate code for return statement */
2940 /*-----------------------------------------------------------------*/
2941 static void genRet (iCode *ic)
2943 int size,offset = 0 , pushed = 0;
2945 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
2946 /* if we have no return value then
2947 just generate the "ret" */
2951 /* we have something to return then
2952 move the return value into place */
2953 aopOp(IC_LEFT(ic),ic,FALSE);
2954 size = AOP_SIZE(IC_LEFT(ic));
2958 if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
2960 l = aopGet(AOP(IC_LEFT(ic)),offset++,
2962 pic14_emitcode("push","%s",l);
2965 l = aopGet(AOP(IC_LEFT(ic)),offset,
2967 if (strcmp(fReturn[offset],l)) {
2968 if ((((AOP(IC_LEFT(ic))->type) == AOP_PCODE) &&
2969 AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
2970 ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
2971 ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
2972 emitpcode(POC_MOVLW, popGet(AOP(IC_LEFT(ic)),offset));
2974 emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
2977 emitpcode(POC_MOVWF,popRegFromIdx(Gstack_base_addr+1-size));
2987 if (strcmp(fReturn[pushed],"a"))
2988 pic14_emitcode("pop",fReturn[pushed]);
2990 pic14_emitcode("pop","acc");
2993 freeAsmop (IC_LEFT(ic),NULL,ic,TRUE);
2996 /* generate a jump to the return label
2997 if the next is not the return statement */
2998 if (!(ic->next && ic->next->op == LABEL &&
2999 IC_LABEL(ic->next) == returnLabel)) {
3001 emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
3002 pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
3007 /*-----------------------------------------------------------------*/
3008 /* genLabel - generates a label */
3009 /*-----------------------------------------------------------------*/
3010 static void genLabel (iCode *ic)
3012 /* special case never generate */
3013 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3014 if (IC_LABEL(ic) == entryLabel)
3017 emitpLabel(IC_LABEL(ic)->key);
3018 pic14_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset));
3021 /*-----------------------------------------------------------------*/
3022 /* genGoto - generates a goto */
3023 /*-----------------------------------------------------------------*/
3025 static void genGoto (iCode *ic)
3027 emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
3028 pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
3032 /*-----------------------------------------------------------------*/
3033 /* genMultbits :- multiplication of bits */
3034 /*-----------------------------------------------------------------*/
3035 static void genMultbits (operand *left,
3039 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3041 if(!pic14_sameRegs(AOP(result),AOP(right)))
3042 emitpcode(POC_BSF, popGet(AOP(result),0));
3044 emitpcode(POC_BTFSC,popGet(AOP(right),0));
3045 emitpcode(POC_BTFSS,popGet(AOP(left),0));
3046 emitpcode(POC_BCF, popGet(AOP(result),0));
3051 /*-----------------------------------------------------------------*/
3052 /* genMultOneByte : 8 bit multiplication & division */
3053 /*-----------------------------------------------------------------*/
3054 static void genMultOneByte (operand *left,
3058 sym_link *opetype = operandType(result);
3063 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3064 DEBUGpic14_AopType(__LINE__,left,right,result);
3065 DEBUGpic14_AopTypeSign(__LINE__,left,right,result);
3067 /* (if two literals, the value is computed before) */
3068 /* if one literal, literal on the right */
3069 if (AOP_TYPE(left) == AOP_LIT){
3075 size = AOP_SIZE(result);
3078 if (AOP_TYPE(right) == AOP_LIT){
3079 pic14_emitcode("multiply ","lit val:%s by variable %s and store in %s",
3080 aopGet(AOP(right),0,FALSE,FALSE),
3081 aopGet(AOP(left),0,FALSE,FALSE),
3082 aopGet(AOP(result),0,FALSE,FALSE));
3083 pic14_emitcode("call","genMultLit");
3085 pic14_emitcode("multiply ","variable :%s by variable %s and store in %s",
3086 aopGet(AOP(right),0,FALSE,FALSE),
3087 aopGet(AOP(left),0,FALSE,FALSE),
3088 aopGet(AOP(result),0,FALSE,FALSE));
3089 pic14_emitcode("call","genMult8X8_8");
3092 genMult8X8_8 (left, right,result);
3095 /* signed or unsigned */
3096 //pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3097 //l = aopGet(AOP(left),0,FALSE,FALSE);
3099 //pic14_emitcode("mul","ab");
3100 /* if result size = 1, mul signed = mul unsigned */
3101 //aopPut(AOP(result),"a",0);
3103 } else { // (size > 1)
3105 pic14_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s",
3106 aopGet(AOP(right),0,FALSE,FALSE),
3107 aopGet(AOP(left),0,FALSE,FALSE),
3108 aopGet(AOP(result),0,FALSE,FALSE));
3110 if (SPEC_USIGN(opetype)){
3111 pic14_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result));
3112 genUMult8X8_16 (left, right, result, NULL);
3115 /* for filling the MSBs */
3116 emitpcode(POC_CLRF, popGet(AOP(result),2));
3117 emitpcode(POC_CLRF, popGet(AOP(result),3));
3121 pic14_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result));
3123 pic14_emitcode("mov","a,b");
3125 /* adjust the MSB if left or right neg */
3127 /* if one literal */
3128 if (AOP_TYPE(right) == AOP_LIT){
3129 pic14_emitcode("multiply ","right is a lit");
3130 /* AND literal negative */
3131 if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){
3132 /* adjust MSB (c==0 after mul) */
3133 pic14_emitcode("subb","a,%s", aopGet(AOP(left),0,FALSE,FALSE));
3137 genSMult8X8_16 (left, right, result, NULL);
3141 pic14_emitcode("multiply ","size is greater than 2, so propogate sign");
3143 pic14_emitcode("rlc","a");
3144 pic14_emitcode("subb","a,acc");
3152 pic14_emitcode("multiply ","size is way greater than 2, so propogate sign");
3153 //aopPut(AOP(result),"a",offset++);
3157 /*-----------------------------------------------------------------*/
3158 /* genMult - generates code for multiplication */
3159 /*-----------------------------------------------------------------*/
3160 static void genMult (iCode *ic)
3162 operand *left = IC_LEFT(ic);
3163 operand *right = IC_RIGHT(ic);
3164 operand *result= IC_RESULT(ic);
3166 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3167 /* assign the amsops */
3168 aopOp (left,ic,FALSE);
3169 aopOp (right,ic,FALSE);
3170 aopOp (result,ic,TRUE);
3172 DEBUGpic14_AopType(__LINE__,left,right,result);
3174 /* special cases first */
3176 if (AOP_TYPE(left) == AOP_CRY &&
3177 AOP_TYPE(right)== AOP_CRY) {
3178 genMultbits(left,right,result);
3182 /* if both are of size == 1 */
3183 if (AOP_SIZE(left) == 1 &&
3184 AOP_SIZE(right) == 1 ) {
3185 genMultOneByte(left,right,result);
3189 pic14_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
3191 /* should have been converted to function call */
3195 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3196 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3197 freeAsmop(result,NULL,ic,TRUE);
3200 /*-----------------------------------------------------------------*/
3201 /* genDivbits :- division of bits */
3202 /*-----------------------------------------------------------------*/
3203 static void genDivbits (operand *left,
3210 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3211 /* the result must be bit */
3212 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3213 l = aopGet(AOP(left),0,FALSE,FALSE);
3217 pic14_emitcode("div","ab");
3218 pic14_emitcode("rrc","a");
3219 aopPut(AOP(result),"c",0);
3222 /*-----------------------------------------------------------------*/
3223 /* genDivOneByte : 8 bit division */
3224 /*-----------------------------------------------------------------*/
3225 static void genDivOneByte (operand *left,
3229 sym_link *opetype = operandType(result);
3234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3235 size = AOP_SIZE(result) - 1;
3237 /* signed or unsigned */
3238 if (SPEC_USIGN(opetype)) {
3239 /* unsigned is easy */
3240 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3241 l = aopGet(AOP(left),0,FALSE,FALSE);
3243 pic14_emitcode("div","ab");
3244 aopPut(AOP(result),"a",0);
3246 aopPut(AOP(result),zero,offset++);
3250 /* signed is a little bit more difficult */
3252 /* save the signs of the operands */
3253 l = aopGet(AOP(left),0,FALSE,FALSE);
3255 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,TRUE));
3256 pic14_emitcode("push","acc"); /* save it on the stack */
3258 /* now sign adjust for both left & right */
3259 l = aopGet(AOP(right),0,FALSE,FALSE);
3261 lbl = newiTempLabel(NULL);
3262 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3263 pic14_emitcode("cpl","a");
3264 pic14_emitcode("inc","a");
3265 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3266 pic14_emitcode("mov","b,a");
3268 /* sign adjust left side */
3269 l = aopGet(AOP(left),0,FALSE,FALSE);
3272 lbl = newiTempLabel(NULL);
3273 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3274 pic14_emitcode("cpl","a");
3275 pic14_emitcode("inc","a");
3276 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3278 /* now the division */
3279 pic14_emitcode("div","ab");
3280 /* we are interested in the lower order
3282 pic14_emitcode("mov","b,a");
3283 lbl = newiTempLabel(NULL);
3284 pic14_emitcode("pop","acc");
3285 /* if there was an over flow we don't
3286 adjust the sign of the result */
3287 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3288 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3290 pic14_emitcode("clr","a");
3291 pic14_emitcode("subb","a,b");
3292 pic14_emitcode("mov","b,a");
3293 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3295 /* now we are done */
3296 aopPut(AOP(result),"b",0);
3298 pic14_emitcode("mov","c,b.7");
3299 pic14_emitcode("subb","a,acc");
3302 aopPut(AOP(result),"a",offset++);
3306 /*-----------------------------------------------------------------*/
3307 /* genDiv - generates code for division */
3308 /*-----------------------------------------------------------------*/
3309 static void genDiv (iCode *ic)
3311 operand *left = IC_LEFT(ic);
3312 operand *right = IC_RIGHT(ic);
3313 operand *result= IC_RESULT(ic);
3315 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3316 /* assign the amsops */
3317 aopOp (left,ic,FALSE);
3318 aopOp (right,ic,FALSE);
3319 aopOp (result,ic,TRUE);
3321 /* special cases first */
3323 if (AOP_TYPE(left) == AOP_CRY &&
3324 AOP_TYPE(right)== AOP_CRY) {
3325 genDivbits(left,right,result);
3329 /* if both are of size == 1 */
3330 if (AOP_SIZE(left) == 1 &&
3331 AOP_SIZE(right) == 1 ) {
3332 genDivOneByte(left,right,result);
3336 /* should have been converted to function call */
3339 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3340 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3341 freeAsmop(result,NULL,ic,TRUE);
3344 /*-----------------------------------------------------------------*/
3345 /* genModbits :- modulus of bits */
3346 /*-----------------------------------------------------------------*/
3347 static void genModbits (operand *left,
3354 /* the result must be bit */
3355 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
3356 l = aopGet(AOP(left),0,FALSE,FALSE);
3360 pic14_emitcode("div","ab");
3361 pic14_emitcode("mov","a,b");
3362 pic14_emitcode("rrc","a");
3363 aopPut(AOP(result),"c",0);
3366 /*-----------------------------------------------------------------*/
3367 /* genModOneByte : 8 bit modulus */
3368 /*-----------------------------------------------------------------*/
3369 static void genModOneByte (operand *left,
3373 sym_link *opetype = operandType(result);
3377 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3378 /* signed or unsigned */
3379 if (SPEC_USIGN(opetype)) {
3380 /* unsigned is easy */
3381 pic14_emitcode("mov","b,%s", aopGet(AOP(right),0,FALSE,FALSE));
3382 l = aopGet(AOP(left),0,FALSE,FALSE);
3384 pic14_emitcode("div","ab");
3385 aopPut(AOP(result),"b",0);
3389 /* signed is a little bit more difficult */
3391 /* save the signs of the operands */
3392 l = aopGet(AOP(left),0,FALSE,FALSE);
3395 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),0,FALSE,FALSE));
3396 pic14_emitcode("push","acc"); /* save it on the stack */
3398 /* now sign adjust for both left & right */
3399 l = aopGet(AOP(right),0,FALSE,FALSE);
3402 lbl = newiTempLabel(NULL);
3403 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3404 pic14_emitcode("cpl","a");
3405 pic14_emitcode("inc","a");
3406 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3407 pic14_emitcode("mov","b,a");
3409 /* sign adjust left side */
3410 l = aopGet(AOP(left),0,FALSE,FALSE);
3413 lbl = newiTempLabel(NULL);
3414 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3415 pic14_emitcode("cpl","a");
3416 pic14_emitcode("inc","a");
3417 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3419 /* now the multiplication */
3420 pic14_emitcode("div","ab");
3421 /* we are interested in the lower order
3423 lbl = newiTempLabel(NULL);
3424 pic14_emitcode("pop","acc");
3425 /* if there was an over flow we don't
3426 adjust the sign of the result */
3427 pic14_emitcode("jb","ov,%05d_DS_",(lbl->key+100));
3428 pic14_emitcode("jnb","acc.7,%05d_DS_",(lbl->key+100));
3430 pic14_emitcode("clr","a");
3431 pic14_emitcode("subb","a,b");
3432 pic14_emitcode("mov","b,a");
3433 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
3435 /* now we are done */
3436 aopPut(AOP(result),"b",0);
3440 /*-----------------------------------------------------------------*/
3441 /* genMod - generates code for division */
3442 /*-----------------------------------------------------------------*/
3443 static void genMod (iCode *ic)
3445 operand *left = IC_LEFT(ic);
3446 operand *right = IC_RIGHT(ic);
3447 operand *result= IC_RESULT(ic);
3449 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3450 /* assign the amsops */
3451 aopOp (left,ic,FALSE);
3452 aopOp (right,ic,FALSE);
3453 aopOp (result,ic,TRUE);
3455 /* special cases first */
3457 if (AOP_TYPE(left) == AOP_CRY &&
3458 AOP_TYPE(right)== AOP_CRY) {
3459 genModbits(left,right,result);
3463 /* if both are of size == 1 */
3464 if (AOP_SIZE(left) == 1 &&
3465 AOP_SIZE(right) == 1 ) {
3466 genModOneByte(left,right,result);
3470 /* should have been converted to function call */
3474 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3475 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
3476 freeAsmop(result,NULL,ic,TRUE);
3479 /*-----------------------------------------------------------------*/
3480 /* genIfxJump :- will create a jump depending on the ifx */
3481 /*-----------------------------------------------------------------*/
3483 note: May need to add parameter to indicate when a variable is in bit space.
3485 static void genIfxJump (iCode *ic, char *jval)
3488 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3489 /* if true label then we jump if condition
3491 if ( IC_TRUE(ic) ) {
3493 if(strcmp(jval,"a") == 0)
3495 else if (strcmp(jval,"c") == 0)
3498 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3499 emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1));
3502 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
3503 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset);
3507 /* false label is present */
3508 if(strcmp(jval,"a") == 0)
3510 else if (strcmp(jval,"c") == 0)
3513 DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);
3514 emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1));
3517 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
3518 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset);
3523 /* mark the icode as generated */
3527 /*-----------------------------------------------------------------*/
3529 /*-----------------------------------------------------------------*/
3530 static void genSkip(iCode *ifx,int status_bit)
3535 if ( IC_TRUE(ifx) ) {
3536 switch(status_bit) {
3551 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3552 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3556 switch(status_bit) {
3570 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3571 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3577 /*-----------------------------------------------------------------*/
3579 /*-----------------------------------------------------------------*/
3580 static void genSkipc(resolvedIfx *rifx)
3590 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3591 rifx->generated = 1;
3594 /*-----------------------------------------------------------------*/
3596 /*-----------------------------------------------------------------*/
3597 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
3602 if( (rifx->condition ^ invert_condition) & 1)
3607 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3608 rifx->generated = 1;
3611 /*-----------------------------------------------------------------*/
3613 /*-----------------------------------------------------------------*/
3614 static void genSkipz(iCode *ifx, int condition)
3625 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
3627 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
3630 pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
3632 pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
3635 /*-----------------------------------------------------------------*/
3637 /*-----------------------------------------------------------------*/
3638 static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit)
3644 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3646 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0));
3649 emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
3650 rifx->generated = 1;
3654 /*-----------------------------------------------------------------*/
3655 /* genChkZeroes :- greater or less than comparison */
3656 /* For each byte in a literal that is zero, inclusive or the */
3657 /* the corresponding byte in the operand with W */
3658 /* returns true if any of the bytes are zero */
3659 /*-----------------------------------------------------------------*/
3660 static int genChkZeroes(operand *op, int lit, int size)
3667 i = (lit >> (size*8)) & 0xff;
3671 emitpcode(POC_MOVFW, popGet(AOP(op),size));
3673 emitpcode(POC_IORFW, popGet(AOP(op),size));
3682 /*-----------------------------------------------------------------*/
3683 /* genCmp :- greater or less than comparison */
3684 /*-----------------------------------------------------------------*/
3685 static void genCmp (operand *left,operand *right,
3686 operand *result, iCode *ifx, int sign)
3688 int size; //, offset = 0 ;
3689 unsigned long lit = 0L,i = 0;
3690 resolvedIfx rFalseIfx;
3691 // resolvedIfx rTrueIfx;
3693 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
3696 DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true"));
3697 DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true"));
3701 resolveIfx(&rFalseIfx,ifx);
3702 truelbl = newiTempLabel(NULL);
3703 size = max(AOP_SIZE(left),AOP_SIZE(right));
3705 DEBUGpic14_AopType(__LINE__,left,right,result);
3709 /* if literal is on the right then swap with left */
3710 if ((AOP_TYPE(right) == AOP_LIT)) {
3711 operand *tmp = right ;
3712 unsigned long mask = (0x100 << (8*(size-1))) - 1;
3713 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3716 lit = (lit - 1) & mask;
3719 rFalseIfx.condition ^= 1;
3722 } else if ((AOP_TYPE(left) == AOP_LIT)) {
3723 lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
3727 //if(IC_TRUE(ifx) == NULL)
3728 /* if left & right are bit variables */
3729 if (AOP_TYPE(left) == AOP_CRY &&
3730 AOP_TYPE(right) == AOP_CRY ) {
3731 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
3732 pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
3734 /* subtract right from left if at the
3735 end the carry flag is set then we know that
3736 left is greater than right */
3740 symbol *lbl = newiTempLabel(NULL);
3743 if(AOP_TYPE(right) == AOP_LIT) {
3745 //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
3747 DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
3754 genSkipCond(&rFalseIfx,left,size-1,7);
3756 /* no need to compare to 0...*/
3757 /* NOTE: this is a de-generate compare that most certainly
3758 * creates some dead code. */
3759 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
3761 if(ifx) ifx->generated = 1;
3768 //i = (lit >> (size*8)) & 0xff;
3769 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3771 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3773 i = ((0-lit) & 0xff);
3776 /* lit is 0x7f, all signed chars are less than
3777 * this except for 0x7f itself */
3778 emitpcode(POC_XORLW, popGetLit(0x7f));
3779 genSkipz2(&rFalseIfx,0);
3781 emitpcode(POC_ADDLW, popGetLit(0x80));
3782 emitpcode(POC_ADDLW, popGetLit(i^0x80));
3783 genSkipc(&rFalseIfx);
3788 genSkipz2(&rFalseIfx,1);
3790 emitpcode(POC_ADDLW, popGetLit(i));
3791 genSkipc(&rFalseIfx);
3795 if(ifx) ifx->generated = 1;
3799 /* chars are out of the way. now do ints and longs */
3802 DEBUGpic14_emitcode(";right lit","line = %d",__LINE__);
3809 genSkipCond(&rFalseIfx,left,size,7);
3810 if(ifx) ifx->generated = 1;
3815 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3817 //rFalseIfx.condition ^= 1;
3818 //genSkipCond(&rFalseIfx,left,size,7);
3819 //rFalseIfx.condition ^= 1;
3821 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3822 if(rFalseIfx.condition)
3823 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3825 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3827 emitpcode(POC_MOVLW, popGetLit(0x100-lit));
3828 emitpcode(POC_ADDFW, popGet(AOP(left),0));
3829 emitpcode(POC_MOVFW, popGet(AOP(left),1));
3832 emitpcode(POC_IORFW, popGet(AOP(left),size--));
3834 if(rFalseIfx.condition) {
3836 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3842 genSkipc(&rFalseIfx);
3843 emitpLabel(truelbl->key);
3844 if(ifx) ifx->generated = 1;
3851 if( (lit & 0xff) == 0) {
3852 /* lower byte is zero */
3853 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3854 i = ((lit >> 8) & 0xff) ^0x80;
3855 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3856 emitpcode(POC_ADDLW, popGetLit( 0x80));
3857 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3858 genSkipc(&rFalseIfx);
3861 if(ifx) ifx->generated = 1;
3866 /* Special cases for signed longs */
3867 if( (lit & 0xffffff) == 0) {
3868 /* lower byte is zero */
3869 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3870 i = ((lit >> 8*3) & 0xff) ^0x80;
3871 emitpcode(POC_MOVFW, popGet(AOP(left),size));
3872 emitpcode(POC_ADDLW, popGetLit( 0x80));
3873 emitpcode(POC_ADDLW, popGetLit(0x100-i));
3874 genSkipc(&rFalseIfx);
3877 if(ifx) ifx->generated = 1;
3885 if(lit & (0x80 << (size*8))) {
3886 /* lit is negative */
3887 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3889 //genSkipCond(&rFalseIfx,left,size,7);
3891 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3893 if(rFalseIfx.condition)
3894 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3896 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3900 /* lit is positive */
3901 DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
3902 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
3903 if(rFalseIfx.condition)
3904 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
3906 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
3910 /* There are no more special cases, so perform a general compare */
3912 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3913 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3917 emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
3919 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3921 //rFalseIfx.condition ^= 1;
3922 genSkipc(&rFalseIfx);
3924 emitpLabel(truelbl->key);
3926 if(ifx) ifx->generated = 1;
3933 /* sign is out of the way. So now do an unsigned compare */
3934 DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
3937 /* General case - compare to an unsigned literal on the right.*/
3939 i = (lit >> (size*8)) & 0xff;
3940 emitpcode(POC_MOVLW, popGetLit(i));
3941 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3943 i = (lit >> (size*8)) & 0xff;
3946 emitpcode(POC_MOVLW, popGetLit(i));
3948 emitpcode(POC_SUBFW, popGet(AOP(left),size));
3950 /* this byte of the lit is zero,
3951 *if it's not the last then OR in the variable */
3953 emitpcode(POC_IORFW, popGet(AOP(left),size));
3958 emitpLabel(lbl->key);
3959 //if(emitFinalCheck)
3960 genSkipc(&rFalseIfx);
3962 emitpLabel(truelbl->key);
3964 if(ifx) ifx->generated = 1;
3971 if(AOP_TYPE(left) == AOP_LIT) {
3972 //symbol *lbl = newiTempLabel(NULL);
3974 //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
3977 DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
3980 if((lit == 0) && (sign == 0)){
3983 emitpcode(POC_MOVFW, popGet(AOP(right),size));
3985 emitpcode(POC_IORFW, popGet(AOP(right),--size));
3987 genSkipz2(&rFalseIfx,0);
3988 if(ifx) ifx->generated = 1;
3995 if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
3996 /* degenerate compare can never be true */
3997 if(rFalseIfx.condition == 0)
3998 emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
4000 if(ifx) ifx->generated = 1;
4005 /* signed comparisons to a literal byte */
4007 int lp1 = (lit+1) & 0xff;
4009 DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
4012 rFalseIfx.condition ^= 1;
4013 genSkipCond(&rFalseIfx,right,0,7);
4016 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4017 emitpcode(POC_XORLW, popGetLit(0x7f));
4018 genSkipz2(&rFalseIfx,1);
4021 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4022 emitpcode(POC_ADDLW, popGetLit(0x80));
4023 emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
4024 rFalseIfx.condition ^= 1;
4025 genSkipc(&rFalseIfx);
4028 if(ifx) ifx->generated = 1;
4030 /* unsigned comparisons to a literal byte */
4032 switch(lit & 0xff ) {
4034 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4035 genSkipz2(&rFalseIfx,0);
4036 if(ifx) ifx->generated = 1;
4039 rFalseIfx.condition ^= 1;
4040 genSkipCond(&rFalseIfx,right,0,7);
4041 if(ifx) ifx->generated = 1;
4045 emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff));
4046 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4047 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4048 rFalseIfx.condition ^= 1;
4049 if (AOP_TYPE(result) == AOP_CRY) {
4050 genSkipc(&rFalseIfx);
4051 if(ifx) ifx->generated = 1;
4053 DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
4054 emitpcode(POC_CLRF, popGet(AOP(result),0));
4055 emitpcode(POC_RLF, popGet(AOP(result),0));
4056 emitpcode(POC_MOVLW, popGetLit(0x01));
4057 emitpcode(POC_XORWF, popGet(AOP(result),0));
4068 /* Size is greater than 1 */
4076 /* this means lit = 0xffffffff, or -1 */
4079 DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__);
4080 rFalseIfx.condition ^= 1;
4081 genSkipCond(&rFalseIfx,right,size,7);
4082 if(ifx) ifx->generated = 1;
4089 if(rFalseIfx.condition) {
4090 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4091 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4094 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4096 emitpcode(POC_IORFW, popGet(AOP(right),size));
4100 if(rFalseIfx.condition) {
4101 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4102 emitpLabel(truelbl->key);
4104 rFalseIfx.condition ^= 1;
4105 genSkipCond(&rFalseIfx,right,s,7);
4108 if(ifx) ifx->generated = 1;
4112 if((size == 1) && (0 == (lp1&0xff))) {
4113 /* lower byte of signed word is zero */
4114 DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
4115 i = ((lp1 >> 8) & 0xff) ^0x80;
4116 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4117 emitpcode(POC_ADDLW, popGetLit( 0x80));
4118 emitpcode(POC_ADDLW, popGetLit(0x100-i));
4119 rFalseIfx.condition ^= 1;
4120 genSkipc(&rFalseIfx);
4123 if(ifx) ifx->generated = 1;
4127 if(lit & (0x80 << (size*8))) {
4128 /* Lit is less than zero */
4129 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
4130 //rFalseIfx.condition ^= 1;
4131 //genSkipCond(&rFalseIfx,left,size,7);
4132 //rFalseIfx.condition ^= 1;
4133 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4134 //emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4136 if(rFalseIfx.condition)
4137 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4139 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4143 /* Lit is greater than or equal to zero */
4144 DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
4145 //rFalseIfx.condition ^= 1;
4146 //genSkipCond(&rFalseIfx,right,size,7);
4147 //rFalseIfx.condition ^= 1;
4149 //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4150 //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4152 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
4153 if(rFalseIfx.condition)
4154 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4156 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4161 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4162 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4166 emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
4168 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4170 rFalseIfx.condition ^= 1;
4171 //rFalseIfx.condition = 1;
4172 genSkipc(&rFalseIfx);
4174 emitpLabel(truelbl->key);
4176 if(ifx) ifx->generated = 1;
4181 /* compare word or long to an unsigned literal on the right.*/
4186 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
4189 break; /* handled above */
4192 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4194 emitpcode(POC_IORFW, popGet(AOP(right),size));
4195 genSkipz2(&rFalseIfx,0);
4199 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4201 emitpcode(POC_IORFW, popGet(AOP(right),size));
4204 if(rFalseIfx.condition)
4205 emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
4207 emitpcode(POC_GOTO, popGetLabel(truelbl->key));
4210 emitpcode(POC_MOVLW, popGetLit(lit+1));
4211 emitpcode(POC_SUBFW, popGet(AOP(right),0));
4213 rFalseIfx.condition ^= 1;
4214 genSkipc(&rFalseIfx);
4217 emitpLabel(truelbl->key);
4219 if(ifx) ifx->generated = 1;
4225 DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
4226 i = (lit >> (size*8)) & 0xff;
4228 emitpcode(POC_MOVLW, popGetLit(i));
4229 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4232 i = (lit >> (size*8)) & 0xff;
4235 emitpcode(POC_MOVLW, popGetLit(i));
4237 emitpcode(POC_SUBFW, popGet(AOP(right),size));
4239 /* this byte of the lit is zero,
4240 *if it's not the last then OR in the variable */
4242 emitpcode(POC_IORFW, popGet(AOP(right),size));
4247 emitpLabel(lbl->key);
4249 rFalseIfx.condition ^= 1;
4250 genSkipc(&rFalseIfx);
4254 emitpLabel(truelbl->key);
4255 if(ifx) ifx->generated = 1;
4259 /* Compare two variables */
4261 DEBUGpic14_emitcode(";sign","%d",sign);
4265 /* Sigh. thus sucks... */
4267 emitpcode(POC_MOVFW, popGet(AOP(left),size));
4268 emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr));
4269 emitpcode(POC_MOVLW, popGetLit(0x80));
4270 emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr));
4271 emitpcode(POC_XORFW, popGet(AOP(right),size));
4272 emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr));
4274 /* Signed char comparison */
4275 /* Special thanks to Nikolai Golovchenko for this snippet */
4276 emitpcode(POC_MOVFW, popGet(AOP(right),0));
4277 emitpcode(POC_SUBFW, popGet(AOP(left),0));
4278 emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */
4279 emitpcode(POC_XORFW, popGet(AOP(left),0));
4280 emitpcode(POC_XORFW, popGet(AOP(right),0));
4281 emitpcode(POC_ADDLW, popGetLit(0x80));
4283 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4284 genSkipc(&rFalseIfx);
4286 if(ifx) ifx->generated = 1;
4292 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4293 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4297 /* The rest of the bytes of a multi-byte compare */
4301 emitpcode(POC_GOTO, popGetLabel(lbl->key));
4304 emitpcode(POC_MOVFW, popGet(AOP(right),size));
4305 emitpcode(POC_SUBFW, popGet(AOP(left),size));
4310 emitpLabel(lbl->key);
4312 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4313 if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
4314 (AOP_TYPE(result) == AOP_REG)) {
4315 emitpcode(POC_CLRF, popGet(AOP(result),0));
4316 emitpcode(POC_RLF, popGet(AOP(result),0));
4318 genSkipc(&rFalseIfx);
4320 //genSkipc(&rFalseIfx);
4321 if(ifx) ifx->generated = 1;
4328 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4329 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4330 pic14_outBitC(result);
4332 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4333 /* if the result is used in the next
4334 ifx conditional branch then generate
4335 code a little differently */
4337 genIfxJump (ifx,"c");
4339 pic14_outBitC(result);
4340 /* leave the result in acc */
4345 /*-----------------------------------------------------------------*/
4346 /* genCmpGt :- greater than comparison */
4347 /*-----------------------------------------------------------------*/
4348 static void genCmpGt (iCode *ic, iCode *ifx)
4350 operand *left, *right, *result;
4351 sym_link *letype , *retype;
4354 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4356 right= IC_RIGHT(ic);
4357 result = IC_RESULT(ic);
4359 letype = getSpec(operandType(left));
4360 retype =getSpec(operandType(right));
4361 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4362 /* assign the amsops */
4363 aopOp (left,ic,FALSE);
4364 aopOp (right,ic,FALSE);
4365 aopOp (result,ic,TRUE);
4367 genCmp(right, left, result, ifx, sign);
4369 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4370 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4371 freeAsmop(result,NULL,ic,TRUE);
4374 /*-----------------------------------------------------------------*/
4375 /* genCmpLt - less than comparisons */
4376 /*-----------------------------------------------------------------*/
4377 static void genCmpLt (iCode *ic, iCode *ifx)
4379 operand *left, *right, *result;
4380 sym_link *letype , *retype;
4383 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4385 right= IC_RIGHT(ic);
4386 result = IC_RESULT(ic);
4388 letype = getSpec(operandType(left));
4389 retype =getSpec(operandType(right));
4390 sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
4392 /* assign the amsops */
4393 aopOp (left,ic,FALSE);
4394 aopOp (right,ic,FALSE);
4395 aopOp (result,ic,TRUE);
4397 genCmp(left, right, result, ifx, sign);
4399 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4400 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4401 freeAsmop(result,NULL,ic,TRUE);
4404 /*-----------------------------------------------------------------*/
4405 /* genc16bit2lit - compare a 16 bit value to a literal */
4406 /*-----------------------------------------------------------------*/
4407 static void genc16bit2lit(operand *op, int lit, int offset)
4411 DEBUGpic14_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
4412 if( (lit&0xff) == 0)
4417 switch( BYTEofLONG(lit,i)) {
4419 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4422 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4425 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4428 emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
4429 emitpcode(POC_XORLW,popGetLit(BYTEofLONG(lit,i)));
4434 switch( BYTEofLONG(lit,i)) {
4436 emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
4440 emitpcode(POC_DECFW,popGet(AOP(op),offset+i));
4444 emitpcode(POC_INCFW,popGet(AOP(op),offset+i));
4447 emitpcode(POC_MOVLW,popGetLit(BYTEofLONG(lit,i)));
4449 emitpcode(POC_XORFW,popGet(AOP(op),offset+i));
4455 /*-----------------------------------------------------------------*/
4456 /* gencjneshort - compare and jump if not equal */
4457 /*-----------------------------------------------------------------*/
4458 static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
4460 int size = max(AOP_SIZE(left),AOP_SIZE(right));
4462 int res_offset = 0; /* the result may be a different size then left or right */
4463 int res_size = AOP_SIZE(result);
4467 unsigned long lit = 0L;
4468 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4469 DEBUGpic14_AopType(__LINE__,left,right,result);
4471 DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
4472 resolveIfx(&rIfx,ifx);
4473 lbl = newiTempLabel(NULL);
4476 /* if the left side is a literal or
4477 if the right is in a pointer register and left
4479 if ((AOP_TYPE(left) == AOP_LIT) ||
4480 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4485 if(AOP_TYPE(right) == AOP_LIT)
4486 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4488 /* if the right side is a literal then anything goes */
4489 if (AOP_TYPE(right) == AOP_LIT &&
4490 AOP_TYPE(left) != AOP_DIR ) {
4493 genc16bit2lit(left, lit, 0);
4495 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4500 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4501 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4503 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4507 emitpcode(POC_GOTO,popGetLabel(lbl->key));
4509 if(res_offset < res_size-1)
4517 /* if the right side is in a register or in direct space or
4518 if the left is a pointer register & right is not */
4519 else if (AOP_TYPE(right) == AOP_REG ||
4520 AOP_TYPE(right) == AOP_DIR ||
4521 (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
4522 (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
4523 //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
4524 int lbl_key = lbl->key;
4527 emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
4528 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4530 DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
4531 fprintf(stderr, "%s %d error - expecting result to be non_null\n",
4532 __FUNCTION__,__LINE__);
4536 /* switch(size) { */
4538 /* genc16bit2lit(left, lit, 0); */
4540 /* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
4545 if((AOP_TYPE(left) == AOP_DIR) &&
4546 ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
4548 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4549 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4551 } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
4553 switch (lit & 0xff) {
4555 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4558 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4559 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4560 //emitpcode(POC_GOTO,popGetLabel(lbl->key));
4564 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4565 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4566 //emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4567 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4571 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4572 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4577 emitpcode(POC_MOVF,popGet(AOP(left),offset));
4580 if(AOP_TYPE(result) == AOP_CRY) {
4581 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4586 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4588 /* fix me. probably need to check result size too */
4589 //emitpcode(POC_CLRF,popGet(AOP(result),0));
4594 emitpcode(POC_GOTO,popGetLabel(lbl_key));
4595 //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4602 if(res_offset < res_size-1)
4607 } else if(AOP_TYPE(right) == AOP_REG &&
4608 AOP_TYPE(left) != AOP_DIR){
4611 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4612 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4613 pic14_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
4618 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4620 if(res_offset < res_size-1)
4625 /* right is a pointer reg need both a & b */
4627 char *l = aopGet(AOP(left),offset,FALSE,FALSE);
4629 pic14_emitcode("mov","b,%s",l);
4630 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
4631 pic14_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
4636 emitpcode(POC_INCF,popGet(AOP(result),res_offset));
4638 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
4640 emitpLabel(lbl->key);
4642 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4649 /*-----------------------------------------------------------------*/
4650 /* gencjne - compare and jump if not equal */
4651 /*-----------------------------------------------------------------*/
4652 static void gencjne(operand *left, operand *right, iCode *ifx)
4654 symbol *tlbl = newiTempLabel(NULL);
4656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4657 gencjneshort(left, right, lbl);
4659 pic14_emitcode("mov","a,%s",one);
4660 pic14_emitcode("sjmp","%05d_DS_",tlbl->key+100);
4661 pic14_emitcode("","%05d_DS_:",lbl->key+100);
4662 pic14_emitcode("clr","a");
4663 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
4665 emitpLabel(lbl->key);
4666 emitpLabel(tlbl->key);
4671 /*-----------------------------------------------------------------*/
4672 /* genCmpEq - generates code for equal to */
4673 /*-----------------------------------------------------------------*/
4674 static void genCmpEq (iCode *ic, iCode *ifx)
4676 operand *left, *right, *result;
4677 unsigned long lit = 0L;
4680 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4683 DEBUGpic14_emitcode ("; ifx is non-null","");
4685 DEBUGpic14_emitcode ("; ifx is null","");
4687 aopOp((left=IC_LEFT(ic)),ic,FALSE);
4688 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
4689 aopOp((result=IC_RESULT(ic)),ic,TRUE);
4691 size = max(AOP_SIZE(left),AOP_SIZE(right));
4693 DEBUGpic14_AopType(__LINE__,left,right,result);
4695 /* if literal, literal on the right or
4696 if the right is in a pointer register and left
4698 if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
4699 (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
4700 operand *tmp = right ;
4706 if(ifx && !AOP_SIZE(result)){
4708 /* if they are both bit variables */
4709 if (AOP_TYPE(left) == AOP_CRY &&
4710 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4711 if(AOP_TYPE(right) == AOP_LIT){
4712 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4714 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4715 pic14_emitcode("cpl","c");
4716 } else if(lit == 1L) {
4717 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4719 pic14_emitcode("clr","c");
4721 /* AOP_TYPE(right) == AOP_CRY */
4723 symbol *lbl = newiTempLabel(NULL);
4724 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4725 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4726 pic14_emitcode("cpl","c");
4727 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4729 /* if true label then we jump if condition
4731 tlbl = newiTempLabel(NULL);
4732 if ( IC_TRUE(ifx) ) {
4733 pic14_emitcode("jnc","%05d_DS_",tlbl->key+100);
4734 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100);
4736 pic14_emitcode("jc","%05d_DS_",tlbl->key+100);
4737 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100);
4739 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
4742 /* left and right are both bit variables, result is carry */
4745 resolveIfx(&rIfx,ifx);
4747 emitpcode(POC_MOVLW,popGet(AOP(left),0));
4748 emitpcode(POC_ANDFW,popGet(AOP(left),0));
4749 emitpcode(POC_BTFSC,popGet(AOP(right),0));
4750 emitpcode(POC_ANDLW,popGet(AOP(left),0));
4755 /* They're not both bit variables. Is the right a literal? */
4756 if(AOP_TYPE(right) == AOP_LIT) {
4757 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4762 switch(lit & 0xff) {
4764 if ( IC_TRUE(ifx) ) {
4765 emitpcode(POC_DECFW,popGet(AOP(left),offset));
4767 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4769 emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
4770 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4774 if ( IC_TRUE(ifx) ) {
4775 emitpcode(POC_INCFW,popGet(AOP(left),offset));
4777 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4779 emitpcode(POC_INCFSZW,popGet(AOP(left),offset));
4780 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4784 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4786 emitpcode(POC_XORLW,popGetLit(lit & 0xff));
4791 /* end of size == 1 */
4795 genc16bit2lit(left,lit,offset);
4798 /* end of size == 2 */
4803 emitpcode(POC_MOVFW,popGet(AOP(left),0));
4804 emitpcode(POC_IORFW,popGet(AOP(left),1));
4805 emitpcode(POC_IORFW,popGet(AOP(left),2));
4806 emitpcode(POC_IORFW,popGet(AOP(left),3));
4810 /* search for patterns that can be optimized */
4812 genc16bit2lit(left,lit,0);
4815 genSkipz(ifx,IC_TRUE(ifx) == NULL);
4817 genc16bit2lit(left,lit,2);
4819 emitpcode(POC_IORFW,popGet(AOP(left),2));
4820 emitpcode(POC_IORFW,popGet(AOP(left),3));
4833 } else if(AOP_TYPE(right) == AOP_CRY ) {
4834 /* we know the left is not a bit, but that the right is */
4835 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4836 emitpcode( ( (IC_TRUE(ifx)) ? POC_BTFSC : POC_BTFSS),
4837 popGet(AOP(right),offset));
4838 emitpcode(POC_XORLW,popGetLit(1));
4840 /* if the two are equal, then W will be 0 and the Z bit is set
4841 * we could test Z now, or go ahead and check the high order bytes if
4842 * the variable we're comparing is larger than a byte. */
4845 emitpcode(POC_IORFW,popGet(AOP(left),offset));
4847 if ( IC_TRUE(ifx) ) {
4849 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4850 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4853 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4854 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4858 /* They're both variables that are larger than bits */
4861 tlbl = newiTempLabel(NULL);
4864 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
4865 emitpcode(POC_XORFW,popGet(AOP(right),offset));
4867 if ( IC_TRUE(ifx) ) {
4870 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
4871 pic14_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset);
4874 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
4875 pic14_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset);
4879 emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key));
4880 pic14_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
4884 if(s>1 && IC_TRUE(ifx)) {
4885 emitpLabel(tlbl->key);
4886 pic14_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset);
4890 /* mark the icode as generated */
4895 /* if they are both bit variables */
4896 if (AOP_TYPE(left) == AOP_CRY &&
4897 ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) {
4898 if(AOP_TYPE(right) == AOP_LIT){
4899 unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
4901 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4902 pic14_emitcode("cpl","c");
4903 } else if(lit == 1L) {
4904 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4906 pic14_emitcode("clr","c");
4908 /* AOP_TYPE(right) == AOP_CRY */
4910 symbol *lbl = newiTempLabel(NULL);
4911 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
4912 pic14_emitcode("jb","%s,%05d_DS_",AOP(right)->aopu.aop_dir,(lbl->key+100));
4913 pic14_emitcode("cpl","c");
4914 pic14_emitcode("","%05d_DS_:",(lbl->key+100));
4917 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)){
4918 pic14_outBitC(result);
4922 genIfxJump (ifx,"c");
4925 /* if the result is used in an arithmetic operation
4926 then put the result in place */
4927 pic14_outBitC(result);
4930 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4931 gencjne(left,right,result,ifx);
4934 gencjne(left,right,newiTempLabel(NULL));
4936 if(IC_TRUE(ifx)->key)
4937 gencjne(left,right,IC_TRUE(ifx)->key);
4939 gencjne(left,right,IC_FALSE(ifx)->key);
4943 if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
4944 aopPut(AOP(result),"a",0);
4949 genIfxJump (ifx,"a");
4953 /* if the result is used in an arithmetic operation
4954 then put the result in place */
4956 if (AOP_TYPE(result) != AOP_CRY)
4957 pic14_outAcc(result);
4959 /* leave the result in acc */
4963 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4964 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
4965 freeAsmop(result,NULL,ic,TRUE);
4968 /*-----------------------------------------------------------------*/
4969 /* ifxForOp - returns the icode containing the ifx for operand */
4970 /*-----------------------------------------------------------------*/
4971 static iCode *ifxForOp ( operand *op, iCode *ic )
4973 /* if true symbol then needs to be assigned */
4974 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
4975 if (IS_TRUE_SYMOP(op))
4978 /* if this has register type condition and
4979 the next instruction is ifx with the same operand
4980 and live to of the operand is upto the ifx only then */
4982 ic->next->op == IFX &&
4983 IC_COND(ic->next)->key == op->key &&
4984 OP_SYMBOL(op)->liveTo <= ic->next->seq )
4988 ic->next->op == IFX &&
4989 IC_COND(ic->next)->key == op->key) {
4990 DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
4994 DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__);
4996 ic->next->op == IFX)
4997 DEBUGpic14_emitcode ("; ic-next"," is an IFX");
5000 ic->next->op == IFX &&
5001 IC_COND(ic->next)->key == op->key) {
5002 DEBUGpic14_emitcode ("; "," key is okay");
5003 DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d",
5004 OP_SYMBOL(op)->liveTo,
5011 /*-----------------------------------------------------------------*/
5012 /* genAndOp - for && operation */
5013 /*-----------------------------------------------------------------*/
5014 static void genAndOp (iCode *ic)
5016 operand *left,*right, *result;
5019 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5020 /* note here that && operations that are in an
5021 if statement are taken away by backPatchLabels
5022 only those used in arthmetic operations remain */
5023 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5024 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5025 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5027 DEBUGpic14_AopType(__LINE__,left,right,result);
5029 emitpcode(POC_MOVFW,popGet(AOP(left),0));
5030 emitpcode(POC_ANDFW,popGet(AOP(right),0));
5031 emitpcode(POC_MOVWF,popGet(AOP(result),0));
5033 /* if both are bit variables */
5034 /* if (AOP_TYPE(left) == AOP_CRY && */
5035 /* AOP_TYPE(right) == AOP_CRY ) { */
5036 /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */
5037 /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */
5038 /* pic14_outBitC(result); */
5040 /* tlbl = newiTempLabel(NULL); */
5041 /* pic14_toBoolean(left); */
5042 /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */
5043 /* pic14_toBoolean(right); */
5044 /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */
5045 /* pic14_outBitAcc(result); */
5048 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5049 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5050 freeAsmop(result,NULL,ic,TRUE);
5054 /*-----------------------------------------------------------------*/
5055 /* genOrOp - for || operation */
5056 /*-----------------------------------------------------------------*/
5059 modified this code, but it doesn't appear to ever get called
5062 static void genOrOp (iCode *ic)
5064 operand *left,*right, *result;
5067 /* note here that || operations that are in an
5068 if statement are taken away by backPatchLabels
5069 only those used in arthmetic operations remain */
5070 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5071 aopOp((left=IC_LEFT(ic)),ic,FALSE);
5072 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
5073 aopOp((result=IC_RESULT(ic)),ic,FALSE);
5075 DEBUGpic14_AopType(__LINE__,left,right,result);
5077 /* if both are bit variables */
5078 if (AOP_TYPE(left) == AOP_CRY &&
5079 AOP_TYPE(right) == AOP_CRY ) {
5080 pic14_emitcode("clrc","");
5081 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5082 AOP(left)->aopu.aop_dir,
5083 AOP(left)->aopu.aop_dir);
5084 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5085 AOP(right)->aopu.aop_dir,
5086 AOP(right)->aopu.aop_dir);
5087 pic14_emitcode("setc","");
5090 tlbl = newiTempLabel(NULL);
5091 pic14_toBoolean(left);
5093 pic14_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset);
5094 pic14_toBoolean(right);
5095 pic14_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset);
5097 pic14_outBitAcc(result);
5100 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5101 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5102 freeAsmop(result,NULL,ic,TRUE);
5105 /*-----------------------------------------------------------------*/
5106 /* isLiteralBit - test if lit == 2^n */
5107 /*-----------------------------------------------------------------*/
5108 static int isLiteralBit(unsigned long lit)
5110 unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L,
5111 0x100L,0x200L,0x400L,0x800L,
5112 0x1000L,0x2000L,0x4000L,0x8000L,
5113 0x10000L,0x20000L,0x40000L,0x80000L,
5114 0x100000L,0x200000L,0x400000L,0x800000L,
5115 0x1000000L,0x2000000L,0x4000000L,0x8000000L,
5116 0x10000000L,0x20000000L,0x40000000L,0x80000000L};
5119 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5120 for(idx = 0; idx < 32; idx++)
5126 /*-----------------------------------------------------------------*/
5127 /* continueIfTrue - */
5128 /*-----------------------------------------------------------------*/
5129 static void continueIfTrue (iCode *ic)
5131 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5133 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5137 /*-----------------------------------------------------------------*/
5139 /*-----------------------------------------------------------------*/
5140 static void jumpIfTrue (iCode *ic)
5142 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5144 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5148 /*-----------------------------------------------------------------*/
5149 /* jmpTrueOrFalse - */
5150 /*-----------------------------------------------------------------*/
5151 static void jmpTrueOrFalse (iCode *ic, symbol *tlbl)
5153 // ugly but optimized by peephole
5154 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5156 symbol *nlbl = newiTempLabel(NULL);
5157 pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100);
5158 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5159 pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
5160 pic14_emitcode("","%05d_DS_:",nlbl->key+100);
5163 pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
5164 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5169 /*-----------------------------------------------------------------*/
5170 /* genAnd - code for and */
5171 /*-----------------------------------------------------------------*/
5172 static void genAnd (iCode *ic, iCode *ifx)
5174 operand *left, *right, *result;
5176 unsigned long lit = 0L;
5181 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5182 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5183 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5184 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5186 resolveIfx(&rIfx,ifx);
5188 /* if left is a literal & right is not then exchange them */
5189 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5190 AOP_NEEDSACC(left)) {
5191 operand *tmp = right ;
5196 /* if result = right then exchange them */
5197 if(pic14_sameRegs(AOP(result),AOP(right))){
5198 operand *tmp = right ;
5203 /* if right is bit then exchange them */
5204 if (AOP_TYPE(right) == AOP_CRY &&
5205 AOP_TYPE(left) != AOP_CRY){
5206 operand *tmp = right ;
5210 if(AOP_TYPE(right) == AOP_LIT)
5211 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5213 size = AOP_SIZE(result);
5215 DEBUGpic14_AopType(__LINE__,left,right,result);
5218 // result = bit & yy;
5219 if (AOP_TYPE(left) == AOP_CRY){
5220 // c = bit & literal;
5221 if(AOP_TYPE(right) == AOP_LIT){
5223 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5226 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5229 if(size && (AOP_TYPE(result) == AOP_CRY)){
5230 pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir);
5233 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5237 pic14_emitcode("clr","c");
5240 if (AOP_TYPE(right) == AOP_CRY){
5242 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5243 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5246 MOVA(aopGet(AOP(right),0,FALSE,FALSE));
5248 pic14_emitcode("rrc","a");
5249 pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir);
5255 pic14_outBitC(result);
5257 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5258 genIfxJump(ifx, "c");
5262 // if(val & 0xZZ) - size = 0, ifx != FALSE -
5263 // bit = val & 0xZZ - size = 1, ifx = FALSE -
5264 if((AOP_TYPE(right) == AOP_LIT) &&
5265 (AOP_TYPE(result) == AOP_CRY) &&
5266 (AOP_TYPE(left) != AOP_CRY)){
5267 int posbit = isLiteralBit(lit);
5271 //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
5274 pic14_emitcode("mov","c,acc.%d",posbit&0x07);
5279 while (posbit > 7) {
5283 emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS),
5284 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0));
5285 emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
5292 symbol *tlbl = newiTempLabel(NULL);
5293 int sizel = AOP_SIZE(left);
5295 pic14_emitcode("setb","c");
5297 if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
5298 MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
5300 if((posbit = isLiteralBit(bytelit)) != 0)
5301 pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
5303 if(bytelit != 0x0FFL)
5304 pic14_emitcode("anl","a,%s",
5305 aopGet(AOP(right),offset,FALSE,TRUE));
5306 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5311 // bit = left & literal
5313 pic14_emitcode("clr","c");
5314 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5316 // if(left & literal)
5319 jmpTrueOrFalse(ifx, tlbl);
5323 pic14_outBitC(result);
5327 /* if left is same as result */
5328 if(pic14_sameRegs(AOP(result),AOP(left))){
5330 for(;size--; offset++,lit>>=8) {
5331 if(AOP_TYPE(right) == AOP_LIT){
5332 switch(lit & 0xff) {
5334 /* and'ing with 0 has clears the result */
5335 pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5336 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5339 /* and'ing with 0xff is a nop when the result and left are the same */
5344 int p = my_powof2( (~lit) & 0xff );
5346 /* only one bit is set in the literal, so use a bcf instruction */
5347 pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
5348 emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5351 pic14_emitcode("movlw","0x%x", (lit & 0xff));
5352 pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
5353 if(know_W != (int)(lit&0xff))
5354 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5356 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5361 if (AOP_TYPE(left) == AOP_ACC) {
5362 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5364 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5365 emitpcode(POC_ANDWF,popGet(AOP(left),offset));
5372 // left & result in different registers
5373 if(AOP_TYPE(result) == AOP_CRY){
5375 // if(size), result in bit
5376 // if(!size && ifx), conditional oper: if(left & right)
5377 symbol *tlbl = newiTempLabel(NULL);
5378 int sizer = min(AOP_SIZE(left),AOP_SIZE(right));
5380 pic14_emitcode("setb","c");
5382 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5383 pic14_emitcode("anl","a,%s",
5384 aopGet(AOP(left),offset,FALSE,FALSE));
5385 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5390 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5391 pic14_outBitC(result);
5393 jmpTrueOrFalse(ifx, tlbl);
5395 for(;(size--);offset++) {
5397 // result = left & right
5398 if(AOP_TYPE(right) == AOP_LIT){
5399 int t = (lit >> (offset*8)) & 0x0FFL;
5402 pic14_emitcode("clrf","%s",
5403 aopGet(AOP(result),offset,FALSE,FALSE));
5404 emitpcode(POC_CLRF,popGet(AOP(result),offset));
5407 if(AOP_TYPE(left) != AOP_ACC) {
5408 pic14_emitcode("movf","%s,w",
5409 aopGet(AOP(left),offset,FALSE,FALSE));
5410 pic14_emitcode("movwf","%s",
5411 aopGet(AOP(result),offset,FALSE,FALSE));
5412 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5414 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5417 if(AOP_TYPE(left) == AOP_ACC) {
5418 emitpcode(POC_ANDLW, popGetLit(t));
5420 pic14_emitcode("movlw","0x%x",t);
5421 pic14_emitcode("andwf","%s,w",
5422 aopGet(AOP(left),offset,FALSE,FALSE));
5423 pic14_emitcode("movwf","%s",
5424 aopGet(AOP(result),offset,FALSE,FALSE));
5426 emitpcode(POC_MOVLW, popGetLit(t));
5427 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5429 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5434 if (AOP_TYPE(left) == AOP_ACC) {
5435 pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5436 emitpcode(POC_ANDFW,popGet(AOP(right),offset));
5438 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5439 pic14_emitcode("andwf","%s,w",
5440 aopGet(AOP(left),offset,FALSE,FALSE));
5441 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5442 emitpcode(POC_ANDFW,popGet(AOP(left),offset));
5444 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5445 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5451 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5452 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5453 freeAsmop(result,NULL,ic,TRUE);
5456 /*-----------------------------------------------------------------*/
5457 /* genOr - code for or */
5458 /*-----------------------------------------------------------------*/
5459 static void genOr (iCode *ic, iCode *ifx)
5461 operand *left, *right, *result;
5463 unsigned long lit = 0L;
5465 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5467 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5468 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5469 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5471 DEBUGpic14_AopType(__LINE__,left,right,result);
5473 /* if left is a literal & right is not then exchange them */
5474 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5475 AOP_NEEDSACC(left)) {
5476 operand *tmp = right ;
5481 /* if result = right then exchange them */
5482 if(pic14_sameRegs(AOP(result),AOP(right))){
5483 operand *tmp = right ;
5488 /* if right is bit then exchange them */
5489 if (AOP_TYPE(right) == AOP_CRY &&
5490 AOP_TYPE(left) != AOP_CRY){
5491 operand *tmp = right ;
5496 DEBUGpic14_AopType(__LINE__,left,right,result);
5498 if(AOP_TYPE(right) == AOP_LIT)
5499 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5501 size = AOP_SIZE(result);
5505 if (AOP_TYPE(left) == AOP_CRY){
5506 if(AOP_TYPE(right) == AOP_LIT){
5507 // c = bit & literal;
5509 // lit != 0 => result = 1
5510 if(AOP_TYPE(result) == AOP_CRY){
5512 emitpcode(POC_BSF, popGet(AOP(result),0));
5513 //pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5514 // AOP(result)->aopu.aop_dir,
5515 // AOP(result)->aopu.aop_dir);
5517 continueIfTrue(ifx);
5521 // lit == 0 => result = left
5522 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5524 pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__);
5527 if (AOP_TYPE(right) == AOP_CRY){
5528 if(pic14_sameRegs(AOP(result),AOP(left))){
5530 emitpcode(POC_BCF, popGet(AOP(result),0));
5531 emitpcode(POC_BTFSC, popGet(AOP(right),0));
5532 emitpcode(POC_BSF, popGet(AOP(result),0));
5534 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5535 AOP(result)->aopu.aop_dir,
5536 AOP(result)->aopu.aop_dir);
5537 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5538 AOP(right)->aopu.aop_dir,
5539 AOP(right)->aopu.aop_dir);
5540 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5541 AOP(result)->aopu.aop_dir,
5542 AOP(result)->aopu.aop_dir);
5544 if( AOP_TYPE(result) == AOP_ACC) {
5545 emitpcode(POC_MOVLW, popGetLit(0));
5546 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5547 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5548 emitpcode(POC_MOVLW, popGetLit(1));
5552 emitpcode(POC_BCF, popGet(AOP(result),0));
5553 emitpcode(POC_BTFSS, popGet(AOP(right),0));
5554 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5555 emitpcode(POC_BSF, popGet(AOP(result),0));
5557 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
5558 AOP(result)->aopu.aop_dir,
5559 AOP(result)->aopu.aop_dir);
5560 pic14_emitcode("btfss","(%s >> 3), (%s & 7)",
5561 AOP(right)->aopu.aop_dir,
5562 AOP(right)->aopu.aop_dir);
5563 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
5564 AOP(left)->aopu.aop_dir,
5565 AOP(left)->aopu.aop_dir);
5566 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
5567 AOP(result)->aopu.aop_dir,
5568 AOP(result)->aopu.aop_dir);
5573 symbol *tlbl = newiTempLabel(NULL);
5574 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5577 emitpcode(POC_BCF, popGet(AOP(result),0));
5578 if( AOP_TYPE(right) == AOP_ACC) {
5579 emitpcode(POC_IORLW, popGetLit(0));
5581 emitpcode(POC_BTFSC, popGet(AOP(left),0));
5582 emitpcode(POC_BSF, popGet(AOP(result),0));
5587 if(!((AOP_TYPE(result) == AOP_CRY) && ifx))
5588 pic14_emitcode(";XXX setb","c");
5589 pic14_emitcode(";XXX jb","%s,%05d_DS_",
5590 AOP(left)->aopu.aop_dir,tlbl->key+100);
5591 pic14_toBoolean(right);
5592 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5593 if((AOP_TYPE(result) == AOP_CRY) && ifx){
5594 jmpTrueOrFalse(ifx, tlbl);
5598 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5605 pic14_outBitC(result);
5607 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5608 genIfxJump(ifx, "c");
5612 // if(val | 0xZZ) - size = 0, ifx != FALSE -
5613 // bit = val | 0xZZ - size = 1, ifx = FALSE -
5614 if((AOP_TYPE(right) == AOP_LIT) &&
5615 (AOP_TYPE(result) == AOP_CRY) &&
5616 (AOP_TYPE(left) != AOP_CRY)){
5618 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5621 pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir);
5623 continueIfTrue(ifx);
5626 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5627 // lit = 0, result = boolean(left)
5629 pic14_emitcode(";XXX setb","c");
5630 pic14_toBoolean(right);
5632 symbol *tlbl = newiTempLabel(NULL);
5633 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5635 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5637 genIfxJump (ifx,"a");
5641 pic14_outBitC(result);
5645 /* if left is same as result */
5646 if(pic14_sameRegs(AOP(result),AOP(left))){
5648 for(;size--; offset++,lit>>=8) {
5649 if(AOP_TYPE(right) == AOP_LIT){
5650 if((lit & 0xff) == 0)
5651 /* or'ing with 0 has no effect */
5654 int p = my_powof2(lit & 0xff);
5656 /* only one bit is set in the literal, so use a bsf instruction */
5658 newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
5660 if(know_W != (int)(lit & 0xff))
5661 emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
5662 know_W = lit & 0xff;
5663 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5668 if (AOP_TYPE(left) == AOP_ACC) {
5669 emitpcode(POC_IORFW, popGet(AOP(right),offset));
5670 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5672 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5673 emitpcode(POC_IORWF, popGet(AOP(left),offset));
5675 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5676 pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
5682 // left & result in different registers
5683 if(AOP_TYPE(result) == AOP_CRY){
5685 // if(size), result in bit
5686 // if(!size && ifx), conditional oper: if(left | right)
5687 symbol *tlbl = newiTempLabel(NULL);
5688 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5689 pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__);
5693 pic14_emitcode(";XXX setb","c");
5695 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5696 pic14_emitcode(";XXX orl","a,%s",
5697 aopGet(AOP(left),offset,FALSE,FALSE));
5698 pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100);
5703 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5704 pic14_outBitC(result);
5706 jmpTrueOrFalse(ifx, tlbl);
5707 } else for(;(size--);offset++){
5709 // result = left & right
5710 if(AOP_TYPE(right) == AOP_LIT){
5711 int t = (lit >> (offset*8)) & 0x0FFL;
5714 if (AOP_TYPE(left) != AOP_ACC) {
5715 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
5717 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5721 if (AOP_TYPE(left) == AOP_ACC) {
5722 emitpcode(POC_IORLW, popGetLit(t));
5724 emitpcode(POC_MOVLW, popGetLit(t));
5725 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5727 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5732 // faster than result <- left, anl result,right
5733 // and better if result is SFR
5734 if (AOP_TYPE(left) == AOP_ACC) {
5735 emitpcode(POC_IORWF, popGet(AOP(right),offset));
5736 pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5738 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
5739 emitpcode(POC_IORFW, popGet(AOP(left),offset));
5741 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5742 pic14_emitcode("iorwf","%s,w",
5743 aopGet(AOP(left),offset,FALSE,FALSE));
5745 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
5746 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5751 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5752 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5753 freeAsmop(result,NULL,ic,TRUE);
5756 /*-----------------------------------------------------------------*/
5757 /* genXor - code for xclusive or */
5758 /*-----------------------------------------------------------------*/
5759 static void genXor (iCode *ic, iCode *ifx)
5761 operand *left, *right, *result;
5763 unsigned long lit = 0L;
5765 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
5767 aopOp((left = IC_LEFT(ic)),ic,FALSE);
5768 aopOp((right= IC_RIGHT(ic)),ic,FALSE);
5769 aopOp((result=IC_RESULT(ic)),ic,TRUE);
5771 /* if left is a literal & right is not ||
5772 if left needs acc & right does not */
5773 if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) ||
5774 (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) {
5775 operand *tmp = right ;
5780 /* if result = right then exchange them */
5781 if(pic14_sameRegs(AOP(result),AOP(right))){
5782 operand *tmp = right ;
5787 /* if right is bit then exchange them */
5788 if (AOP_TYPE(right) == AOP_CRY &&
5789 AOP_TYPE(left) != AOP_CRY){
5790 operand *tmp = right ;
5794 if(AOP_TYPE(right) == AOP_LIT)
5795 lit = (unsigned long)floatFromVal (AOP(right)->aopu.aop_lit);
5797 size = AOP_SIZE(result);
5801 if (AOP_TYPE(left) == AOP_CRY){
5802 if(AOP_TYPE(right) == AOP_LIT){
5803 // c = bit & literal;
5805 // lit>>1 != 0 => result = 1
5806 if(AOP_TYPE(result) == AOP_CRY){
5808 {emitpcode(POC_BSF, popGet(AOP(result),offset));
5809 pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);}
5811 continueIfTrue(ifx);
5814 pic14_emitcode("setb","c");
5818 // lit == 0, result = left
5819 if(size && pic14_sameRegs(AOP(result),AOP(left)))
5821 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5823 // lit == 1, result = not(left)
5824 if(size && pic14_sameRegs(AOP(result),AOP(left))){
5825 emitpcode(POC_MOVLW, popGet(AOP(result),offset));
5826 emitpcode(POC_XORWF, popGet(AOP(result),offset));
5827 pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
5830 pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
5831 pic14_emitcode("cpl","c");
5838 symbol *tlbl = newiTempLabel(NULL);
5839 if (AOP_TYPE(right) == AOP_CRY){
5841 pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
5844 int sizer = AOP_SIZE(right);
5846 // if val>>1 != 0, result = 1
5847 pic14_emitcode("setb","c");
5849 MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE));
5851 // test the msb of the lsb
5852 pic14_emitcode("anl","a,#0xfe");
5853 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5857 pic14_emitcode("rrc","a");
5859 pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100));
5860 pic14_emitcode("cpl","c");
5861 pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
5866 pic14_outBitC(result);
5868 else if((AOP_TYPE(result) == AOP_CRY) && ifx)
5869 genIfxJump(ifx, "c");
5873 if(pic14_sameRegs(AOP(result),AOP(left))){
5874 /* if left is same as result */
5875 for(;size--; offset++) {
5876 if(AOP_TYPE(right) == AOP_LIT){
5877 int t = (lit >> (offset*8)) & 0x0FFL;
5881 if (IS_AOP_PREG(left)) {
5882 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5883 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5884 aopPut(AOP(result),"a",offset);
5886 emitpcode(POC_MOVLW, popGetLit(t));
5887 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5888 pic14_emitcode("xrl","%s,%s",
5889 aopGet(AOP(left),offset,FALSE,TRUE),
5890 aopGet(AOP(right),offset,FALSE,FALSE));
5893 if (AOP_TYPE(left) == AOP_ACC)
5894 pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
5896 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5897 emitpcode(POC_XORWF,popGet(AOP(left),offset));
5899 if (IS_AOP_PREG(left)) {
5900 pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
5901 aopPut(AOP(result),"a",offset);
5903 pic14_emitcode("xrl","%s,a",
5904 aopGet(AOP(left),offset,FALSE,TRUE));
5910 // left & result in different registers
5911 if(AOP_TYPE(result) == AOP_CRY){
5913 // if(size), result in bit
5914 // if(!size && ifx), conditional oper: if(left ^ right)
5915 symbol *tlbl = newiTempLabel(NULL);
5916 int sizer = max(AOP_SIZE(left),AOP_SIZE(right));
5918 pic14_emitcode("setb","c");
5920 if((AOP_TYPE(right) == AOP_LIT) &&
5921 (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){
5922 MOVA(aopGet(AOP(left),offset,FALSE,FALSE));
5924 MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
5925 pic14_emitcode("xrl","a,%s",
5926 aopGet(AOP(left),offset,FALSE,FALSE));
5928 pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
5933 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
5934 pic14_outBitC(result);
5936 jmpTrueOrFalse(ifx, tlbl);
5937 } else for(;(size--);offset++){
5939 // result = left & right
5940 if(AOP_TYPE(right) == AOP_LIT){
5941 int t = (lit >> (offset*8)) & 0x0FFL;
5944 if (AOP_TYPE(left) != AOP_ACC) {
5945 emitpcode(POC_MOVFW,popGet(AOP(left),offset));
5947 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5948 pic14_emitcode("movf","%s,w",
5949 aopGet(AOP(left),offset,FALSE,FALSE));
5950 pic14_emitcode("movwf","%s",
5951 aopGet(AOP(result),offset,FALSE,FALSE));
5954 if (AOP_TYPE(left) == AOP_ACC) {
5955 emitpcode(POC_XORLW, popGetLit(t));
5957 emitpcode(POC_COMFW,popGet(AOP(left),offset));
5959 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5962 if (AOP_TYPE(left) == AOP_ACC) {
5963 emitpcode(POC_XORLW, popGetLit(t));
5965 emitpcode(POC_MOVLW, popGetLit(t));
5966 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5968 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5969 pic14_emitcode("movlw","0x%x",t);
5970 pic14_emitcode("xorwf","%s,w",
5971 aopGet(AOP(left),offset,FALSE,FALSE));
5972 pic14_emitcode("movwf","%s",
5973 aopGet(AOP(result),offset,FALSE,FALSE));
5979 // faster than result <- left, anl result,right
5980 // and better if result is SFR
5981 if (AOP_TYPE(left) == AOP_ACC) {
5982 emitpcode(POC_XORFW,popGet(AOP(right),offset));
5983 pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5985 emitpcode(POC_MOVFW,popGet(AOP(right),offset));
5986 emitpcode(POC_XORFW,popGet(AOP(left),offset));
5987 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
5988 pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
5990 if ( AOP_TYPE(result) != AOP_ACC){
5991 emitpcode(POC_MOVWF,popGet(AOP(result),offset));
5992 pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
5998 freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
5999 freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
6000 freeAsmop(result,NULL,ic,TRUE);
6003 /*-----------------------------------------------------------------*/
6004 /* genInline - write the inline code out */
6005 /*-----------------------------------------------------------------*/
6006 static void genInline (iCode *ic)
6008 char *buffer, *bp, *bp1;
6010 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6012 _G.inLine += (!options.asmpeep);
6014 buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
6015 strcpy(buffer,IC_INLINE(ic));
6017 /* emit each line as a code */
6023 addpCode2pBlock(pb,AssembleLine(bp1));
6030 pic14_emitcode(bp1,"");
6036 if ((bp1 != bp) && *bp1)
6037 addpCode2pBlock(pb,AssembleLine(bp1));
6041 _G.inLine -= (!options.asmpeep);
6044 /*-----------------------------------------------------------------*/
6045 /* genRRC - rotate right with carry */
6046 /*-----------------------------------------------------------------*/
6047 static void genRRC (iCode *ic)
6049 operand *left , *result ;
6050 int size, offset = 0, same;
6052 /* rotate right with carry */
6054 result=IC_RESULT(ic);
6055 aopOp (left,ic,FALSE);
6056 aopOp (result,ic,FALSE);
6058 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6060 same = pic14_sameRegs(AOP(result),AOP(left));
6062 size = AOP_SIZE(result);
6064 /* get the lsb and put it into the carry */
6065 emitpcode(POC_RRFW, popGet(AOP(left),size-1));
6072 emitpcode(POC_RRF, popGet(AOP(left),offset));
6074 emitpcode(POC_RRFW, popGet(AOP(left),offset));
6075 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6081 freeAsmop(left,NULL,ic,TRUE);
6082 freeAsmop(result,NULL,ic,TRUE);
6085 /*-----------------------------------------------------------------*/
6086 /* genRLC - generate code for rotate left with carry */
6087 /*-----------------------------------------------------------------*/
6088 static void genRLC (iCode *ic)
6090 operand *left , *result ;
6091 int size, offset = 0;
6094 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6095 /* rotate right with carry */
6097 result=IC_RESULT(ic);
6098 aopOp (left,ic,FALSE);
6099 aopOp (result,ic,FALSE);
6101 DEBUGpic14_AopType(__LINE__,left,NULL,result);
6103 same = pic14_sameRegs(AOP(result),AOP(left));
6105 /* move it to the result */
6106 size = AOP_SIZE(result);
6108 /* get the msb and put it into the carry */
6109 emitpcode(POC_RLFW, popGet(AOP(left),size-1));
6116 emitpcode(POC_RLF, popGet(AOP(left),offset));
6118 emitpcode(POC_RLFW, popGet(AOP(left),offset));
6119 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
6126 freeAsmop(left,NULL,ic,TRUE);
6127 freeAsmop(result,NULL,ic,TRUE);
6130 /*-----------------------------------------------------------------*/
6131 /* genGetHbit - generates code get highest order bit */
6132 /*-----------------------------------------------------------------*/
6133 static void genGetHbit (iCode *ic)
6135 operand *left, *result;
6137 result=IC_RESULT(ic);
6138 aopOp (left,ic,FALSE);
6139 aopOp (result,ic,FALSE);
6141 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6142 /* get the highest order byte into a */
6143 MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE));
6144 if(AOP_TYPE(result) == AOP_CRY){
6145 pic14_emitcode("rlc","a");
6146 pic14_outBitC(result);
6149 pic14_emitcode("rl","a");
6150 pic14_emitcode("anl","a,#0x01");
6151 pic14_outAcc(result);
6155 freeAsmop(left,NULL,ic,TRUE);
6156 freeAsmop(result,NULL,ic,TRUE);
6159 /*-----------------------------------------------------------------*/
6160 /* AccRol - rotate left accumulator by known count */
6161 /*-----------------------------------------------------------------*/
6162 static void AccRol (int shCount)
6164 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6165 shCount &= 0x0007; // shCount : 0..7
6170 pic14_emitcode("rl","a");
6173 pic14_emitcode("rl","a");
6174 pic14_emitcode("rl","a");
6177 pic14_emitcode("swap","a");
6178 pic14_emitcode("rr","a");
6181 pic14_emitcode("swap","a");
6184 pic14_emitcode("swap","a");
6185 pic14_emitcode("rl","a");
6188 pic14_emitcode("rr","a");
6189 pic14_emitcode("rr","a");
6192 pic14_emitcode("rr","a");
6197 /*-----------------------------------------------------------------*/
6198 /* AccLsh - left shift accumulator by known count */
6199 /*-----------------------------------------------------------------*/
6200 static void AccLsh (int shCount)
6202 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6205 pic14_emitcode("add","a,acc");
6208 pic14_emitcode("add","a,acc");
6209 pic14_emitcode("add","a,acc");
6211 /* rotate left accumulator */
6213 /* and kill the lower order bits */
6214 pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
6219 /*-----------------------------------------------------------------*/
6220 /* AccRsh - right shift accumulator by known count */
6221 /*-----------------------------------------------------------------*/
6222 static void AccRsh (int shCount)
6224 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6228 pic14_emitcode("rrc","a");
6230 /* rotate right accumulator */
6231 AccRol(8 - shCount);
6232 /* and kill the higher order bits */
6233 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6239 /*-----------------------------------------------------------------*/
6240 /* AccSRsh - signed right shift accumulator by known count */
6241 /*-----------------------------------------------------------------*/
6242 static void AccSRsh (int shCount)
6245 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6248 pic14_emitcode("mov","c,acc.7");
6249 pic14_emitcode("rrc","a");
6250 } else if(shCount == 2){
6251 pic14_emitcode("mov","c,acc.7");
6252 pic14_emitcode("rrc","a");
6253 pic14_emitcode("mov","c,acc.7");
6254 pic14_emitcode("rrc","a");
6256 tlbl = newiTempLabel(NULL);
6257 /* rotate right accumulator */
6258 AccRol(8 - shCount);
6259 /* and kill the higher order bits */
6260 pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
6261 pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100);
6262 pic14_emitcode("orl","a,#0x%02x",
6263 (unsigned char)~SRMask[shCount]);
6264 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
6269 /*-----------------------------------------------------------------*/
6270 /* shiftR1Left2Result - shift right one byte from left to result */
6271 /*-----------------------------------------------------------------*/
6272 static void shiftR1Left2ResultSigned (operand *left, int offl,
6273 operand *result, int offr,
6278 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6280 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6284 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6286 emitpcode(POC_RRF, popGet(AOP(result),offr));
6288 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6289 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6295 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6297 emitpcode(POC_RRF, popGet(AOP(result),offr));
6299 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6300 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6302 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6303 emitpcode(POC_RRF, popGet(AOP(result),offr));
6309 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6311 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6312 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6315 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6316 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6317 emitpcode(POC_ANDLW, popGetLit(0x1f));
6319 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6320 emitpcode(POC_IORLW, popGetLit(0xe0));
6322 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6326 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6327 emitpcode(POC_ANDLW, popGetLit(0x0f));
6328 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6329 emitpcode(POC_IORLW, popGetLit(0xf0));
6330 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6334 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6336 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6337 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6339 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6340 emitpcode(POC_ANDLW, popGetLit(0x07));
6341 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0));
6342 emitpcode(POC_IORLW, popGetLit(0xf8));
6343 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6348 emitpcode(POC_MOVLW, popGetLit(0x00));
6349 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6350 emitpcode(POC_MOVLW, popGetLit(0xfe));
6351 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6352 emitpcode(POC_IORLW, popGetLit(0x01));
6353 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6355 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6356 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6357 emitpcode(POC_DECF, popGet(AOP(result),offr));
6358 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0));
6359 emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0));
6365 emitpcode(POC_MOVLW, popGetLit(0x00));
6366 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
6367 emitpcode(POC_MOVLW, popGetLit(0xff));
6368 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6370 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6371 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0));
6372 emitpcode(POC_DECF, popGet(AOP(result),offr));
6380 /*-----------------------------------------------------------------*/
6381 /* shiftR1Left2Result - shift right one byte from left to result */
6382 /*-----------------------------------------------------------------*/
6383 static void shiftR1Left2Result (operand *left, int offl,
6384 operand *result, int offr,
6385 int shCount, int sign)
6389 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6391 same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
6393 /* Copy the msb into the carry if signed. */
6395 shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
6405 emitpcode(POC_RRF, popGet(AOP(result),offr));
6407 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6408 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6414 emitpcode(POC_RRF, popGet(AOP(result),offr));
6416 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6417 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6420 emitpcode(POC_RRF, popGet(AOP(result),offr));
6425 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6427 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6428 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6431 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6432 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6433 emitpcode(POC_ANDLW, popGetLit(0x1f));
6434 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6438 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6439 emitpcode(POC_ANDLW, popGetLit(0x0f));
6440 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6444 emitpcode(POC_SWAPFW, popGet(AOP(left),offl));
6445 emitpcode(POC_ANDLW, popGetLit(0x0f));
6446 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6448 emitpcode(POC_RRF, popGet(AOP(result),offr));
6453 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6454 emitpcode(POC_ANDLW, popGetLit(0x80));
6455 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6456 emitpcode(POC_RLF, popGet(AOP(result),offr));
6457 emitpcode(POC_RLF, popGet(AOP(result),offr));
6462 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6463 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6464 emitpcode(POC_RLF, popGet(AOP(result),offr));
6473 /*-----------------------------------------------------------------*/
6474 /* shiftL1Left2Result - shift left one byte from left to result */
6475 /*-----------------------------------------------------------------*/
6476 static void shiftL1Left2Result (operand *left, int offl,
6477 operand *result, int offr, int shCount)
6482 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6484 same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
6485 DEBUGpic14_emitcode ("; ***","same = %d",same);
6486 // l = aopGet(AOP(left),offl,FALSE,FALSE);
6488 /* shift left accumulator */
6489 //AccLsh(shCount); // don't comment out just yet...
6490 // aopPut(AOP(result),"a",offr);
6494 /* Shift left 1 bit position */
6495 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6497 emitpcode(POC_ADDWF, popGet(AOP(left),offl));
6499 emitpcode(POC_ADDFW, popGet(AOP(left),offl));
6500 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6504 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6505 emitpcode(POC_ANDLW,popGetLit(0x7e));
6506 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6507 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6510 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6511 emitpcode(POC_ANDLW,popGetLit(0x3e));
6512 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6513 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6514 emitpcode(POC_RLF, popGet(AOP(result),offr));
6517 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6518 emitpcode(POC_ANDLW, popGetLit(0xf0));
6519 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6522 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6523 emitpcode(POC_ANDLW, popGetLit(0xf0));
6524 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6525 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6528 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6529 emitpcode(POC_ANDLW, popGetLit(0x30));
6530 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6531 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6532 emitpcode(POC_RLF, popGet(AOP(result),offr));
6535 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6536 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6537 emitpcode(POC_RRF, popGet(AOP(result),offr));
6541 DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
6546 /*-----------------------------------------------------------------*/
6547 /* movLeft2Result - move byte from left to result */
6548 /*-----------------------------------------------------------------*/
6549 static void movLeft2Result (operand *left, int offl,
6550 operand *result, int offr)
6553 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6554 if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){
6555 l = aopGet(AOP(left),offl,FALSE,FALSE);
6557 if (*l == '@' && (IS_AOP_PREG(result))) {
6558 pic14_emitcode("mov","a,%s",l);
6559 aopPut(AOP(result),"a",offr);
6561 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6562 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6567 /*-----------------------------------------------------------------*/
6568 /* shiftL2Left2Result - shift left two bytes from left to result */
6569 /*-----------------------------------------------------------------*/
6570 static void shiftL2Left2Result (operand *left, int offl,
6571 operand *result, int offr, int shCount)
6575 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6577 if(pic14_sameRegs(AOP(result), AOP(left))) {
6585 emitpcode(POC_MOVFW,popGet(AOP(result),offr));
6586 emitpcode(POC_ADDWF,popGet(AOP(result),offr));
6587 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6591 emitpcode(POC_RLF, popGet(AOP(result),offr));
6592 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6598 emitpcode(POC_MOVLW, popGetLit(0x0f));
6599 emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16));
6600 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6601 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6602 emitpcode(POC_ANDFW, popGet(AOP(result),offr));
6603 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6604 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6606 emitpcode(POC_RLF, popGet(AOP(result),offr));
6607 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6611 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6612 emitpcode(POC_RRF, popGet(AOP(result),offr));
6613 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6614 emitpcode(POC_RRF, popGet(AOP(result),offr));
6615 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6616 emitpcode(POC_ANDLW,popGetLit(0xc0));
6617 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6618 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6619 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6620 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6623 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6624 emitpcode(POC_RRFW, popGet(AOP(result),offr));
6625 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6626 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6627 emitpcode(POC_RRF, popGet(AOP(result),offr));
6637 /* note, use a mov/add for the shift since the mov has a
6638 chance of getting optimized out */
6639 emitpcode(POC_MOVFW, popGet(AOP(left),offl));
6640 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6641 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6642 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6643 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6647 emitpcode(POC_RLF, popGet(AOP(result),offr));
6648 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6654 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6655 emitpcode(POC_ANDLW, popGetLit(0xF0));
6656 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6657 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6658 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6659 emitpcode(POC_ANDLW, popGetLit(0xF0));
6660 emitpcode(POC_XORWF, popGet(AOP(result),offr));
6661 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6665 emitpcode(POC_RLF, popGet(AOP(result),offr));
6666 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6670 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6671 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6672 emitpcode(POC_RRFW, popGet(AOP(result),offl));
6673 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6675 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6676 emitpcode(POC_RRF, popGet(AOP(result),offr));
6677 emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16));
6678 emitpcode(POC_ANDLW,popGetLit(0xc0));
6679 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6680 emitpcode(POC_XORWF,popGet(AOP(result),offr));
6681 emitpcode(POC_XORFW,popGet(AOP(result),offr));
6682 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6685 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6686 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6687 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6688 emitpcode(POC_CLRF, popGet(AOP(result),offr));
6689 emitpcode(POC_RRF, popGet(AOP(result),offr));
6694 /*-----------------------------------------------------------------*/
6695 /* shiftR2Left2Result - shift right two bytes from left to result */
6696 /*-----------------------------------------------------------------*/
6697 static void shiftR2Left2Result (operand *left, int offl,
6698 operand *result, int offr,
6699 int shCount, int sign)
6703 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6704 same = pic14_sameRegs(AOP(result), AOP(left));
6706 if(same && ((offl + MSB16) == offr)){
6708 /* don't crash result[offr] */
6709 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6710 pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6713 movLeft2Result(left,offl, result, offr);
6714 MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
6717 /* a:x >> shCount (x = lsb(result))*/
6720 AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6722 AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
6731 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6736 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6737 emitpcode(POC_RRF,popGet(AOP(result),offr));
6739 emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16));
6740 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6741 emitpcode(POC_RRFW, popGet(AOP(left),offl));
6742 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6747 emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16));
6750 emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16));
6751 emitpcode(POC_RRF,popGet(AOP(result),offr));
6758 emitpcode(POC_MOVLW, popGetLit(0xf0));
6759 emitpcode(POC_ANDWF, popGet(AOP(result),offr));
6760 emitpcode(POC_SWAPF, popGet(AOP(result),offr));
6762 emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16));
6763 emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16));
6764 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6765 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6767 emitpcode(POC_SWAPFW,popGet(AOP(left),offl));
6768 emitpcode(POC_ANDLW, popGetLit(0x0f));
6769 emitpcode(POC_MOVWF, popGet(AOP(result),offr));
6771 emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16));
6772 emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16));
6773 emitpcode(POC_ANDLW, popGetLit(0xf0));
6774 emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16));
6775 emitpcode(POC_ADDWF, popGet(AOP(result),offr));
6779 emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16));
6780 emitpcode(POC_RRF, popGet(AOP(result),offr));
6784 emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 ));
6785 emitpcode(POC_BTFSC,
6786 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0));
6787 emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16));
6795 emitpcode(POC_RLF, popGet(AOP(result),offr));
6796 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6798 emitpcode(POC_RLF, popGet(AOP(result),offr));
6799 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6800 emitpcode(POC_RLFW, popGet(AOP(result),offr));
6801 emitpcode(POC_ANDLW,popGetLit(0x03));
6803 emitpcode(POC_BTFSC,
6804 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0));
6805 emitpcode(POC_IORLW,popGetLit(0xfc));
6807 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6808 emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16));
6809 emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16));
6810 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6812 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6813 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6814 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6815 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6816 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6817 emitpcode(POC_RLF, popGet(AOP(result),offr));
6818 emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16));
6819 emitpcode(POC_ANDLW,popGetLit(0x03));
6821 emitpcode(POC_BTFSC,
6822 newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0));
6823 emitpcode(POC_IORLW,popGetLit(0xfc));
6825 emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16));
6826 //emitpcode(POC_RLF, popGet(AOP(result),offr));
6833 emitpcode(POC_RLFW, popGet(AOP(left),offl));
6834 emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16));
6835 emitpcode(POC_MOVWF,popGet(AOP(result),offr));
6836 emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16));
6839 emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16));
6841 emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16));
6846 /*-----------------------------------------------------------------*/
6847 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
6848 /*-----------------------------------------------------------------*/
6849 static void shiftLLeftOrResult (operand *left, int offl,
6850 operand *result, int offr, int shCount)
6852 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6853 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6854 /* shift left accumulator */
6856 /* or with result */
6857 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6858 /* back to result */
6859 aopPut(AOP(result),"a",offr);
6862 /*-----------------------------------------------------------------*/
6863 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
6864 /*-----------------------------------------------------------------*/
6865 static void shiftRLeftOrResult (operand *left, int offl,
6866 operand *result, int offr, int shCount)
6868 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6869 MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
6870 /* shift right accumulator */
6872 /* or with result */
6873 pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
6874 /* back to result */
6875 aopPut(AOP(result),"a",offr);
6878 /*-----------------------------------------------------------------*/
6879 /* genlshOne - left shift a one byte quantity by known count */
6880 /*-----------------------------------------------------------------*/
6881 static void genlshOne (operand *result, operand *left, int shCount)
6883 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6884 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6887 /*-----------------------------------------------------------------*/
6888 /* genlshTwo - left shift two bytes by known amount != 0 */
6889 /*-----------------------------------------------------------------*/
6890 static void genlshTwo (operand *result,operand *left, int shCount)
6894 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6895 size = pic14_getDataSize(result);
6897 /* if shCount >= 8 */
6903 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
6905 movLeft2Result(left, LSB, result, MSB16);
6907 emitpcode(POC_CLRF,popGet(AOP(result),LSB));
6910 /* 1 <= shCount <= 7 */
6913 shiftL1Left2Result(left, LSB, result, LSB, shCount);
6915 shiftL2Left2Result(left, LSB, result, LSB, shCount);
6919 /*-----------------------------------------------------------------*/
6920 /* shiftLLong - shift left one long from left to result */
6921 /* offl = LSB or MSB16 */
6922 /*-----------------------------------------------------------------*/
6923 static void shiftLLong (operand *left, operand *result, int offr )
6926 int size = AOP_SIZE(result);
6928 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6929 if(size >= LSB+offr){
6930 l = aopGet(AOP(left),LSB,FALSE,FALSE);
6932 pic14_emitcode("add","a,acc");
6933 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6934 size >= MSB16+offr && offr != LSB )
6935 pic14_emitcode("xch","a,%s",
6936 aopGet(AOP(left),LSB+offr,FALSE,FALSE));
6938 aopPut(AOP(result),"a",LSB+offr);
6941 if(size >= MSB16+offr){
6942 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) {
6943 l = aopGet(AOP(left),MSB16,FALSE,FALSE);
6946 pic14_emitcode("rlc","a");
6947 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6948 size >= MSB24+offr && offr != LSB)
6949 pic14_emitcode("xch","a,%s",
6950 aopGet(AOP(left),MSB16+offr,FALSE,FALSE));
6952 aopPut(AOP(result),"a",MSB16+offr);
6955 if(size >= MSB24+offr){
6956 if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) {
6957 l = aopGet(AOP(left),MSB24,FALSE,FALSE);
6960 pic14_emitcode("rlc","a");
6961 if (pic14_sameRegs(AOP(left),AOP(result)) &&
6962 size >= MSB32+offr && offr != LSB )
6963 pic14_emitcode("xch","a,%s",
6964 aopGet(AOP(left),MSB24+offr,FALSE,FALSE));
6966 aopPut(AOP(result),"a",MSB24+offr);
6969 if(size > MSB32+offr){
6970 if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) {
6971 l = aopGet(AOP(left),MSB32,FALSE,FALSE);
6974 pic14_emitcode("rlc","a");
6975 aopPut(AOP(result),"a",MSB32+offr);
6978 aopPut(AOP(result),zero,LSB);
6981 /*-----------------------------------------------------------------*/
6982 /* genlshFour - shift four byte by a known amount != 0 */
6983 /*-----------------------------------------------------------------*/
6984 static void genlshFour (operand *result, operand *left, int shCount)
6988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
6989 size = AOP_SIZE(result);
6991 /* if shifting more that 3 bytes */
6992 if (shCount >= 24 ) {
6995 /* lowest order of left goes to the highest
6996 order of the destination */
6997 shiftL1Left2Result(left, LSB, result, MSB32, shCount);
6999 movLeft2Result(left, LSB, result, MSB32);
7000 aopPut(AOP(result),zero,LSB);
7001 aopPut(AOP(result),zero,MSB16);
7002 aopPut(AOP(result),zero,MSB32);
7006 /* more than two bytes */
7007 else if ( shCount >= 16 ) {
7008 /* lower order two bytes goes to higher order two bytes */
7010 /* if some more remaining */
7012 shiftL2Left2Result(left, LSB, result, MSB24, shCount);
7014 movLeft2Result(left, MSB16, result, MSB32);
7015 movLeft2Result(left, LSB, result, MSB24);
7017 aopPut(AOP(result),zero,MSB16);
7018 aopPut(AOP(result),zero,LSB);
7022 /* if more than 1 byte */
7023 else if ( shCount >= 8 ) {
7024 /* lower order three bytes goes to higher order three bytes */
7028 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7030 movLeft2Result(left, LSB, result, MSB16);
7032 else{ /* size = 4 */
7034 movLeft2Result(left, MSB24, result, MSB32);
7035 movLeft2Result(left, MSB16, result, MSB24);
7036 movLeft2Result(left, LSB, result, MSB16);
7037 aopPut(AOP(result),zero,LSB);
7039 else if(shCount == 1)
7040 shiftLLong(left, result, MSB16);
7042 shiftL2Left2Result(left, MSB16, result, MSB24, shCount);
7043 shiftL1Left2Result(left, LSB, result, MSB16, shCount);
7044 shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount);
7045 aopPut(AOP(result),zero,LSB);
7050 /* 1 <= shCount <= 7 */
7051 else if(shCount <= 2){
7052 shiftLLong(left, result, LSB);
7054 shiftLLong(result, result, LSB);
7056 /* 3 <= shCount <= 7, optimize */
7058 shiftL2Left2Result(left, MSB24, result, MSB24, shCount);
7059 shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount);
7060 shiftL2Left2Result(left, LSB, result, LSB, shCount);
7064 /*-----------------------------------------------------------------*/
7065 /* genLeftShiftLiteral - left shifting by known count */
7066 /*-----------------------------------------------------------------*/
7067 static void genLeftShiftLiteral (operand *left,
7072 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7075 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7076 freeAsmop(right,NULL,ic,TRUE);
7078 aopOp(left,ic,FALSE);
7079 aopOp(result,ic,FALSE);
7081 size = getSize(operandType(result));
7084 pic14_emitcode("; shift left ","result %d, left %d",size,
7088 /* I suppose that the left size >= result size */
7091 movLeft2Result(left, size, result, size);
7095 else if(shCount >= (size * 8))
7097 aopPut(AOP(result),zero,size);
7101 genlshOne (result,left,shCount);
7106 genlshTwo (result,left,shCount);
7110 genlshFour (result,left,shCount);
7114 freeAsmop(left,NULL,ic,TRUE);
7115 freeAsmop(result,NULL,ic,TRUE);
7118 /*-----------------------------------------------------------------*
7119 * genMultiAsm - repeat assembly instruction for size of register.
7120 * if endian == 1, then the high byte (i.e base address + size of
7121 * register) is used first else the low byte is used first;
7122 *-----------------------------------------------------------------*/
7123 static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian)
7128 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7141 emitpcode(poc, popGet(AOP(reg),offset));
7146 /*-----------------------------------------------------------------*/
7147 /* genLeftShift - generates code for left shifting */
7148 /*-----------------------------------------------------------------*/
7149 static void genLeftShift (iCode *ic)
7151 operand *left,*right, *result;
7154 symbol *tlbl , *tlbl1;
7157 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7159 right = IC_RIGHT(ic);
7161 result = IC_RESULT(ic);
7163 aopOp(right,ic,FALSE);
7165 /* if the shift count is known then do it
7166 as efficiently as possible */
7167 if (AOP_TYPE(right) == AOP_LIT) {
7168 genLeftShiftLiteral (left,right,result,ic);
7172 /* shift count is unknown then we have to form
7173 a loop get the loop count in B : Note: we take
7174 only the lower order byte since shifting
7175 more that 32 bits make no sense anyway, ( the
7176 largest size of an object can be only 32 bits ) */
7179 aopOp(left,ic,FALSE);
7180 aopOp(result,ic,FALSE);
7182 /* now move the left to the result if they are not the
7184 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7185 AOP_SIZE(result) > 1) {
7187 size = AOP_SIZE(result);
7190 l = aopGet(AOP(left),offset,FALSE,TRUE);
7191 if (*l == '@' && (IS_AOP_PREG(result))) {
7193 pic14_emitcode("mov","a,%s",l);
7194 aopPut(AOP(result),"a",offset);
7196 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7197 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7198 //aopPut(AOP(result),l,offset);
7204 size = AOP_SIZE(result);
7206 /* if it is only one byte then */
7208 if(optimized_for_speed) {
7209 emitpcode(POC_SWAPFW, popGet(AOP(left),0));
7210 emitpcode(POC_ANDLW, popGetLit(0xf0));
7211 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
7212 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7213 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7214 emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
7215 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7216 emitpcode(POC_RLFW, popGet(AOP(result),0));
7217 emitpcode(POC_ANDLW, popGetLit(0xfe));
7218 emitpcode(POC_ADDFW, popGet(AOP(result),0));
7219 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
7220 emitpcode(POC_ADDWF, popGet(AOP(result),0));
7223 tlbl = newiTempLabel(NULL);
7224 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7225 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7226 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7229 emitpcode(POC_COMFW, popGet(AOP(right),0));
7230 emitpcode(POC_RRF, popGet(AOP(result),0));
7231 emitpLabel(tlbl->key);
7232 emitpcode(POC_RLF, popGet(AOP(result),0));
7233 emitpcode(POC_ADDLW, popGetLit(1));
7235 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7240 if (pic14_sameRegs(AOP(left),AOP(result))) {
7242 tlbl = newiTempLabel(NULL);
7243 emitpcode(POC_COMFW, popGet(AOP(right),0));
7244 genMultiAsm(POC_RRF, result, size,1);
7245 emitpLabel(tlbl->key);
7246 genMultiAsm(POC_RLF, result, size,0);
7247 emitpcode(POC_ADDLW, popGetLit(1));
7249 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7253 //tlbl = newiTempLabel(NULL);
7255 //tlbl1 = newiTempLabel(NULL);
7257 //reAdjustPreg(AOP(result));
7259 //pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7260 //pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7261 //l = aopGet(AOP(result),offset,FALSE,FALSE);
7263 //pic14_emitcode("add","a,acc");
7264 //aopPut(AOP(result),"a",offset++);
7266 // l = aopGet(AOP(result),offset,FALSE,FALSE);
7268 // pic14_emitcode("rlc","a");
7269 // aopPut(AOP(result),"a",offset++);
7271 //reAdjustPreg(AOP(result));
7273 //pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7274 //pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7277 tlbl = newiTempLabel(NULL);
7278 tlbl1= newiTempLabel(NULL);
7280 size = AOP_SIZE(result);
7283 pctemp = popGetTempReg(); /* grab a temporary working register. */
7285 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7287 /* offset should be 0, 1 or 3 */
7288 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7290 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7292 emitpcode(POC_MOVWF, pctemp);
7295 emitpLabel(tlbl->key);
7298 emitpcode(POC_RLF, popGet(AOP(result),0));
7300 emitpcode(POC_RLF, popGet(AOP(result),offset++));
7302 emitpcode(POC_DECFSZ, pctemp);
7303 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7304 emitpLabel(tlbl1->key);
7306 popReleaseTempReg(pctemp);
7310 freeAsmop (right,NULL,ic,TRUE);
7311 freeAsmop(left,NULL,ic,TRUE);
7312 freeAsmop(result,NULL,ic,TRUE);
7315 /*-----------------------------------------------------------------*/
7316 /* genrshOne - right shift a one byte quantity by known count */
7317 /*-----------------------------------------------------------------*/
7318 static void genrshOne (operand *result, operand *left,
7319 int shCount, int sign)
7321 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7322 shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
7325 /*-----------------------------------------------------------------*/
7326 /* genrshTwo - right shift two bytes by known amount != 0 */
7327 /*-----------------------------------------------------------------*/
7328 static void genrshTwo (operand *result,operand *left,
7329 int shCount, int sign)
7331 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7332 /* if shCount >= 8 */
7336 shiftR1Left2Result(left, MSB16, result, LSB,
7339 movLeft2Result(left, MSB16, result, LSB);
7341 emitpcode(POC_CLRF,popGet(AOP(result),MSB16));
7344 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0));
7345 emitpcode(POC_DECF, popGet(AOP(result),MSB16));
7349 /* 1 <= shCount <= 7 */
7351 shiftR2Left2Result(left, LSB, result, LSB, shCount, sign);
7354 /*-----------------------------------------------------------------*/
7355 /* shiftRLong - shift right one long from left to result */
7356 /* offl = LSB or MSB16 */
7357 /*-----------------------------------------------------------------*/
7358 static void shiftRLong (operand *left, int offl,
7359 operand *result, int sign)
7361 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7363 pic14_emitcode("clr","c");
7364 MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
7366 pic14_emitcode("mov","c,acc.7");
7367 pic14_emitcode("rrc","a");
7368 aopPut(AOP(result),"a",MSB32-offl);
7370 /* add sign of "a" */
7371 addSign(result, MSB32, sign);
7373 MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
7374 pic14_emitcode("rrc","a");
7375 aopPut(AOP(result),"a",MSB24-offl);
7377 MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
7378 pic14_emitcode("rrc","a");
7379 aopPut(AOP(result),"a",MSB16-offl);
7382 MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
7383 pic14_emitcode("rrc","a");
7384 aopPut(AOP(result),"a",LSB);
7388 /*-----------------------------------------------------------------*/
7389 /* genrshFour - shift four byte by a known amount != 0 */
7390 /*-----------------------------------------------------------------*/
7391 static void genrshFour (operand *result, operand *left,
7392 int shCount, int sign)
7394 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7395 /* if shifting more that 3 bytes */
7396 if(shCount >= 24 ) {
7399 shiftR1Left2Result(left, MSB32, result, LSB, shCount, sign);
7401 movLeft2Result(left, MSB32, result, LSB);
7403 addSign(result, MSB16, sign);
7405 else if(shCount >= 16){
7408 shiftR2Left2Result(left, MSB24, result, LSB, shCount, sign);
7410 movLeft2Result(left, MSB24, result, LSB);
7411 movLeft2Result(left, MSB32, result, MSB16);
7413 addSign(result, MSB24, sign);
7415 else if(shCount >= 8){
7418 shiftRLong(left, MSB16, result, sign);
7419 else if(shCount == 0){
7420 movLeft2Result(left, MSB16, result, LSB);
7421 movLeft2Result(left, MSB24, result, MSB16);
7422 movLeft2Result(left, MSB32, result, MSB24);
7423 addSign(result, MSB32, sign);
7426 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0);
7427 shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount);
7428 /* the last shift is signed */
7429 shiftR1Left2Result(left, MSB32, result, MSB24, shCount, sign);
7430 addSign(result, MSB32, sign);
7433 else{ /* 1 <= shCount <= 7 */
7435 shiftRLong(left, LSB, result, sign);
7437 shiftRLong(result, LSB, result, sign);
7440 shiftR2Left2Result(left, LSB, result, LSB, shCount, 0);
7441 shiftLLeftOrResult(left, MSB24, result, MSB16, 8 - shCount);
7442 shiftR2Left2Result(left, MSB24, result, MSB24, shCount, sign);
7447 /*-----------------------------------------------------------------*/
7448 /* genRightShiftLiteral - right shifting by known count */
7449 /*-----------------------------------------------------------------*/
7450 static void genRightShiftLiteral (operand *left,
7456 int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
7459 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7460 freeAsmop(right,NULL,ic,TRUE);
7462 aopOp(left,ic,FALSE);
7463 aopOp(result,ic,FALSE);
7466 pic14_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result),
7470 lsize = pic14_getDataSize(left);
7471 res_size = pic14_getDataSize(result);
7472 /* test the LEFT size !!! */
7474 /* I suppose that the left size >= result size */
7477 movLeft2Result(left, lsize, result, res_size);
7480 else if(shCount >= (lsize * 8)){
7483 emitpcode(POC_CLRF, popGet(AOP(result),LSB));
7485 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7486 emitpcode(POC_DECF, popGet(AOP(result),LSB));
7491 emitpcode(POC_MOVLW, popGetLit(0));
7492 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0));
7493 emitpcode(POC_MOVLW, popGetLit(0xff));
7495 emitpcode(POC_MOVWF, popGet(AOP(result),res_size));
7500 emitpcode(POC_CLRF, popGet(AOP(result),res_size));
7507 genrshOne (result,left,shCount,sign);
7511 genrshTwo (result,left,shCount,sign);
7515 genrshFour (result,left,shCount,sign);
7523 freeAsmop(left,NULL,ic,TRUE);
7524 freeAsmop(result,NULL,ic,TRUE);
7527 /*-----------------------------------------------------------------*/
7528 /* genSignedRightShift - right shift of signed number */
7529 /*-----------------------------------------------------------------*/
7530 static void genSignedRightShift (iCode *ic)
7532 operand *right, *left, *result;
7535 symbol *tlbl, *tlbl1 ;
7538 //same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr);
7540 /* we do it the hard way put the shift count in b
7541 and loop thru preserving the sign */
7542 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7544 right = IC_RIGHT(ic);
7546 result = IC_RESULT(ic);
7548 aopOp(right,ic,FALSE);
7549 aopOp(left,ic,FALSE);
7550 aopOp(result,ic,FALSE);
7553 if ( AOP_TYPE(right) == AOP_LIT) {
7554 genRightShiftLiteral (left,right,result,ic,1);
7557 /* shift count is unknown then we have to form
7558 a loop get the loop count in B : Note: we take
7559 only the lower order byte since shifting
7560 more that 32 bits make no sense anyway, ( the
7561 largest size of an object can be only 32 bits ) */
7563 //pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7564 //pic14_emitcode("inc","b");
7565 //freeAsmop (right,NULL,ic,TRUE);
7566 //aopOp(left,ic,FALSE);
7567 //aopOp(result,ic,FALSE);
7569 /* now move the left to the result if they are not the
7571 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7572 AOP_SIZE(result) > 1) {
7574 size = AOP_SIZE(result);
7578 l = aopGet(AOP(left),offset,FALSE,TRUE);
7579 if (*l == '@' && IS_AOP_PREG(result)) {
7581 pic14_emitcode("mov","a,%s",l);
7582 aopPut(AOP(result),"a",offset);
7584 aopPut(AOP(result),l,offset);
7586 emitpcode(POC_MOVFW, popGet(AOP(left),offset));
7587 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7593 /* mov the highest order bit to OVR */
7594 tlbl = newiTempLabel(NULL);
7595 tlbl1= newiTempLabel(NULL);
7597 size = AOP_SIZE(result);
7600 pctemp = popGetTempReg(); /* grab a temporary working register. */
7602 emitpcode(POC_MOVFW, popGet(AOP(right),0));
7604 /* offset should be 0, 1 or 3 */
7605 emitpcode(POC_ANDLW, popGetLit(0x07 + ((offset&3) << 3)));
7607 emitpcode(POC_GOTO, popGetLabel(tlbl1->key));
7609 emitpcode(POC_MOVWF, pctemp);
7612 emitpLabel(tlbl->key);
7614 emitpcode(POC_RLFW, popGet(AOP(result),offset));
7615 emitpcode(POC_RRF, popGet(AOP(result),offset));
7618 emitpcode(POC_RRF, popGet(AOP(result),--offset));
7621 emitpcode(POC_DECFSZ, pctemp);
7622 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7623 emitpLabel(tlbl1->key);
7625 popReleaseTempReg(pctemp);
7627 size = AOP_SIZE(result);
7629 pic14_emitcode("mov","a,%s",aopGet(AOP(left),offset,FALSE,FALSE));
7630 pic14_emitcode("rlc","a");
7631 pic14_emitcode("mov","ov,c");
7632 /* if it is only one byte then */
7634 l = aopGet(AOP(left),0,FALSE,FALSE);
7636 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7637 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7638 pic14_emitcode("mov","c,ov");
7639 pic14_emitcode("rrc","a");
7640 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7641 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7642 aopPut(AOP(result),"a",0);
7646 reAdjustPreg(AOP(result));
7647 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7648 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7649 pic14_emitcode("mov","c,ov");
7651 l = aopGet(AOP(result),offset,FALSE,FALSE);
7653 pic14_emitcode("rrc","a");
7654 aopPut(AOP(result),"a",offset--);
7656 reAdjustPreg(AOP(result));
7657 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7658 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7663 freeAsmop(left,NULL,ic,TRUE);
7664 freeAsmop(result,NULL,ic,TRUE);
7665 freeAsmop(right,NULL,ic,TRUE);
7668 /*-----------------------------------------------------------------*/
7669 /* genRightShift - generate code for right shifting */
7670 /*-----------------------------------------------------------------*/
7671 static void genRightShift (iCode *ic)
7673 operand *right, *left, *result;
7677 symbol *tlbl, *tlbl1 ;
7679 /* if signed then we do it the hard way preserve the
7680 sign bit moving it inwards */
7681 retype = getSpec(operandType(IC_RESULT(ic)));
7682 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7684 if (!SPEC_USIGN(retype)) {
7685 genSignedRightShift (ic);
7689 /* signed & unsigned types are treated the same : i.e. the
7690 signed is NOT propagated inwards : quoting from the
7691 ANSI - standard : "for E1 >> E2, is equivalent to division
7692 by 2**E2 if unsigned or if it has a non-negative value,
7693 otherwise the result is implementation defined ", MY definition
7694 is that the sign does not get propagated */
7696 right = IC_RIGHT(ic);
7698 result = IC_RESULT(ic);
7700 aopOp(right,ic,FALSE);
7702 /* if the shift count is known then do it
7703 as efficiently as possible */
7704 if (AOP_TYPE(right) == AOP_LIT) {
7705 genRightShiftLiteral (left,right,result,ic, 0);
7709 /* shift count is unknown then we have to form
7710 a loop get the loop count in B : Note: we take
7711 only the lower order byte since shifting
7712 more that 32 bits make no sense anyway, ( the
7713 largest size of an object can be only 32 bits ) */
7715 pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
7716 pic14_emitcode("inc","b");
7717 aopOp(left,ic,FALSE);
7718 aopOp(result,ic,FALSE);
7720 /* now move the left to the result if they are not the
7722 if (!pic14_sameRegs(AOP(left),AOP(result)) &&
7723 AOP_SIZE(result) > 1) {
7725 size = AOP_SIZE(result);
7728 l = aopGet(AOP(left),offset,FALSE,TRUE);
7729 if (*l == '@' && IS_AOP_PREG(result)) {
7731 pic14_emitcode("mov","a,%s",l);
7732 aopPut(AOP(result),"a",offset);
7734 aopPut(AOP(result),l,offset);
7739 tlbl = newiTempLabel(NULL);
7740 tlbl1= newiTempLabel(NULL);
7741 size = AOP_SIZE(result);
7744 /* if it is only one byte then */
7747 tlbl = newiTempLabel(NULL);
7748 if (!pic14_sameRegs(AOP(left),AOP(result))) {
7749 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7750 emitpcode(POC_MOVWF, popGet(AOP(result),0));
7753 emitpcode(POC_COMFW, popGet(AOP(right),0));
7754 emitpcode(POC_RLF, popGet(AOP(result),0));
7755 emitpLabel(tlbl->key);
7756 emitpcode(POC_RRF, popGet(AOP(result),0));
7757 emitpcode(POC_ADDLW, popGetLit(1));
7759 emitpcode(POC_GOTO,popGetLabel(tlbl->key));
7764 reAdjustPreg(AOP(result));
7765 pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
7766 pic14_emitcode("","%05d_DS_:",tlbl->key+100);
7769 l = aopGet(AOP(result),offset,FALSE,FALSE);
7771 pic14_emitcode("rrc","a");
7772 aopPut(AOP(result),"a",offset--);
7774 reAdjustPreg(AOP(result));
7776 pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
7777 pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
7780 freeAsmop(left,NULL,ic,TRUE);
7781 freeAsmop (right,NULL,ic,TRUE);
7782 freeAsmop(result,NULL,ic,TRUE);
7785 /*-----------------------------------------------------------------*/
7786 /* genUnpackBits - generates code for unpacking bits */
7787 /*-----------------------------------------------------------------*/
7788 static void genUnpackBits (operand *result, char *rname, int ptype)
7795 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7796 etype = getSpec(operandType(result));
7798 /* read the first byte */
7803 pic14_emitcode("mov","a,@%s",rname);
7807 pic14_emitcode("movx","a,@%s",rname);
7811 pic14_emitcode("movx","a,@dptr");
7815 pic14_emitcode("clr","a");
7816 pic14_emitcode("movc","a","@a+dptr");
7820 pic14_emitcode("lcall","__gptrget");
7824 /* if we have bitdisplacement then it fits */
7825 /* into this byte completely or if length is */
7826 /* less than a byte */
7827 if ((shCnt = SPEC_BSTR(etype)) ||
7828 (SPEC_BLEN(etype) <= 8)) {
7830 /* shift right acc */
7833 pic14_emitcode("anl","a,#0x%02x",
7834 ((unsigned char) -1)>>(8 - SPEC_BLEN(etype)));
7835 aopPut(AOP(result),"a",offset);
7839 /* bit field did not fit in a byte */
7840 rlen = SPEC_BLEN(etype) - 8;
7841 aopPut(AOP(result),"a",offset++);
7848 pic14_emitcode("inc","%s",rname);
7849 pic14_emitcode("mov","a,@%s",rname);
7853 pic14_emitcode("inc","%s",rname);
7854 pic14_emitcode("movx","a,@%s",rname);
7858 pic14_emitcode("inc","dptr");
7859 pic14_emitcode("movx","a,@dptr");
7863 pic14_emitcode("clr","a");
7864 pic14_emitcode("inc","dptr");
7865 pic14_emitcode("movc","a","@a+dptr");
7869 pic14_emitcode("inc","dptr");
7870 pic14_emitcode("lcall","__gptrget");
7875 /* if we are done */
7879 aopPut(AOP(result),"a",offset++);
7884 pic14_emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
7885 aopPut(AOP(result),"a",offset);
7892 /*-----------------------------------------------------------------*/
7893 /* genDataPointerGet - generates code when ptr offset is known */
7894 /*-----------------------------------------------------------------*/
7895 static void genDataPointerGet (operand *left,
7899 int size , offset = 0;
7902 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7905 /* optimization - most of the time, left and result are the same
7906 * address, but different types. for the pic code, we could omit
7910 aopOp(result,ic,TRUE);
7912 DEBUGpic14_AopType(__LINE__,left,NULL,result);
7914 emitpcode(POC_MOVFW, popGet(AOP(left),0));
7916 size = AOP_SIZE(result);
7919 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
7923 freeAsmop(left,NULL,ic,TRUE);
7924 freeAsmop(result,NULL,ic,TRUE);
7927 /*-----------------------------------------------------------------*/
7928 /* genNearPointerGet - pic14_emitcode for near pointer fetch */
7929 /*-----------------------------------------------------------------*/
7930 static void genNearPointerGet (operand *left,
7935 //regs *preg = NULL ;
7937 sym_link *rtype, *retype;
7938 sym_link *ltype = operandType(left);
7941 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7943 rtype = operandType(result);
7944 retype= getSpec(rtype);
7946 aopOp(left,ic,FALSE);
7948 /* if left is rematerialisable and
7949 result is not bit variable type and
7950 the left is pointer to data space i.e
7951 lower 128 bytes of space */
7952 if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD &&
7953 !IS_BITVAR(retype) &&
7954 DCL_TYPE(ltype) == POINTER) {
7955 //genDataPointerGet (left,result,ic);
7959 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7961 /* if the value is already in a pointer register
7962 then don't need anything more */
7963 if (!AOP_INPREG(AOP(left))) {
7964 /* otherwise get a free pointer register */
7965 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7968 preg = getFreePtr(ic,&aop,FALSE);
7969 pic14_emitcode("mov","%s,%s",
7971 aopGet(AOP(left),0,FALSE,TRUE));
7972 rname = preg->name ;
7976 rname = aopGet(AOP(left),0,FALSE,FALSE);
7978 aopOp (result,ic,FALSE);
7980 /* if bitfield then unpack the bits */
7981 if (IS_BITVAR(retype))
7982 genUnpackBits (result,rname,POINTER);
7984 /* we have can just get the values */
7985 int size = AOP_SIZE(result);
7988 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
7990 emitpcode(POC_MOVFW,popGet(AOP(left),0));
7991 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
7993 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
7994 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
7996 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8000 if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) {
8002 pic14_emitcode("mov","a,@%s",rname);
8003 aopPut(AOP(result),"a",offset);
8005 sprintf(buffer,"@%s",rname);
8006 aopPut(AOP(result),buffer,offset);
8010 pic14_emitcode("inc","%s",rname);
8015 /* now some housekeeping stuff */
8017 /* we had to allocate for this iCode */
8018 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8019 freeAsmop(NULL,aop,ic,TRUE);
8021 /* we did not allocate which means left
8022 already in a pointer register, then
8023 if size > 0 && this could be used again
8024 we have to point it back to where it
8026 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8027 if (AOP_SIZE(result) > 1 &&
8028 !OP_SYMBOL(left)->remat &&
8029 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8031 int size = AOP_SIZE(result) - 1;
8033 pic14_emitcode("dec","%s",rname);
8038 freeAsmop(left,NULL,ic,TRUE);
8039 freeAsmop(result,NULL,ic,TRUE);
8043 /*-----------------------------------------------------------------*/
8044 /* genPagedPointerGet - pic14_emitcode for paged pointer fetch */
8045 /*-----------------------------------------------------------------*/
8046 static void genPagedPointerGet (operand *left,
8053 sym_link *rtype, *retype;
8055 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8057 rtype = operandType(result);
8058 retype= getSpec(rtype);
8060 aopOp(left,ic,FALSE);
8062 /* if the value is already in a pointer register
8063 then don't need anything more */
8064 if (!AOP_INPREG(AOP(left))) {
8065 /* otherwise get a free pointer register */
8067 preg = getFreePtr(ic,&aop,FALSE);
8068 pic14_emitcode("mov","%s,%s",
8070 aopGet(AOP(left),0,FALSE,TRUE));
8071 rname = preg->name ;
8073 rname = aopGet(AOP(left),0,FALSE,FALSE);
8075 freeAsmop(left,NULL,ic,TRUE);
8076 aopOp (result,ic,FALSE);
8078 /* if bitfield then unpack the bits */
8079 if (IS_BITVAR(retype))
8080 genUnpackBits (result,rname,PPOINTER);
8082 /* we have can just get the values */
8083 int size = AOP_SIZE(result);
8088 pic14_emitcode("movx","a,@%s",rname);
8089 aopPut(AOP(result),"a",offset);
8094 pic14_emitcode("inc","%s",rname);
8098 /* now some housekeeping stuff */
8100 /* we had to allocate for this iCode */
8101 freeAsmop(NULL,aop,ic,TRUE);
8103 /* we did not allocate which means left
8104 already in a pointer register, then
8105 if size > 0 && this could be used again
8106 we have to point it back to where it
8108 if (AOP_SIZE(result) > 1 &&
8109 !OP_SYMBOL(left)->remat &&
8110 ( OP_SYMBOL(left)->liveTo > ic->seq ||
8112 int size = AOP_SIZE(result) - 1;
8114 pic14_emitcode("dec","%s",rname);
8119 freeAsmop(result,NULL,ic,TRUE);
8124 /*-----------------------------------------------------------------*/
8125 /* genFarPointerGet - gget value from far space */
8126 /*-----------------------------------------------------------------*/
8127 static void genFarPointerGet (operand *left,
8128 operand *result, iCode *ic)
8131 sym_link *retype = getSpec(operandType(result));
8133 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8135 aopOp(left,ic,FALSE);
8137 /* if the operand is already in dptr
8138 then we do nothing else we move the value to dptr */
8139 if (AOP_TYPE(left) != AOP_STR) {
8140 /* if this is remateriazable */
8141 if (AOP_TYPE(left) == AOP_IMMD)
8142 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8143 else { /* we need to get it byte by byte */
8144 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8145 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8146 if (options.model == MODEL_FLAT24)
8148 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8152 /* so dptr know contains the address */
8153 freeAsmop(left,NULL,ic,TRUE);
8154 aopOp(result,ic,FALSE);
8156 /* if bit then unpack */
8157 if (IS_BITVAR(retype))
8158 genUnpackBits(result,"dptr",FPOINTER);
8160 size = AOP_SIZE(result);
8164 pic14_emitcode("movx","a,@dptr");
8165 aopPut(AOP(result),"a",offset++);
8167 pic14_emitcode("inc","dptr");
8171 freeAsmop(result,NULL,ic,TRUE);
8174 /*-----------------------------------------------------------------*/
8175 /* genCodePointerGet - get value from code space */
8176 /*-----------------------------------------------------------------*/
8177 static void genCodePointerGet (operand *left,
8178 operand *result, iCode *ic)
8181 sym_link *retype = getSpec(operandType(result));
8183 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8185 aopOp(left,ic,FALSE);
8187 /* if the operand is already in dptr
8188 then we do nothing else we move the value to dptr */
8189 if (AOP_TYPE(left) != AOP_STR) {
8190 /* if this is remateriazable */
8191 if (AOP_TYPE(left) == AOP_IMMD)
8192 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8193 else { /* we need to get it byte by byte */
8194 pic14_emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
8195 pic14_emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
8196 if (options.model == MODEL_FLAT24)
8198 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
8202 /* so dptr know contains the address */
8203 freeAsmop(left,NULL,ic,TRUE);
8204 aopOp(result,ic,FALSE);
8206 /* if bit then unpack */
8207 if (IS_BITVAR(retype))
8208 genUnpackBits(result,"dptr",CPOINTER);
8210 size = AOP_SIZE(result);
8214 pic14_emitcode("clr","a");
8215 pic14_emitcode("movc","a,@a+dptr");
8216 aopPut(AOP(result),"a",offset++);
8218 pic14_emitcode("inc","dptr");
8222 freeAsmop(result,NULL,ic,TRUE);
8225 /*-----------------------------------------------------------------*/
8226 /* genGenPointerGet - gget value from generic pointer space */
8227 /*-----------------------------------------------------------------*/
8228 static void genGenPointerGet (operand *left,
8229 operand *result, iCode *ic)
8232 sym_link *retype = getSpec(operandType(result));
8234 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8235 aopOp(left,ic,FALSE);
8236 aopOp(result,ic,FALSE);
8239 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8241 /* if the operand is already in dptr
8242 then we do nothing else we move the value to dptr */
8243 // if (AOP_TYPE(left) != AOP_STR) {
8244 /* if this is remateriazable */
8245 if (AOP_TYPE(left) == AOP_IMMD) {
8246 pic14_emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE));
8247 pic14_emitcode("mov","b,#%d",pointerCode(retype));
8249 else { /* we need to get it byte by byte */
8251 emitpcode(POC_MOVFW,popGet(AOP(left),0));
8252 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8254 size = AOP_SIZE(result);
8258 emitpcode(POC_MOVFW,popCopyReg(&pc_indf));
8259 emitpcode(POC_MOVWF,popGet(AOP(result),offset++));
8261 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8266 /* so dptr know contains the address */
8268 /* if bit then unpack */
8269 //if (IS_BITVAR(retype))
8270 // genUnpackBits(result,"dptr",GPOINTER);
8273 freeAsmop(left,NULL,ic,TRUE);
8274 freeAsmop(result,NULL,ic,TRUE);
8278 /*-----------------------------------------------------------------*/
8279 /* genConstPointerGet - get value from const generic pointer space */
8280 /*-----------------------------------------------------------------*/
8281 static void genConstPointerGet (operand *left,
8282 operand *result, iCode *ic)
8284 //sym_link *retype = getSpec(operandType(result));
8285 symbol *albl = newiTempLabel(NULL);
8286 symbol *blbl = newiTempLabel(NULL);
8290 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8291 aopOp(left,ic,FALSE);
8292 aopOp(result,ic,FALSE);
8295 DEBUGpic14_AopType(__LINE__,left,NULL,result);
8297 DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
8299 emitpcode(POC_CALL,popGetLabel(albl->key));
8300 pcop = popGetLabel(blbl->key);
8301 emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
8302 emitpcode(POC_GOTO,pcop);
8303 emitpLabel(albl->key);
8305 poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
8307 emitpcode(poc,popGet(AOP(left),1));
8308 emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
8309 emitpcode(poc,popGet(AOP(left),0));
8310 emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
8312 emitpLabel(blbl->key);
8314 emitpcode(POC_MOVWF,popGet(AOP(result),0));
8317 freeAsmop(left,NULL,ic,TRUE);
8318 freeAsmop(result,NULL,ic,TRUE);
8321 /*-----------------------------------------------------------------*/
8322 /* genPointerGet - generate code for pointer get */
8323 /*-----------------------------------------------------------------*/
8324 static void genPointerGet (iCode *ic)
8326 operand *left, *result ;
8327 sym_link *type, *etype;
8330 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8333 result = IC_RESULT(ic) ;
8335 /* depending on the type of pointer we need to
8336 move it to the correct pointer register */
8337 type = operandType(left);
8338 etype = getSpec(type);
8340 if (IS_PTR_CONST(type))
8341 DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
8343 /* if left is of type of pointer then it is simple */
8344 if (IS_PTR(type) && !IS_FUNC(type->next))
8345 p_type = DCL_TYPE(type);
8347 /* we have to go by the storage class */
8348 p_type = PTR_TYPE(SPEC_OCLS(etype));
8350 DEBUGpic14_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__);
8352 if (SPEC_OCLS(etype)->codesp ) {
8353 DEBUGpic14_emitcode ("; ***","%d - cpointer",__LINE__);
8354 //p_type = CPOINTER ;
8357 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
8358 DEBUGpic14_emitcode ("; ***","%d - fpointer",__LINE__);
8359 /*p_type = FPOINTER ;*/
8361 if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
8362 DEBUGpic14_emitcode ("; ***","%d - ppointer",__LINE__);
8363 /* p_type = PPOINTER; */
8365 if (SPEC_OCLS(etype) == idata )
8366 DEBUGpic14_emitcode ("; ***","%d - ipointer",__LINE__);
8367 /* p_type = IPOINTER; */
8369 DEBUGpic14_emitcode ("; ***","%d - pointer",__LINE__);
8370 /* p_type = POINTER ; */
8373 /* now that we have the pointer type we assign
8374 the pointer values */
8379 genNearPointerGet (left,result,ic);
8383 genPagedPointerGet(left,result,ic);
8387 genFarPointerGet (left,result,ic);
8391 genConstPointerGet (left,result,ic);
8392 //pic14_emitcodePointerGet (left,result,ic);
8396 if (IS_PTR_CONST(type))
8397 genConstPointerGet (left,result,ic);
8399 genGenPointerGet (left,result,ic);
8405 /*-----------------------------------------------------------------*/
8406 /* genPackBits - generates code for packed bit storage */
8407 /*-----------------------------------------------------------------*/
8408 static void genPackBits (sym_link *etype ,
8410 char *rname, int p_type)
8418 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8419 blen = SPEC_BLEN(etype);
8420 bstr = SPEC_BSTR(etype);
8422 l = aopGet(AOP(right),offset++,FALSE,FALSE);
8425 /* if the bit lenth is less than or */
8426 /* it exactly fits a byte then */
8427 if (SPEC_BLEN(etype) <= 8 ) {
8428 shCount = SPEC_BSTR(etype) ;
8430 /* shift left acc */
8433 if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */
8438 pic14_emitcode ("mov","b,a");
8439 pic14_emitcode("mov","a,@%s",rname);
8443 pic14_emitcode ("mov","b,a");
8444 pic14_emitcode("movx","a,@dptr");
8448 pic14_emitcode ("push","b");
8449 pic14_emitcode ("push","acc");
8450 pic14_emitcode ("lcall","__gptrget");
8451 pic14_emitcode ("pop","b");
8455 pic14_emitcode ("anl","a,#0x%02x",(unsigned char)
8456 ((unsigned char)(0xFF << (blen+bstr)) |
8457 (unsigned char)(0xFF >> (8-bstr)) ) );
8458 pic14_emitcode ("orl","a,b");
8459 if (p_type == GPOINTER)
8460 pic14_emitcode("pop","b");
8466 pic14_emitcode("mov","@%s,a",rname);
8470 pic14_emitcode("movx","@dptr,a");
8474 DEBUGpic14_emitcode(";lcall","__gptrput");
8479 if ( SPEC_BLEN(etype) <= 8 )
8482 pic14_emitcode("inc","%s",rname);
8483 rLen = SPEC_BLEN(etype) ;
8485 /* now generate for lengths greater than one byte */
8488 l = aopGet(AOP(right),offset++,FALSE,TRUE);
8498 pic14_emitcode("mov","@%s,a",rname);
8500 pic14_emitcode("mov","@%s,%s",rname,l);
8505 pic14_emitcode("movx","@dptr,a");
8510 DEBUGpic14_emitcode(";lcall","__gptrput");
8513 pic14_emitcode ("inc","%s",rname);
8518 /* last last was not complete */
8520 /* save the byte & read byte */
8523 pic14_emitcode ("mov","b,a");
8524 pic14_emitcode("mov","a,@%s",rname);
8528 pic14_emitcode ("mov","b,a");
8529 pic14_emitcode("movx","a,@dptr");
8533 pic14_emitcode ("push","b");
8534 pic14_emitcode ("push","acc");
8535 pic14_emitcode ("lcall","__gptrget");
8536 pic14_emitcode ("pop","b");
8540 pic14_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
8541 pic14_emitcode ("orl","a,b");
8544 if (p_type == GPOINTER)
8545 pic14_emitcode("pop","b");
8550 pic14_emitcode("mov","@%s,a",rname);
8554 pic14_emitcode("movx","@dptr,a");
8558 DEBUGpic14_emitcode(";lcall","__gptrput");
8562 /*-----------------------------------------------------------------*/
8563 /* genDataPointerSet - remat pointer to data space */
8564 /*-----------------------------------------------------------------*/
8565 static void genDataPointerSet(operand *right,
8569 int size, offset = 0 ;
8570 char *l, buffer[256];
8572 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8573 aopOp(right,ic,FALSE);
8575 l = aopGet(AOP(result),0,FALSE,TRUE);
8576 size = AOP_SIZE(right);
8578 if ( AOP_TYPE(result) == AOP_PCODE) {
8579 fprintf(stderr,"genDataPointerSet %s, %d\n",
8580 AOP(result)->aopu.pcop->name,
8581 PCOI(AOP(result)->aopu.pcop)->offset);
8585 // tsd, was l+1 - the underline `_' prefix was being stripped
8588 sprintf(buffer,"(%s + %d)",l,offset);
8589 fprintf(stderr,"oops %s\n",buffer);
8591 sprintf(buffer,"%s",l);
8593 if (AOP_TYPE(right) == AOP_LIT) {
8594 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8595 lit = lit >> (8*offset);
8597 pic14_emitcode("movlw","%d",lit);
8598 pic14_emitcode("movwf","%s",buffer);
8600 emitpcode(POC_MOVLW, popGetLit(lit&0xff));
8601 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8602 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8605 pic14_emitcode("clrf","%s",buffer);
8606 //emitpcode(POC_CLRF, popRegFromString(buffer));
8607 emitpcode(POC_CLRF, popGet(AOP(result),0));
8610 pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
8611 pic14_emitcode("movwf","%s",buffer);
8613 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8614 //emitpcode(POC_MOVWF, popRegFromString(buffer));
8615 emitpcode(POC_MOVWF, popGet(AOP(result),0));
8622 freeAsmop(right,NULL,ic,TRUE);
8623 freeAsmop(result,NULL,ic,TRUE);
8626 /*-----------------------------------------------------------------*/
8627 /* genNearPointerSet - pic14_emitcode for near pointer put */
8628 /*-----------------------------------------------------------------*/
8629 static void genNearPointerSet (operand *right,
8636 sym_link *ptype = operandType(result);
8639 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8640 retype= getSpec(operandType(right));
8642 aopOp(result,ic,FALSE);
8645 /* if the result is rematerializable &
8646 in data space & not a bit variable */
8647 //if (AOP_TYPE(result) == AOP_IMMD &&
8648 if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD &&
8649 DCL_TYPE(ptype) == POINTER &&
8650 !IS_BITVAR(retype)) {
8651 genDataPointerSet (right,result,ic);
8652 freeAsmop(result,NULL,ic,TRUE);
8656 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8657 aopOp(right,ic,FALSE);
8658 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8660 /* if the value is already in a pointer register
8661 then don't need anything more */
8662 if (!AOP_INPREG(AOP(result))) {
8663 /* otherwise get a free pointer register */
8664 //aop = newAsmop(0);
8665 //preg = getFreePtr(ic,&aop,FALSE);
8666 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8667 //pic14_emitcode("mov","%s,%s",
8669 // aopGet(AOP(result),0,FALSE,TRUE));
8670 //rname = preg->name ;
8671 //pic14_emitcode("movwf","fsr");
8672 emitpcode(POC_MOVFW, popGet(AOP(result),0));
8673 emitpcode(POC_MOVWF, popCopyReg(&pc_fsr));
8674 emitpcode(POC_MOVFW, popGet(AOP(right),0));
8675 emitpcode(POC_MOVWF, popCopyReg(&pc_indf));
8679 // rname = aopGet(AOP(result),0,FALSE,FALSE);
8682 /* if bitfield then unpack the bits */
8683 if (IS_BITVAR(retype)) {
8684 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
8685 "The programmer is obviously confused");
8686 //genPackBits (retype,right,rname,POINTER);
8690 /* we have can just get the values */
8691 int size = AOP_SIZE(right);
8694 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8696 l = aopGet(AOP(right),offset,FALSE,TRUE);
8699 //pic14_emitcode("mov","@%s,a",rname);
8700 pic14_emitcode("movf","indf,w ;1");
8703 if (AOP_TYPE(right) == AOP_LIT) {
8704 unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
8706 pic14_emitcode("movlw","%s",l);
8707 pic14_emitcode("movwf","indf ;2");
8709 pic14_emitcode("clrf","indf");
8711 pic14_emitcode("movf","%s,w",l);
8712 pic14_emitcode("movwf","indf ;2");
8714 //pic14_emitcode("mov","@%s,%s",rname,l);
8717 pic14_emitcode("incf","fsr,f ;3");
8718 //pic14_emitcode("inc","%s",rname);
8723 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8724 /* now some housekeeping stuff */
8726 /* we had to allocate for this iCode */
8727 freeAsmop(NULL,aop,ic,TRUE);
8729 /* we did not allocate which means left
8730 already in a pointer register, then
8731 if size > 0 && this could be used again
8732 we have to point it back to where it
8734 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8735 if (AOP_SIZE(right) > 1 &&
8736 !OP_SYMBOL(result)->remat &&
8737 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8739 int size = AOP_SIZE(right) - 1;
8741 pic14_emitcode("decf","fsr,f");
8742 //pic14_emitcode("dec","%s",rname);
8746 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8749 freeAsmop(right,NULL,ic,TRUE);
8750 freeAsmop(result,NULL,ic,TRUE);
8753 /*-----------------------------------------------------------------*/
8754 /* genPagedPointerSet - pic14_emitcode for Paged pointer put */
8755 /*-----------------------------------------------------------------*/
8756 static void genPagedPointerSet (operand *right,
8765 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8767 retype= getSpec(operandType(right));
8769 aopOp(result,ic,FALSE);
8771 /* if the value is already in a pointer register
8772 then don't need anything more */
8773 if (!AOP_INPREG(AOP(result))) {
8774 /* otherwise get a free pointer register */
8776 preg = getFreePtr(ic,&aop,FALSE);
8777 pic14_emitcode("mov","%s,%s",
8779 aopGet(AOP(result),0,FALSE,TRUE));
8780 rname = preg->name ;
8782 rname = aopGet(AOP(result),0,FALSE,FALSE);
8784 freeAsmop(result,NULL,ic,TRUE);
8785 aopOp (right,ic,FALSE);
8787 /* if bitfield then unpack the bits */
8788 if (IS_BITVAR(retype))
8789 genPackBits (retype,right,rname,PPOINTER);
8791 /* we have can just get the values */
8792 int size = AOP_SIZE(right);
8796 l = aopGet(AOP(right),offset,FALSE,TRUE);
8799 pic14_emitcode("movx","@%s,a",rname);
8802 pic14_emitcode("inc","%s",rname);
8808 /* now some housekeeping stuff */
8810 /* we had to allocate for this iCode */
8811 freeAsmop(NULL,aop,ic,TRUE);
8813 /* we did not allocate which means left
8814 already in a pointer register, then
8815 if size > 0 && this could be used again
8816 we have to point it back to where it
8818 if (AOP_SIZE(right) > 1 &&
8819 !OP_SYMBOL(result)->remat &&
8820 ( OP_SYMBOL(result)->liveTo > ic->seq ||
8822 int size = AOP_SIZE(right) - 1;
8824 pic14_emitcode("dec","%s",rname);
8829 freeAsmop(right,NULL,ic,TRUE);
8834 /*-----------------------------------------------------------------*/
8835 /* genFarPointerSet - set value from far space */
8836 /*-----------------------------------------------------------------*/
8837 static void genFarPointerSet (operand *right,
8838 operand *result, iCode *ic)
8841 sym_link *retype = getSpec(operandType(right));
8843 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8844 aopOp(result,ic,FALSE);
8846 /* if the operand is already in dptr
8847 then we do nothing else we move the value to dptr */
8848 if (AOP_TYPE(result) != AOP_STR) {
8849 /* if this is remateriazable */
8850 if (AOP_TYPE(result) == AOP_IMMD)
8851 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8852 else { /* we need to get it byte by byte */
8853 pic14_emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
8854 pic14_emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
8855 if (options.model == MODEL_FLAT24)
8857 pic14_emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
8861 /* so dptr know contains the address */
8862 freeAsmop(result,NULL,ic,TRUE);
8863 aopOp(right,ic,FALSE);
8865 /* if bit then unpack */
8866 if (IS_BITVAR(retype))
8867 genPackBits(retype,right,"dptr",FPOINTER);
8869 size = AOP_SIZE(right);
8873 char *l = aopGet(AOP(right),offset++,FALSE,FALSE);
8875 pic14_emitcode("movx","@dptr,a");
8877 pic14_emitcode("inc","dptr");
8881 freeAsmop(right,NULL,ic,TRUE);
8884 /*-----------------------------------------------------------------*/
8885 /* genGenPointerSet - set value from generic pointer space */
8886 /*-----------------------------------------------------------------*/
8887 static void genGenPointerSet (operand *right,
8888 operand *result, iCode *ic)
8891 sym_link *retype = getSpec(operandType(right));
8893 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
8895 aopOp(result,ic,FALSE);
8896 aopOp(right,ic,FALSE);
8897 size = AOP_SIZE(right);
8899 DEBUGpic14_AopType(__LINE__,NULL,right,result);
8901 /* if the operand is already in dptr
8902 then we do nothing else we move the value to dptr */
8903 if (AOP_TYPE(result) != AOP_STR) {
8904 /* if this is remateriazable */
8905 if (AOP_TYPE(result) == AOP_IMMD) {
8906 pic14_emitcode("mov","dptr,%s",aopGet(AOP(result),0,TRUE,FALSE));
8907 pic14_emitcode("mov","b,%s + 1",aopGet(AOP(result),0,TRUE,FALSE));
8909 else { /* we need to get it byte by byte */
8910 //char *l = aopGet(AOP(result),0,FALSE,FALSE);
8911 size = AOP_SIZE(right);
8914 /* hack hack! see if this the FSR. If so don't load W */
8915 if(AOP_TYPE(right) != AOP_ACC) {
8918 emitpcode(POC_MOVFW,popGet(AOP(result),0));
8919 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8921 if(AOP_SIZE(result) > 1) {
8922 emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8923 emitpcode(POC_BTFSC,newpCodeOpBit(aopGet(AOP(result),1,FALSE,FALSE),0,0));
8924 emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_IRP_BIT));
8929 //emitpcode(POC_DECF,popCopyReg(&pc_fsr));
8931 // emitpcode(POC_MOVLW,popGetLit(0xfd));
8932 // emitpcode(POC_ADDWF,popCopyReg(&pc_fsr));
8936 emitpcode(POC_MOVFW,popGet(AOP(right),offset++));
8937 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8940 emitpcode(POC_INCF,popCopyReg(&pc_fsr));
8947 if(aopIdx(AOP(result),0) != 4) {
8949 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8953 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8958 /* so dptr know contains the address */
8961 /* if bit then unpack */
8962 if (IS_BITVAR(retype))
8963 genPackBits(retype,right,"dptr",GPOINTER);
8965 size = AOP_SIZE(right);
8968 DEBUGpic14_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size);
8972 emitpcode(POC_MOVFW,popGet(AOP(result),offset));
8973 emitpcode(POC_MOVWF,popCopyReg(&pc_fsr));
8975 if (AOP_TYPE(right) == AOP_LIT)
8976 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
8978 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
8980 emitpcode(POC_MOVWF,popCopyReg(&pc_indf));
8987 freeAsmop(right,NULL,ic,TRUE);
8988 freeAsmop(result,NULL,ic,TRUE);
8991 /*-----------------------------------------------------------------*/
8992 /* genPointerSet - stores the value into a pointer location */
8993 /*-----------------------------------------------------------------*/
8994 static void genPointerSet (iCode *ic)
8996 operand *right, *result ;
8997 sym_link *type, *etype;
9000 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9002 right = IC_RIGHT(ic);
9003 result = IC_RESULT(ic) ;
9005 /* depending on the type of pointer we need to
9006 move it to the correct pointer register */
9007 type = operandType(result);
9008 etype = getSpec(type);
9009 /* if left is of type of pointer then it is simple */
9010 if (IS_PTR(type) && !IS_FUNC(type->next)) {
9011 p_type = DCL_TYPE(type);
9014 /* we have to go by the storage class */
9015 p_type = PTR_TYPE(SPEC_OCLS(etype));
9017 /* if (SPEC_OCLS(etype)->codesp ) { */
9018 /* p_type = CPOINTER ; */
9021 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9022 /* p_type = FPOINTER ; */
9024 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9025 /* p_type = PPOINTER ; */
9027 /* if (SPEC_OCLS(etype) == idata ) */
9028 /* p_type = IPOINTER ; */
9030 /* p_type = POINTER ; */
9033 /* now that we have the pointer type we assign
9034 the pointer values */
9039 genNearPointerSet (right,result,ic);
9043 genPagedPointerSet (right,result,ic);
9047 genFarPointerSet (right,result,ic);
9051 genGenPointerSet (right,result,ic);
9055 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
9056 "genPointerSet: illegal pointer type");
9060 /*-----------------------------------------------------------------*/
9061 /* genIfx - generate code for Ifx statement */
9062 /*-----------------------------------------------------------------*/
9063 static void genIfx (iCode *ic, iCode *popIc)
9065 operand *cond = IC_COND(ic);
9068 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9070 aopOp(cond,ic,FALSE);
9072 /* get the value into acc */
9073 if (AOP_TYPE(cond) != AOP_CRY)
9074 pic14_toBoolean(cond);
9077 /* the result is now in the accumulator */
9078 freeAsmop(cond,NULL,ic,TRUE);
9080 /* if there was something to be popped then do it */
9084 /* if the condition is a bit variable */
9085 if (isbit && IS_ITEMP(cond) &&
9087 genIfxJump(ic,SPIL_LOC(cond)->rname);
9088 DEBUGpic14_emitcode ("; isbit SPIL_LOC","%s",SPIL_LOC(cond)->rname);
9091 if (isbit && !IS_ITEMP(cond))
9092 genIfxJump(ic,OP_SYMBOL(cond)->rname);
9100 /*-----------------------------------------------------------------*/
9101 /* genAddrOf - generates code for address of */
9102 /*-----------------------------------------------------------------*/
9103 static void genAddrOf (iCode *ic)
9105 operand *right, *result, *left;
9108 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9111 //aopOp(IC_RESULT(ic),ic,FALSE);
9113 aopOp((left=IC_LEFT(ic)),ic,FALSE);
9114 aopOp((right=IC_RIGHT(ic)),ic,FALSE);
9115 aopOp((result=IC_RESULT(ic)),ic,TRUE);
9117 DEBUGpic14_AopType(__LINE__,left,right,result);
9119 size = AOP_SIZE(IC_RESULT(ic));
9123 /* fixing bug #863624, reported from (errolv) */
9124 emitpcode(POC_MOVLW, popGetImmd(OP_SYMBOL(left)->rname, offset, 0, IS_FUNC(OP_SYM_TYPE(left))));
9125 emitpcode(POC_MOVWF, popGet(AOP(result), offset));
9128 emitpcode(POC_MOVLW, popGet(AOP(left),offset));
9129 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9134 freeAsmop(left,NULL,ic,FALSE);
9135 freeAsmop(result,NULL,ic,TRUE);
9140 /*-----------------------------------------------------------------*/
9141 /* genFarFarAssign - assignment when both are in far space */
9142 /*-----------------------------------------------------------------*/
9143 static void genFarFarAssign (operand *result, operand *right, iCode *ic)
9145 int size = AOP_SIZE(right);
9148 /* first push the right side on to the stack */
9150 l = aopGet(AOP(right),offset++,FALSE,FALSE);
9152 pic14_emitcode ("push","acc");
9155 freeAsmop(right,NULL,ic,FALSE);
9156 /* now assign DPTR to result */
9157 aopOp(result,ic,FALSE);
9158 size = AOP_SIZE(result);
9160 pic14_emitcode ("pop","acc");
9161 aopPut(AOP(result),"a",--offset);
9163 freeAsmop(result,NULL,ic,FALSE);
9168 /*-----------------------------------------------------------------*/
9169 /* genAssign - generate code for assignment */
9170 /*-----------------------------------------------------------------*/
9171 static void genAssign (iCode *ic)
9173 operand *result, *right;
9174 int size, offset,know_W;
9175 unsigned long lit = 0L;
9177 result = IC_RESULT(ic);
9178 right = IC_RIGHT(ic) ;
9180 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9182 /* if they are the same */
9183 if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic)))
9186 aopOp(right,ic,FALSE);
9187 aopOp(result,ic,TRUE);
9189 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9191 /* if they are the same registers */
9192 if (pic14_sameRegs(AOP(right),AOP(result)))
9195 /* if the result is a bit */
9196 if (AOP_TYPE(result) == AOP_CRY) {
9198 /* if the right size is a literal then
9199 we know what the value is */
9200 if (AOP_TYPE(right) == AOP_LIT) {
9202 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9203 popGet(AOP(result),0));
9205 if (((int) operandLitValue(right)))
9206 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9207 AOP(result)->aopu.aop_dir,
9208 AOP(result)->aopu.aop_dir);
9210 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9211 AOP(result)->aopu.aop_dir,
9212 AOP(result)->aopu.aop_dir);
9216 /* the right is also a bit variable */
9217 if (AOP_TYPE(right) == AOP_CRY) {
9218 emitpcode(POC_BCF, popGet(AOP(result),0));
9219 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9220 emitpcode(POC_BSF, popGet(AOP(result),0));
9222 pic14_emitcode("bcf","(%s >> 3),(%s & 7)",
9223 AOP(result)->aopu.aop_dir,
9224 AOP(result)->aopu.aop_dir);
9225 pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",
9226 AOP(right)->aopu.aop_dir,
9227 AOP(right)->aopu.aop_dir);
9228 pic14_emitcode("bsf","(%s >> 3),(%s & 7)",
9229 AOP(result)->aopu.aop_dir,
9230 AOP(result)->aopu.aop_dir);
9235 emitpcode(POC_BCF, popGet(AOP(result),0));
9236 pic14_toBoolean(right);
9238 emitpcode(POC_BSF, popGet(AOP(result),0));
9239 //aopPut(AOP(result),"a",0);
9243 /* bit variables done */
9245 size = AOP_SIZE(result);
9247 if(AOP_TYPE(right) == AOP_LIT)
9248 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
9250 if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) {
9251 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9252 if(aopIdx(AOP(result),0) == 4) {
9253 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9254 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9255 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9258 DEBUGpic14_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__);
9263 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9264 if(AOP_TYPE(right) == AOP_LIT) {
9266 if(know_W != (int)(lit&0xff))
9267 emitpcode(POC_MOVLW,popGetLit(lit&0xff));
9269 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9271 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9275 } else if (AOP_TYPE(right) == AOP_CRY) {
9276 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9278 emitpcode(POC_BTFSS, popGet(AOP(right),0));
9279 emitpcode(POC_INCF, popGet(AOP(result),0));
9282 mov2w (AOP(right), offset);
9283 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9291 freeAsmop (right,NULL,ic,FALSE);
9292 freeAsmop (result,NULL,ic,TRUE);
9295 /*-----------------------------------------------------------------*/
9296 /* genJumpTab - genrates code for jump table */
9297 /*-----------------------------------------------------------------*/
9298 static void genJumpTab (iCode *ic)
9303 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9305 aopOp(IC_JTCOND(ic),ic,FALSE);
9306 /* get the condition into accumulator */
9307 l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE);
9309 /* multiply by three */
9310 pic14_emitcode("add","a,acc");
9311 pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
9313 jtab = newiTempLabel(NULL);
9314 pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
9315 pic14_emitcode("jmp","@a+dptr");
9316 pic14_emitcode("","%05d_DS_:",jtab->key+100);
9318 emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
9319 emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
9320 emitpcode(POC_MOVLW, popGetLabel(jtab->key));
9321 emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
9323 emitpcode(POC_INCF, popCopyReg(&pc_pclath));
9324 emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
9325 emitpLabel(jtab->key);
9327 freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
9329 /* now generate the jump labels */
9330 for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
9331 jtab = setNextItem(IC_JTLABELS(ic))) {
9332 pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
9333 emitpcode(POC_GOTO,popGetLabel(jtab->key));
9339 /*-----------------------------------------------------------------*/
9340 /* genMixedOperation - gen code for operators between mixed types */
9341 /*-----------------------------------------------------------------*/
9343 TSD - Written for the PIC port - but this unfortunately is buggy.
9344 This routine is good in that it is able to efficiently promote
9345 types to different (larger) sizes. Unfortunately, the temporary
9346 variables that are optimized out by this routine are sometimes
9347 used in other places. So until I know how to really parse the
9348 iCode tree, I'm going to not be using this routine :(.
9350 static int genMixedOperation (iCode *ic)
9353 operand *result = IC_RESULT(ic);
9354 sym_link *ctype = operandType(IC_LEFT(ic));
9355 operand *right = IC_RIGHT(ic);
9361 operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL;
9363 pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9369 nextright = IC_RIGHT(nextic);
9370 nextleft = IC_LEFT(nextic);
9371 nextresult = IC_RESULT(nextic);
9373 aopOp(right,ic,FALSE);
9374 aopOp(result,ic,FALSE);
9375 aopOp(nextright, nextic, FALSE);
9376 aopOp(nextleft, nextic, FALSE);
9377 aopOp(nextresult, nextic, FALSE);
9379 if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) {
9385 pic14_emitcode(";remove right +","");
9387 } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) {
9393 pic14_emitcode(";remove left +","");
9397 big = AOP_SIZE(nextleft);
9398 small = AOP_SIZE(nextright);
9400 switch(nextic->op) {
9403 pic14_emitcode(";optimize a +","");
9404 /* if unsigned or not an integral type */
9405 if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) {
9406 pic14_emitcode(";add a bit to something","");
9409 pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir);
9411 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) {
9412 pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir);
9413 pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE));
9415 pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir);
9423 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9424 pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9425 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9428 pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9430 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9431 AOP(IC_RIGHT(nextic))->aopu.aop_dir,
9432 AOP(IC_RIGHT(nextic))->aopu.aop_dir);
9433 pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9434 pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE));
9437 pic14_emitcode("rlf","known_zero,w");
9444 if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){
9445 pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE));
9446 pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9448 pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) );
9458 freeAsmop(right,NULL,ic,TRUE);
9459 freeAsmop(result,NULL,ic,TRUE);
9460 freeAsmop(nextright,NULL,ic,TRUE);
9461 freeAsmop(nextleft,NULL,ic,TRUE);
9463 nextic->generated = 1;
9470 /*-----------------------------------------------------------------*/
9471 /* genCast - gen code for casting */
9472 /*-----------------------------------------------------------------*/
9473 static void genCast (iCode *ic)
9475 operand *result = IC_RESULT(ic);
9476 sym_link *ctype = operandType(IC_LEFT(ic));
9477 sym_link *rtype = operandType(IC_RIGHT(ic));
9478 operand *right = IC_RIGHT(ic);
9481 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9482 /* if they are equivalent then do nothing */
9483 if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
9486 aopOp(right,ic,FALSE) ;
9487 aopOp(result,ic,FALSE);
9489 DEBUGpic14_AopType(__LINE__,NULL,right,result);
9491 /* if the result is a bit */
9492 if (AOP_TYPE(result) == AOP_CRY) {
9493 /* if the right size is a literal then
9494 we know what the value is */
9495 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9496 if (AOP_TYPE(right) == AOP_LIT) {
9498 emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
9499 popGet(AOP(result),0));
9501 if (((int) operandLitValue(right)))
9502 pic14_emitcode("bsf","(%s >> 3), (%s & 7)",
9503 AOP(result)->aopu.aop_dir,
9504 AOP(result)->aopu.aop_dir);
9506 pic14_emitcode("bcf","(%s >> 3), (%s & 7)",
9507 AOP(result)->aopu.aop_dir,
9508 AOP(result)->aopu.aop_dir);
9513 /* the right is also a bit variable */
9514 if (AOP_TYPE(right) == AOP_CRY) {
9517 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9519 pic14_emitcode("clrc","");
9520 pic14_emitcode("btfsc","(%s >> 3), (%s & 7)",
9521 AOP(right)->aopu.aop_dir,
9522 AOP(right)->aopu.aop_dir);
9523 aopPut(AOP(result),"c",0);
9528 if (AOP_TYPE(right) == AOP_REG) {
9529 emitpcode(POC_BCF, popGet(AOP(result),0));
9530 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
9531 emitpcode(POC_BSF, popGet(AOP(result),0));
9533 pic14_toBoolean(right);
9534 aopPut(AOP(result),"a",0);
9538 if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
9540 size = AOP_SIZE(result);
9542 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9544 emitpcode(POC_CLRF, popGet(AOP(result),0));
9545 emitpcode(POC_BTFSC, popGet(AOP(right),0));
9546 emitpcode(POC_INCF, popGet(AOP(result),0));
9549 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9554 /* if they are the same size : or less */
9555 if (AOP_SIZE(result) <= AOP_SIZE(right)) {
9557 /* if they are in the same place */
9558 if (pic14_sameRegs(AOP(right),AOP(result)))
9561 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9562 if (IS_PTR_CONST(rtype))
9563 DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
9564 if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
9565 DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
9567 if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9568 emitpcode(POC_MOVLW, popGet(AOP(right),0));
9569 emitpcode(POC_MOVWF, popGet(AOP(result),0));
9570 emitpcode(POC_MOVLW, popGet(AOP(right),1));
9571 emitpcode(POC_MOVWF, popGet(AOP(result),1));
9572 if(AOP_SIZE(result) <2)
9573 fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
9577 /* if they in different places then copy */
9578 size = AOP_SIZE(result);
9581 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9582 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9584 //aopPut(AOP(result),
9585 // aopGet(AOP(right),offset,FALSE,FALSE),
9595 /* if the result is of type pointer */
9596 if (IS_PTR(ctype)) {
9599 sym_link *type = operandType(right);
9600 sym_link *etype = getSpec(type);
9601 DEBUGpic14_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__);
9603 /* pointer to generic pointer */
9604 if (IS_GENPTR(ctype)) {
9608 p_type = DCL_TYPE(type);
9610 /* we have to go by the storage class */
9611 p_type = PTR_TYPE(SPEC_OCLS(etype));
9613 /* if (SPEC_OCLS(etype)->codesp ) */
9614 /* p_type = CPOINTER ; */
9616 /* if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
9617 /* p_type = FPOINTER ; */
9619 /* if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
9620 /* p_type = PPOINTER; */
9622 /* if (SPEC_OCLS(etype) == idata ) */
9623 /* p_type = IPOINTER ; */
9625 /* p_type = POINTER ; */
9628 /* the first two bytes are known */
9629 DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__);
9630 size = GPTRSIZE - 1;
9633 if(offset < AOP_SIZE(right)) {
9634 DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
9635 if ((AOP_TYPE(right) == AOP_PCODE) &&
9636 AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
9637 emitpcode(POC_MOVLW, popGet(AOP(right),offset));
9638 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9641 aopGet(AOP(right),offset,FALSE,FALSE),
9645 emitpcode(POC_CLRF,popGet(AOP(result),offset));
9648 /* the last byte depending on type */
9652 emitpcode(POC_CLRF,popGet(AOP(result),GPTRSIZE - 1));
9655 pic14_emitcode(";BUG!? ","%d",__LINE__);
9659 pic14_emitcode(";BUG!? ","%d",__LINE__);
9663 pic14_emitcode(";BUG!? ","%d",__LINE__);
9668 /* this should never happen */
9669 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
9670 "got unknown pointer type");
9673 //aopPut(AOP(result),l, GPTRSIZE - 1);
9677 /* just copy the pointers */
9678 size = AOP_SIZE(result);
9682 aopGet(AOP(right),offset,FALSE,FALSE),
9691 /* so we now know that the size of destination is greater
9692 than the size of the source.
9693 Now, if the next iCode is an operator then we might be
9694 able to optimize the operation without performing a cast.
9696 if(genMixedOperation(ic))
9699 DEBUGpic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
9701 /* we move to result for the size of source */
9702 size = AOP_SIZE(right);
9705 emitpcode(POC_MOVFW, popGet(AOP(right),offset));
9706 emitpcode(POC_MOVWF, popGet(AOP(result),offset));
9710 /* now depending on the sign of the destination */
9711 size = AOP_SIZE(result) - AOP_SIZE(right);
9712 /* if unsigned or not an integral type */
9713 if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
9715 emitpcode(POC_CLRF, popGet(AOP(result),offset++));
9717 /* we need to extend the sign :{ */
9720 /* Save one instruction of casting char to int */
9721 emitpcode(POC_CLRF, popGet(AOP(result),offset));
9722 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9723 emitpcode(POC_DECF, popGet(AOP(result),offset));
9725 emitpcodeNULLop(POC_CLRW);
9728 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0));
9730 emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0));
9732 emitpcode(POC_MOVLW, popGetLit(0xff));
9735 emitpcode(POC_MOVWF, popGet(AOP(result),offset++));
9740 freeAsmop(right,NULL,ic,TRUE);
9741 freeAsmop(result,NULL,ic,TRUE);
9745 /*-----------------------------------------------------------------*/
9746 /* genDjnz - generate decrement & jump if not zero instrucion */
9747 /*-----------------------------------------------------------------*/
9748 static int genDjnz (iCode *ic, iCode *ifx)
9751 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9756 /* if the if condition has a false label
9757 then we cannot save */
9761 /* if the minus is not of the form
9763 if (!isOperandEqual(IC_RESULT(ic),IC_LEFT(ic)) ||
9764 !IS_OP_LITERAL(IC_RIGHT(ic)))
9767 if (operandLitValue(IC_RIGHT(ic)) != 1)
9770 /* if the size of this greater than one then no
9772 if (getSize(operandType(IC_RESULT(ic))) > 1)
9775 /* otherwise we can save BIG */
9776 lbl = newiTempLabel(NULL);
9777 lbl1= newiTempLabel(NULL);
9779 aopOp(IC_RESULT(ic),ic,FALSE);
9781 if (IS_AOP_PREG(IC_RESULT(ic))) {
9782 pic14_emitcode("dec","%s",
9783 aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9784 pic14_emitcode("mov","a,%s",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9785 pic14_emitcode("jnz","%05d_DS_",lbl->key+100);
9789 emitpcode(POC_DECFSZ,popGet(AOP(IC_RESULT(ic)),0));
9790 emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key));
9792 pic14_emitcode("decfsz","%s,f",aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE));
9793 pic14_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset);
9796 /* pic14_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */
9797 /* pic14_emitcode ("","%05d_DS_:",lbl->key+100); */
9798 /* pic14_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */
9799 /* pic14_emitcode ("","%05d_DS_:",lbl1->key+100); */
9802 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9807 /*-----------------------------------------------------------------*/
9808 /* genReceive - generate code for a receive iCode */
9809 /*-----------------------------------------------------------------*/
9810 static void genReceive (iCode *ic)
9812 DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
9814 if (isOperandInFarSpace(IC_RESULT(ic)) &&
9815 ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
9816 IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
9818 int size = getSize(operandType(IC_RESULT(ic)));
9819 int offset = fReturnSizePic - size;
9821 pic14_emitcode ("push","%s", (strcmp(fReturn[fReturnSizePic - offset - 1],"a") ?
9822 fReturn[fReturnSizePic - offset - 1] : "acc"));
9825 aopOp(IC_RESULT(ic),ic,FALSE);
9826 size = AOP_SIZE(IC_RESULT(ic));
9829 pic14_emitcode ("pop","acc");
9830 aopPut (AOP(IC_RESULT(ic)),"a",offset++);
9835 aopOp(IC_RESULT(ic),ic,FALSE);
9837 assignResultValue(IC_RESULT(ic));
9840 freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
9843 /*-----------------------------------------------------------------*/
9844 /* genDummyRead - generate code for dummy read of volatiles */
9845 /*-----------------------------------------------------------------*/
9847 genDummyRead (iCode * ic)
9849 pic14_emitcode ("; genDummyRead","");
9850 pic14_emitcode ("; not implemented","");
9855 /*-----------------------------------------------------------------*/
9856 /* genpic14Code - generate code for pic14 based controllers */
9857 /*-----------------------------------------------------------------*/
9859 * At this point, ralloc.c has gone through the iCode and attempted
9860 * to optimize in a way suitable for a PIC. Now we've got to generate
9861 * PIC instructions that correspond to the iCode.
9863 * Once the instructions are generated, we'll pass through both the
9864 * peep hole optimizer and the pCode optimizer.
9865 *-----------------------------------------------------------------*/
9867 void genpic14Code (iCode *lic)
9872 lineHead = lineCurr = NULL;
9874 pb = newpCodeChain(GcurMemmap,0,newpCodeCharP("; Starting pCode block"));
9877 /* if debug information required */
9878 if (options.debug && currFunc) {
9880 debugFile->writeFunction(currFunc);
9882 if (IS_STATIC(currFunc->etype)) {
9883 pic14_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__);
9884 //addpCode2pBlock(pb,newpCodeLabel(moduleName,currFunc->name));
9886 pic14_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__);
9887 //addpCode2pBlock(pb,newpCodeLabel(NULL,currFunc->name));
9894 for (ic = lic ; ic ; ic = ic->next ) {
9896 DEBUGpic14_emitcode(";ic","");
9897 if ( cln != ic->lineno ) {
9898 if ( options.debug ) {
9900 pic14_emitcode("",";C$%s$%d$%d$%d ==.",
9901 FileBaseName(ic->filename),ic->lineno,
9902 ic->level,ic->block);
9906 pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno);
9907 pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
9908 printCLine(ic->filename, ic->lineno));
9910 if (!options.noCcodeInAsm) {
9912 newpCodeCSource(ic->lineno,
9914 printCLine(ic->filename, ic->lineno)));
9920 // if you want printILine too, look at ../mcs51/gen.c, i don't understand this :)
9922 /* if the result is marked as
9923 spilt and rematerializable or code for
9924 this has already been generated then
9926 if (resultRemat(ic) || ic->generated )
9929 /* depending on the operation */
9948 /* IPOP happens only when trying to restore a
9949 spilt live range, if there is an ifx statement
9950 following this pop then the if statement might
9951 be using some of the registers being popped which
9952 would destory the contents of the register so
9953 we need to check for this condition and handle it */
9955 ic->next->op == IFX &&
9956 regsInCommon(IC_LEFT(ic),IC_COND(ic->next)))
9957 genIfx (ic->next,ic);
9975 genEndFunction (ic);
9995 if ( ! genDjnz (ic,ifxForOp(IC_RESULT(ic),ic)))
10012 genCmpGt (ic,ifxForOp(IC_RESULT(ic),ic));
10016 genCmpLt (ic,ifxForOp(IC_RESULT(ic),ic));
10023 /* note these two are xlated by algebraic equivalence
10024 during parsing SDCC.y */
10025 werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
10026 "got '>=' or '<=' shouldn't have come here");
10030 genCmpEq (ic,ifxForOp(IC_RESULT(ic),ic));
10042 genXor (ic,ifxForOp(IC_RESULT(ic),ic));
10046 genOr (ic,ifxForOp(IC_RESULT(ic),ic));
10050 genAnd (ic,ifxForOp(IC_RESULT(ic),ic));
10074 genRightShift (ic);
10077 case GET_VALUE_AT_ADDRESS:
10082 if (POINTER_SET(ic))
10109 addSet(&_G.sendSet,ic);
10112 case DUMMY_READ_VOLATILE:
10122 /* now we are ready to call the
10123 peep hole optimizer */
10124 if (!options.nopeep) {
10125 peepHole (&lineHead);
10127 /* now do the actual printing */
10128 printLine (lineHead,codeOutFile);
10131 DFPRINTF((stderr,"printing pBlock\n\n"));
10132 printpBlock(stdout,pb);